mga.h | 21 + mga_driver.c | 24 ++ mga_merge.c | 620 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- mga_merge.h | 12 + 4 files changed, 667 insertions(+), 10 deletions(-) Index: src/mga.h =================================================================== RCS file: /cvs/xorg/driver/xf86-video-mga/src/mga.h,v retrieving revision 1.11 diff -u -d -p -r1.11 mga.h --- src/mga.h 9 Nov 2005 21:31:20 -0000 1.11 +++ src/mga.h 21 Dec 2005 16:25:44 -0000 @@ -259,6 +259,15 @@ typedef struct mgaSave { #endif +/* ------- mergedfb support ------------- */ + /* Psuedo Xinerama support */ +#define NEED_REPLIES /* ? */ +#define EXTENSION_PROC_ARGS void * +#include "extnsionst.h" /* required */ +#include "panoramiXproto.h" /* required */ +#define MGA_XINERAMA_MAJOR_VERSION 1 +#define MGA_XINERAMA_MINOR_VERSION 1 + typedef enum { mgaLeftOf, mgaRightOf, @@ -267,6 +276,8 @@ typedef enum { mgaClone } MgaScrn2Rel; +/* ------------------------------------- */ + typedef struct { int lastInstance; #ifdef USEMGAHAL @@ -529,6 +540,7 @@ typedef struct { OptionInfoPtr Options; /* Merged Framebuffer data */ Bool MergedFB; + MgaScrn2Rel Monitor2Pos; /* Real values specific to monitor1, since the original ones are replaced */ DisplayModePtr M1modes; /* list of actual modes */ @@ -540,6 +552,15 @@ typedef struct { ScrnInfoPtr pScrn2; /*pointer to second CRTC screeninforec, if in merged mode */ + /* pseudo xinerama support for mergedfb */ + int maxM1_X1, maxM1_X2, maxM1_Y1, maxM1_Y2; + int maxM2_X1, maxM2_X2, maxM2_Y1, maxM2_Y2; + int maxClone_X1, maxClone_X2, maxClone_Y1, maxClone_Y2; + ExtensionEntry *XineramaExtEntry; + int MGAXineramaVX, MGAXineramaVY; + Bool AtLeastOneNonClone; + int MergedFBXDPI, MergedFBYDPI; + Bool NoVirtual; /* End of Merged Framebuffer Data */ int HALGranularityOffX, HALGranularityOffY; } MGARec, *MGAPtr; Index: src/mga_driver.c =================================================================== RCS file: /cvs/xorg/driver/xf86-video-mga/src/mga_driver.c,v retrieving revision 1.18 diff -u -d -p -r1.18 mga_driver.c --- src/mga_driver.c 9 Sep 2005 23:15:45 -0000 1.18 +++ src/mga_driver.c 21 Dec 2005 16:25:44 -0000 @@ -43,6 +43,9 @@ * Fixed 32bpp hires 8MB horizontal line glitch at middle right * Niels Gram Jeppesen * Added digital screen option for first head + * + * Mergedfb and pseudo xinerama support added by Juerg Billeter (j@bitron.ch) + * based on the radeon driver by Alex Deucher (agd5f@yahoo.com). */ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/mga/mga_driver.c,v 1.244tsi Exp $ */ @@ -140,6 +143,10 @@ static int MGAEntityIndex = -1; #include "mga_merge.h" +/* pseudo xinerama support */ + +extern Bool MGAnoPanoramiXExtension; + /* * This contains the functions needed by the server after loading the @@ -3263,6 +3270,9 @@ MGAScreenInit(int scrnIndex, ScreenPtr p pMga->PointerMoved = pScrn->PointerMoved; pScrn->PointerMoved = MGAMergePointerMoved; + /* Psuedo xinerama */ + MGAnoPanoramiXExtension = FALSE; + MGAXineramaExtensionInit(pScrn); } /* Initialise default colourmap */ @@ -3370,6 +3380,9 @@ MGAScreenInit(int scrnIndex, ScreenPtr p Bool MGASwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + MGAPtr info = MGAPTR(pScrn); + Bool ret; #ifdef USEMGAHAL char sCmdIn[256]; char sCmdOut[256]; @@ -3432,7 +3445,16 @@ MGASwitchMode(int scrnIndex, DisplayMode #endif return FALSE; } else - return MGAModeInit(xf86Screens[scrnIndex], mode); + ret = MGAModeInit(xf86Screens[scrnIndex], mode); + + /* Since RandR (indirectly) uses SwitchMode(), we need to + * update our Xinerama info here, too, in case of resizing + */ + if(info->MergedFB) { + MGAUpdateXineramaScreenInfo(pScrn); + } + + return ret; } /* Adjusts coordinates to match Panning granularity. Index: src/mga_merge.c =================================================================== RCS file: /cvs/xorg/driver/xf86-video-mga/src/mga_merge.c,v retrieving revision 1.5 diff -u -d -p -r1.5 mga_merge.c --- src/mga_merge.c 9 Nov 2005 17:42:58 -0000 1.5 +++ src/mga_merge.c 21 Dec 2005 16:25:44 -0000 @@ -14,6 +14,11 @@ #include "compiler.h" +#include "extnsionst.h" /* required */ +#include "panoramiXproto.h" /* required */ +#include "dixstruct.h" +#include "vbe.h" + /* Drivers for PCI hardware need this */ #include "xf86PciInfo.h" #include "mga.h" @@ -23,6 +28,23 @@ #include "fbdevhw.h" +/* pseudo xinerama support */ +static unsigned char MGAXineramaReqCode = 0; +int MGAXineramaPixWidth = 0; +int MGAXineramaPixHeight = 0; +int MGAXineramaNumScreens = 0; +MGAXineramaData *MGAXineramadataPtr = NULL; +static int MGAXineramaGeneration; +Bool MGAnoPanoramiXExtension = TRUE; + +int MGAProcXineramaQueryVersion(ClientPtr client); +int MGAProcXineramaGetState(ClientPtr client); +int MGAProcXineramaGetScreenCount(ClientPtr client); +int MGAProcXineramaGetScreenSize(ClientPtr client); +int MGAProcXineramaIsActive(ClientPtr client); +int MGAProcXineramaQueryScreens(ClientPtr client); +int MGASProcXineramaDispatch(ClientPtr client); + static int StrToRanges(range* r, char* s) { float num=0.0; @@ -73,6 +95,7 @@ static DisplayModePtr CopyModeNLink(ScrnInfoPtr pScrn, DisplayModePtr dest, DisplayModePtr i, DisplayModePtr j, MgaScrn2Rel srel) { DisplayModePtr mode; int dx = 0,dy = 0; + MGAPtr info = MGAPTR(pScrn); /* start with first node */ mode = xalloc(sizeof(DisplayModeRec)); memcpy(mode,i, sizeof(DisplayModeRec)); @@ -107,6 +130,10 @@ CopyModeNLink(ScrnInfoPtr pScrn, Display mode->VSyncEnd += dy; mode->VTotal += dy; mode->Clock = 0; /* Shows we're in Merge mode. */ + + if(srel != mgaClone) { + info->AtLeastOneNonClone = TRUE; + } mode->next = mode; mode->prev = mode; @@ -138,6 +165,7 @@ GetModeFromName(char* str, DisplayModePt static DisplayModePtr GenerateModeList(ScrnInfoPtr pScrn, char* str, DisplayModePtr i, DisplayModePtr j, MgaScrn2Rel srel) { + MGAPtr info = MGAPTR(pScrn); char* strmode = str; char modename[256]; Bool gotdash = FALSE; @@ -146,6 +174,7 @@ GenerateModeList(ScrnInfoPtr pScrn, char DisplayModePtr mode1 = NULL; DisplayModePtr mode2 = NULL; DisplayModePtr result = NULL; + info->AtLeastOneNonClone = FALSE; do { switch(*str) { case 0: @@ -243,7 +272,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, i #ifdef USEMGAHAL ULONG status; #endif - MgaScrn2Rel Monitor2Pos; + /*MgaScrn2Rel Monitor2Pos;*/ xf86DrvMsg(pScrn1->scrnIndex, X_INFO, "==== Start of second screen initialization ====\n"); pScrn = xalloc(sizeof(ScrnInfoRec)); @@ -348,6 +377,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, i pMga->OverclockMem = pMga1->OverclockMem; pMga->TexturedVideo = pMga1->TexturedVideo; pMga->MergedFB = TRUE; + pMga->MergedFBXDPI = pMga->MergedFBYDPI = 0; pMga->Rotate = 0; @@ -625,29 +655,29 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, i pMga->CurrentLayout.mode = pScrn->currentMode; - Monitor2Pos = mgaRightOf; + pMga1->Monitor2Pos = mgaRightOf; if ((s = xf86GetOptValString(pMga1->Options, OPTION_MONITOR2POS))) { switch(s[0]) { case 'L': case 'l': case 'G': case 'g': - Monitor2Pos = mgaLeftOf; + pMga1->Monitor2Pos = mgaLeftOf; break; case 'R': case 'r': case 'D': case 'd': - Monitor2Pos = mgaRightOf; + pMga1->Monitor2Pos = mgaRightOf; break; case 'A': case 'a': case 'H': case 'h': - Monitor2Pos = mgaAbove; + pMga1->Monitor2Pos = mgaAbove; break; case 'B': case 'b': - Monitor2Pos = mgaBelow; + pMga1->Monitor2Pos = mgaBelow; break; case 'C': case 'c': - Monitor2Pos = mgaClone; + pMga1->Monitor2Pos = mgaClone; break; default: - Monitor2Pos = mgaRightOf; + pMga1->Monitor2Pos = mgaRightOf; break; } } @@ -658,7 +688,7 @@ MGAPreInitMergedFB(ScrnInfoPtr pScrn1, i pMga1->M1currentMode = pScrn1->currentMode; /* make a copy of the mode list, so we can modify it. */ if ((s = xf86GetOptValString(pMga1->Options, OPTION_METAMODES))) { - pScrn1->modes = GenerateModeList(pScrn,s,pMga1->M1modes,pScrn->modes,Monitor2Pos); /*FIXME: free this list*/ + pScrn1->modes = GenerateModeList(pScrn,s,pMga1->M1modes,pScrn->modes,pMga1->Monitor2Pos); /*FIXME: free this list*/ if(!pScrn1->modes) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Parse Error reading MetaModes, or No modes left.\n"); return FALSE; @@ -682,6 +712,578 @@ MGADisplayPowerManagementSetMerged(ScrnI MGADisplayPowerManagementSetCrtc2(pScrn,PowerManagementMode,flags); } +/* Pseudo-Xinerama extension for MergedFB mode */ +void +MGAUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1) +{ + MGAPtr info = MGAPTR(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; + DisplayModePtr currentMode, firstMode; + Bool infochanged = FALSE; + + if(!info->MergedFB) return; + + if(MGAnoPanoramiXExtension) return; + + if(!MGAXineramadataPtr) return; + + pScrn2 = info->pScrn2; + + /* Attention: Usage of RandR may lead into virtual X and Y values + * actually smaller than our MetaModes! To avoid this, we calculate + * the maxCRT fields here (and not somewhere else, like in CopyNLink) + */ + + if((info->MGAXineramaVX != pScrn1->virtualX) || (info->MGAXineramaVY != pScrn1->virtualY)) { + + if(!(pScrn1->modes)) { + xf86DrvMsg(pScrn1->scrnIndex, X_ERROR, + "Internal error: MGAUpdateXineramaScreenInfo(): pScrn->modes is NULL\n"); + return; + } + + info->maxM1_X1 = info->maxM1_X2 = 0; + info->maxM1_Y1 = info->maxM1_Y2 = 0; + info->maxM2_X1 = info->maxM2_X2 = 0; + info->maxM2_Y1 = info->maxM2_Y2 = 0; + info->maxClone_X1 = info->maxClone_X2 = 0; + info->maxClone_Y1 = info->maxClone_Y2 = 0; + + currentMode = firstMode = pScrn1->modes; + + do { + + DisplayModePtr p = currentMode->next; + DisplayModePtr i = ((MergedDisplayModePtr)currentMode->Private)->Monitor1; + DisplayModePtr j = ((MergedDisplayModePtr)currentMode->Private)->Monitor2; + MgaScrn2Rel srel = ((MergedDisplayModePtr)currentMode->Private)->Monitor2Pos; + + if((i->HDisplay <= pScrn1->virtualX) && (j->HDisplay <= pScrn1->virtualX) && + (i->VDisplay <= pScrn1->virtualY) && (j->VDisplay <= pScrn1->virtualY)) { + + if(srel != mgaClone) { + if(info->maxM1_X1 <= i->HDisplay) { + info->maxM1_X1 = i->HDisplay; /* Largest M1 mode */ + if(info->maxM1_X2 < j->HDisplay) { + info->maxM1_X2 = j->HDisplay; /* Largest X of M2 mode displayed with largest M1 mode */ + } + } + if(info->maxM2_X2 <= j->HDisplay) { + info->maxM2_X2 = j->HDisplay; /* Largest M2 mode */ + if(info->maxM2_X1 < i->HDisplay) { + info->maxM2_X1 = i->HDisplay; /* Largest X of M1 mode displayed with largest M2 mode */ + } + } + if(info->maxM1_Y1 <= i->VDisplay) { + info->maxM1_Y1 = i->VDisplay; + if(info->maxM1_Y2 < j->VDisplay) { + info->maxM1_Y2 = j->VDisplay; + } + } + if(info->maxM2_Y2 <= j->VDisplay) { + info->maxM2_Y2 = j->VDisplay; + if(info->maxM2_Y1 < i->VDisplay) { + info->maxM2_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)); + + info->MGAXineramaVX = pScrn1->virtualX; + info->MGAXineramaVY = pScrn1->virtualY; + infochanged = TRUE; + + } + + /* leftof + + V 1: + M2: x = 0 + y = 0 + w = (maxM2 X) + h = (virtual Y) + M1: x = (virtual X) - (maxM1 X) + y = 0 + w = (maxM1 X) + h = (virtual Y) + + V 2: + M2: x = 0 + y = 0 + w = max M2 mode X + h = virtual Y size + M1: x = (max) M2 mode X von dem Metamode, wo M1 mode maximal breit ist + y = 0 + w = max M1 mode X + h = virtual Y size + + V 3: (current) + M1: x = (maxM2 X von dem MMode, wo maxM1 X) + y = 0 + w = (virtual X) - x + h = (virtual Y) + M2: x = 0 + y = 0 + w = (virtual X) - (maxM1 X von dem MMode, wo maxM2 X) + h = (virtual Y) + + */ + switch(info->Monitor2Pos) { + case mgaLeftOf: /* V 1 */ + x1 = min(info->maxM1_X2, pScrn1->virtualX - info->maxM1_X1); /* pScrn1->virtualX - pSiS->maxM1_X1; +*/ + if(x1 < 0) x1 = 0; + y1 = 0; /* 0; */ + w1 = pScrn1->virtualX - x1; /* pSiS->maxM1_X1; */ + h1 = pScrn1->virtualY; /* pScrn1->virtualY; */ + x2 = 0; /* 0; */ + y2 = 0; /* 0; */ + w2 = max(info->maxM2_X2, pScrn1->virtualX - info->maxM2_X1); /* pSiS->maxM2_X2; */ + if(w2 > pScrn1->virtualX) w2 = pScrn1->virtualX; + h2 = pScrn1->virtualY; /* pScrn1->virtualY; */ + break; + case mgaRightOf: + x1 = 0; /* 0; */ + y1 = 0; /* 0; */ + w1 = max(info->maxM1_X1, pScrn1->virtualX - info->maxM1_X2); /* pSiS->maxM1_X1; */ + if(w1 > pScrn1->virtualX) w1 = pScrn1->virtualX; + h1 = pScrn1->virtualY; /* pScrn1->virtualY; */ + x2 = min(info->maxM2_X1, pScrn1->virtualX - info->maxM2_X2); /* pScrn1->virtualX - pSiS->maxM2_X2; +*/ + if(x2 < 0) x2 = 0; + y2 = 0; /* 0; */ + w2 = pScrn1->virtualX - x2; /* pSiS->maxM2_X2; */ + h2 = pScrn1->virtualY; /* pScrn1->virtualY; */ + break; + case mgaAbove: + x1 = 0; /* 0; */ + y1 = min(info->maxM1_Y2, pScrn1->virtualY - info->maxM1_Y1); /* pScrn1->virtualY - pSiS->maxM1_Y1; +*/ + if(y1 < 0) y1 = 0; + w1 = pScrn1->virtualX; /* pScrn1->virtualX; */ + h1 = pScrn1->virtualY - y1; /* pSiS->maxM1_Y1; */ + x2 = 0; /* 0; */ + y2 = 0; /* 0; */ + w2 = pScrn1->virtualX; /* pScrn1->virtualX; */ + h2 = max(info->maxM2_Y2, pScrn1->virtualY - info->maxM2_Y1); /* pSiS->maxM2_Y2; */ + if(h2 > pScrn1->virtualY) h2 = pScrn1->virtualY; + break; + case mgaBelow: + x1 = 0; /* 0; */ + y1 = 0; /* 0; */ + w1 = pScrn1->virtualX; /* pScrn1->virtualX; */ + h1 = max(info->maxM1_Y1, pScrn1->virtualY - info->maxM1_Y2); /* pSiS->maxM1_Y1; */ + if(h1 > pScrn1->virtualY) h1 = pScrn1->virtualY; + x2 = 0; /* 0; */ + y2 = min(info->maxM2_Y1, pScrn1->virtualY - info->maxM2_Y2); /* pScrn1->virtualY - pSiS->maxM2_Y2; +*/ + if(y2 < 0) y2 = 0; + w2 = pScrn1->virtualX; /* pScrn1->virtualX; */ + h2 = pScrn1->virtualY - y2; /* pSiS->maxM2_Y2; */ + break; + default: + xf86DrvMsg(pScrn1->scrnIndex, X_ERROR, + "Internal error: UpdateXineramaInfo(): unsupported Monitor2Pos (%d)\n", + info->Monitor2Pos); + } + MGAXineramadataPtr[crt1scrnnum].x = x1; + MGAXineramadataPtr[crt1scrnnum].y = y1; + MGAXineramadataPtr[crt1scrnnum].width = w1; + MGAXineramadataPtr[crt1scrnnum].height = h1; + MGAXineramadataPtr[crt2scrnnum].x = x2; + MGAXineramadataPtr[crt2scrnnum].y = y2; + MGAXineramadataPtr[crt2scrnnum].width = w2; + MGAXineramadataPtr[crt2scrnnum].height = h2; + + if(infochanged) { + xf86DrvMsg(pScrn1->scrnIndex, X_INFO, + "Pseudo-Xinerama: Monitor1 (Screen %d) (%d,%d)-(%d,%d)\n", + crt1scrnnum, x1, y1, w1+x1-1, h1+y1-1); + xf86DrvMsg(pScrn1->scrnIndex, X_INFO, + "Pseudo-Xinerama: Monitor2 (Screen %d) (%d,%d)-(%d,%d)\n", + crt2scrnnum, x2, y2, w2+x2-1, h2+y2-1); + } + +} + +/* Proc */ + +int +MGAProcXineramaQueryVersion(ClientPtr client) +{ + xPanoramiXQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = MGA_XINERAMA_MAJOR_VERSION; + rep.minorVersion = MGA_XINERAMA_MINOR_VERSION; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *)&rep); + return (client->noClientException); +} + +int +MGAProcXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !MGAnoPanoramiXExtension; + if(client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swaps (&rep.state, n); + } + WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *)&rep); + return client->noClientException; +} + +int +MGAProcXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + pWin = LookupWindow(stuff->window, client); + if(!pWin) return BadWindow; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = MGAXineramaNumScreens; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.ScreenCount, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep); + return client->noClientException; +} + +int +MGAProcXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin; + xPanoramiXGetScreenSizeReply rep; + register int n; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + pWin = LookupWindow (stuff->window, client); + if(!pWin) return BadWindow; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.width = MGAXineramadataPtr[stuff->screen].width; + rep.height = MGAXineramadataPtr[stuff->screen].height; + if(client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.width, n); + swaps(&rep.height, n); + } + WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep); + return client->noClientException; +} + +int +MGAProcXineramaIsActive(ClientPtr client) +{ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !MGAnoPanoramiXExtension; + if(client->swapped) { + register int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.state, n); + } + WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep); + return client->noClientException; +} + +int +MGAProcXineramaQueryScreens(ClientPtr client) +{ + xXineramaQueryScreensReply rep; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = (MGAnoPanoramiXExtension) ? 0 : MGAXineramaNumScreens; + rep.length = rep.number * sz_XineramaScreenInfo >> 2; + if(client->swapped) { + register int n; + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.number, n); + } + WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *)&rep); + + if(!MGAnoPanoramiXExtension) { + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < MGAXineramaNumScreens; i++) { + scratch.x_org = MGAXineramadataPtr[i].x; + scratch.y_org = MGAXineramadataPtr[i].y; + scratch.width = MGAXineramadataPtr[i].width; + scratch.height = MGAXineramadataPtr[i].height; + if(client->swapped) { + register int n; + swaps(&scratch.x_org, n); + swaps(&scratch.y_org, n); + swaps(&scratch.width, n); + swaps(&scratch.height, n); + } + WriteToClient(client, sz_XineramaScreenInfo, (char *)&scratch); + } + } + + return client->noClientException; +} + +static int +MGAProcXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) + { + case X_PanoramiXQueryVersion: + return MGAProcXineramaQueryVersion(client); + case X_PanoramiXGetState: + return MGAProcXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return MGAProcXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return MGAProcXineramaGetScreenSize(client); + case X_XineramaIsActive: + return MGAProcXineramaIsActive(client); + case X_XineramaQueryScreens: + return MGAProcXineramaQueryScreens(client); + } + return BadRequest; +} + +/* SProc */ + +static int +MGASProcXineramaQueryVersion (ClientPtr client) +{ + REQUEST(xPanoramiXQueryVersionReq); + register int n; + swaps(&stuff->length,n); + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + return MGAProcXineramaQueryVersion(client); +} + +static int +MGASProcXineramaGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + return MGAProcXineramaGetState(client); +} + +static int +MGASProcXineramaGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + return MGAProcXineramaGetScreenCount(client); +} + +static int +MGASProcXineramaGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + return MGAProcXineramaGetScreenSize(client); +} + +static int +MGASProcXineramaIsActive(ClientPtr client) +{ + REQUEST(xXineramaIsActiveReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + return MGAProcXineramaIsActive(client); +} + +static int +MGASProcXineramaQueryScreens(ClientPtr client) +{ + REQUEST(xXineramaQueryScreensReq); + register int n; + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + return MGAProcXineramaQueryScreens(client); +} + +int +MGASProcXineramaDispatch(ClientPtr client) +{ + REQUEST(xReq); + switch (stuff->data) { + case X_PanoramiXQueryVersion: + return MGASProcXineramaQueryVersion(client); + case X_PanoramiXGetState: + return MGASProcXineramaGetState(client); + case X_PanoramiXGetScreenCount: + return MGASProcXineramaGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return MGASProcXineramaGetScreenSize(client); + case X_XineramaIsActive: + return MGASProcXineramaIsActive(client); + case X_XineramaQueryScreens: + return MGASProcXineramaQueryScreens(client); + } + return BadRequest; +} + +static void +MGAXineramaResetProc(ExtensionEntry* extEntry) +{ + if(MGAXineramadataPtr) { + Xfree(MGAXineramadataPtr); + MGAXineramadataPtr = NULL; + } +} + +void +MGAXineramaExtensionInit(ScrnInfoPtr pScrn) +{ + MGAPtr info = MGAPTR(pScrn); + Bool success = FALSE; + + if(!(MGAXineramadataPtr)) { + + if(!info->MergedFB) { + MGAnoPanoramiXExtension = TRUE; + return; + } + + if(!noPanoramiXExtension) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Xinerama active, not initializing MGA Pseudo-Xinerama\n"); + MGAnoPanoramiXExtension = TRUE; + return; + } + + if(MGAnoPanoramiXExtension) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "MGA Pseudo-Xinerama disabled\n"); + return; + } + + if(info->Monitor2Pos == mgaClone) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Running MergedFB in Clone mode, MGA Pseudo-Xinerama disabled\n"); + MGAnoPanoramiXExtension = TRUE; + return; + } + +xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s:%d, mgaptr=%d\n", __FILE__, __LINE__, info); + if(!(MGAPTR(info->pScrn2)->AtLeastOneNonClone)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Only Clone modes defined, MGA Pseudo-Xinerama disabled\n"); + MGAnoPanoramiXExtension = TRUE; + return; + } + + MGAXineramaNumScreens = 2; + + while(MGAXineramaGeneration != serverGeneration) { + + info->XineramaExtEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + MGAProcXineramaDispatch, + MGASProcXineramaDispatch, + MGAXineramaResetProc, + StandardMinorOpcode); + + if(!info->XineramaExtEntry) break; + + MGAXineramaReqCode = (unsigned char)info->XineramaExtEntry->base; + + if(!(MGAXineramadataPtr = (MGAXineramaData *) + xcalloc(MGAXineramaNumScreens, sizeof(MGAXineramaData)))) break; + + MGAXineramaGeneration = serverGeneration; + success = TRUE; + } + + if(!success) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize MGA Pseudo-Xinerama extension\n"); + MGAnoPanoramiXExtension = TRUE; + return; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Initialized MGA Pseudo-Xinerama extension\n"); + + info->MGAXineramaVX = 0; + info->MGAXineramaVY = 0; + + } + + MGAUpdateXineramaScreenInfo(pScrn); + +} +/* End of PseudoXinerama */ + typedef struct _region { int x0,x1,y0,y1; } region; Index: src/mga_merge.h =================================================================== RCS file: /cvs/xorg/driver/xf86-video-mga/src/mga_merge.h,v retrieving revision 1.1.1.1 diff -u -d -p -r1.1.1.1 mga_merge.h --- src/mga_merge.h 14 Nov 2003 16:48:55 -0000 1.1.1.1 +++ src/mga_merge.h 21 Dec 2005 16:25:44 -0000 @@ -16,4 +16,16 @@ typedef struct _MergedDisplayModeRec { MgaScrn2Rel Monitor2Pos; } MergedDisplayModeRec, *MergedDisplayModePtr; +typedef struct _MGAXineramaData { + int x; + int y; + int width; + int height; +} MGAXineramaData; + #define MDMPTR(x) ((MergedDisplayModePtr)(x->currentMode->Private)) + +extern void +MGAXineramaExtensionInit(ScrnInfoPtr pScrn); +extern void +MGAUpdateXineramaScreenInfo(ScrnInfoPtr pScrn1);