summaryrefslogtreecommitdiff
path: root/Xext/panoramiX.c
diff options
context:
space:
mode:
Diffstat (limited to 'Xext/panoramiX.c')
-rw-r--r--Xext/panoramiX.c1301
1 files changed, 893 insertions, 408 deletions
diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
index 2d3eb7c42..fb0b9c541 100644
--- a/Xext/panoramiX.c
+++ b/Xext/panoramiX.c
@@ -23,11 +23,13 @@ shall not be used in advertising or otherwise to promote the sale, use or other
dealings in this Software without prior written authorization from Digital
Equipment Corporation.
******************************************************************/
+/* $XFree86: xc/programs/Xserver/Xext/panoramiX.c,v 3.32 2002/08/01 00:30:34 mvojkovi Exp $ */
#define NEED_REPLIES
#include <stdio.h>
#include "X.h"
#include "Xproto.h"
+#include "Xarch.h"
#include "misc.h"
#include "cursor.h"
#include "cursorstr.h"
@@ -39,32 +41,44 @@ Equipment Corporation.
#include "window.h"
#include "windowstr.h"
#include "pixmapstr.h"
-#if 0
-#include <sys/workstation.h>
-#include <X11/Xserver/ws.h>
-#endif
#include "panoramiX.h"
#include "panoramiXproto.h"
+#include "panoramiXsrv.h"
+#include "globals.h"
+#include "servermd.h"
+#include "resource.h"
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+
static unsigned char PanoramiXReqCode = 0;
/*
* PanoramiX data declarations
*/
-int PanoramiXPixWidth;
-int PanoramiXPixHeight;
-int PanoramiXNumScreens;
+int PanoramiXPixWidth = 0;
+int PanoramiXPixHeight = 0;
+int PanoramiXNumScreens = 0;
+
+PanoramiXData *panoramiXdataPtr = NULL;
-PanoramiXData *panoramiXdataPtr;
-PanoramiXWindow *PanoramiXWinRoot;
-PanoramiXGC *PanoramiXGCRoot;
-PanoramiXCmap *PanoramiXCmapRoot;
-PanoramiXPmap *PanoramiXPmapRoot;
-PanoramiXEdge panoramiXEdgePtr[MAXSCREENS];
-RegionRec PanoramiXScreenRegion[MAXSCREENS];
-PanoramiXCDT PanoramiXColorDepthTable[MAXSCREENS];
-PanoramiXDepth PanoramiXLargestScreenDepth;
+RegionRec PanoramiXScreenRegion;
+
+int PanoramiXNumDepths;
+DepthPtr PanoramiXDepths;
+int PanoramiXNumVisuals;
+VisualPtr PanoramiXVisuals;
+/* We support at most 256 visuals */
+XID *PanoramiXVisualTable = NULL;
+
+unsigned long XRC_DRAWABLE;
+unsigned long XRT_WINDOW;
+unsigned long XRT_PIXMAP;
+unsigned long XRT_GC;
+unsigned long XRT_COLORMAP;
+
int (* SavedProcVector[256]) ();
ScreenInfo *GlobalScrInfo;
@@ -75,7 +89,6 @@ static int ProcPanoramiXDispatch();
* Function prototypes
*/
-static void locate_neighbors(int);
static void PanoramiXResetProc(ExtensionEntry*);
/*
@@ -83,16 +96,9 @@ static void PanoramiXResetProc(ExtensionEntry*);
*/
extern int SProcPanoramiXDispatch();
-extern Bool noPanoramiXExtension;
-extern Bool PanoramiXVisibilityNotifySent;
-extern WindowPtr *WindowTable;
-#if 0
-extern ScreenArgsRec screenArgs[MAXSCREENS];
-#endif
-extern int defaultBackingStore;
extern char *ConnectionInfo;
extern int connBlockScreenStart;
-extern int (* ProcVector[256]) ();
+extern xConnSetupPrefix connSetupPrefix;
/*
* Server dispatcher function replacements
@@ -104,11 +110,10 @@ int PanoramiXChangeSaveSet(), PanoramiXReparentWindow();
int PanoramiXMapWindow(), PanoramiXMapSubwindows();
int PanoramiXUnmapWindow(), PanoramiXUnmapSubwindows();
int PanoramiXConfigureWindow(), PanoramiXCirculateWindow();
-int PanoramiXGetGeometry(), PanoramiXChangeProperty();
-int PanoramiXDeleteProperty(), PanoramiXSendEvent();
+int PanoramiXGetGeometry(), PanoramiXTranslateCoords();
int PanoramiXCreatePixmap(), PanoramiXFreePixmap();
int PanoramiXCreateGC(), PanoramiXChangeGC();
-int PanoramiXCopyGC();
+int PanoramiXCopyGC(), PanoramiXCopyColormapAndFree();
int PanoramiXSetDashes(), PanoramiXSetClipRectangles();
int PanoramiXFreeGC(), PanoramiXClearToBackground();
int PanoramiXCopyArea(), PanoramiXCopyPlane();
@@ -122,8 +127,326 @@ int PanoramiXImageText8(), PanoramiXImageText16();
int PanoramiXCreateColormap(), PanoramiXFreeColormap();
int PanoramiXInstallColormap(), PanoramiXUninstallColormap();
int PanoramiXAllocColor(), PanoramiXAllocNamedColor();
-int PanoramiXAllocColorCells();
+int PanoramiXAllocColorCells(), PanoramiXStoreNamedColor();
int PanoramiXFreeColors(), PanoramiXStoreColors();
+int PanoramiXAllocColorPlanes();
+
+static int PanoramiXGCIndex = -1;
+static int PanoramiXScreenIndex = -1;
+
+typedef struct {
+ DDXPointRec clipOrg;
+ DDXPointRec patOrg;
+ GCFuncs *wrapFuncs;
+} PanoramiXGCRec, *PanoramiXGCPtr;
+
+typedef struct {
+ CreateGCProcPtr CreateGC;
+ CloseScreenProcPtr CloseScreen;
+} PanoramiXScreenRec, *PanoramiXScreenPtr;
+
+RegionRec XineramaScreenRegions[MAXSCREENS];
+
+static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void XineramaChangeGC(GCPtr, unsigned long);
+static void XineramaCopyGC(GCPtr, unsigned long, GCPtr);
+static void XineramaDestroyGC(GCPtr);
+static void XineramaChangeClip(GCPtr, int, pointer, int);
+static void XineramaDestroyClip(GCPtr);
+static void XineramaCopyClip(GCPtr, GCPtr);
+
+GCFuncs XineramaGCFuncs = {
+ XineramaValidateGC, XineramaChangeGC, XineramaCopyGC, XineramaDestroyGC,
+ XineramaChangeClip, XineramaDestroyClip, XineramaCopyClip
+};
+
+#define Xinerama_GC_FUNC_PROLOGUE(pGC)\
+ PanoramiXGCPtr pGCPriv = \
+ (PanoramiXGCPtr) (pGC)->devPrivates[PanoramiXGCIndex].ptr;\
+ (pGC)->funcs = pGCPriv->wrapFuncs;
+
+#define Xinerama_GC_FUNC_EPILOGUE(pGC)\
+ pGCPriv->wrapFuncs = (pGC)->funcs;\
+ (pGC)->funcs = &XineramaGCFuncs;
+
+
+static Bool
+XineramaCloseScreen (int i, ScreenPtr pScreen)
+{
+ PanoramiXScreenPtr pScreenPriv =
+ (PanoramiXScreenPtr) pScreen->devPrivates[PanoramiXScreenIndex].ptr;
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+
+ REGION_UNINIT(pScreen, &XineramaScreenRegions[pScreen->myNum]);
+ if (pScreen->myNum == 0)
+ REGION_UNINIT(pScreen, &PanoramiXScreenRegion);
+
+ xfree ((pointer) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+Bool
+XineramaCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ PanoramiXScreenPtr pScreenPriv =
+ (PanoramiXScreenPtr) pScreen->devPrivates[PanoramiXScreenIndex].ptr;
+ Bool ret;
+
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+ if((ret = (*pScreen->CreateGC)(pGC))) {
+ PanoramiXGCPtr pGCPriv =
+ (PanoramiXGCPtr) pGC->devPrivates[PanoramiXGCIndex].ptr;
+
+ pGCPriv->wrapFuncs = pGC->funcs;
+ pGC->funcs = &XineramaGCFuncs;
+
+ pGCPriv->clipOrg.x = pGC->clipOrg.x;
+ pGCPriv->clipOrg.y = pGC->clipOrg.y;
+ pGCPriv->patOrg.x = pGC->patOrg.x;
+ pGCPriv->patOrg.y = pGC->patOrg.y;
+ }
+ pScreen->CreateGC = XineramaCreateGC;
+
+ return ret;
+}
+
+static void
+XineramaValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+
+ if((pDraw->type == DRAWABLE_WINDOW) && !(((WindowPtr)pDraw)->parent)) {
+ /* the root window */
+ int x_off = panoramiXdataPtr[pGC->pScreen->myNum].x;
+ int y_off = panoramiXdataPtr[pGC->pScreen->myNum].y;
+ int new_val;
+
+ new_val = pGCPriv->clipOrg.x - x_off;
+ if(pGC->clipOrg.x != new_val) {
+ pGC->clipOrg.x = new_val;
+ changes |= GCClipXOrigin;
+ }
+ new_val = pGCPriv->clipOrg.y - y_off;
+ if(pGC->clipOrg.y != new_val) {
+ pGC->clipOrg.y = new_val;
+ changes |= GCClipYOrigin;
+ }
+ new_val = pGCPriv->patOrg.x - x_off;
+ if(pGC->patOrg.x != new_val) {
+ pGC->patOrg.x = new_val;
+ changes |= GCTileStipXOrigin;
+ }
+ new_val = pGCPriv->patOrg.y - y_off;
+ if(pGC->patOrg.y != new_val) {
+ pGC->patOrg.y = new_val;
+ changes |= GCTileStipYOrigin;
+ }
+ } else {
+ if(pGC->clipOrg.x != pGCPriv->clipOrg.x) {
+ pGC->clipOrg.x = pGCPriv->clipOrg.x;
+ changes |= GCClipXOrigin;
+ }
+ if(pGC->clipOrg.y != pGCPriv->clipOrg.y) {
+ pGC->clipOrg.y = pGCPriv->clipOrg.y;
+ changes |= GCClipYOrigin;
+ }
+ if(pGC->patOrg.x != pGCPriv->patOrg.x) {
+ pGC->patOrg.x = pGCPriv->patOrg.x;
+ changes |= GCTileStipXOrigin;
+ }
+ if(pGC->patOrg.y != pGCPriv->patOrg.y) {
+ pGC->patOrg.y = pGCPriv->patOrg.y;
+ changes |= GCTileStipYOrigin;
+ }
+ }
+
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XineramaDestroyGC(GCPtr pGC)
+{
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XineramaChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+){
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+
+ if(mask & GCTileStipXOrigin)
+ pGCPriv->patOrg.x = pGC->patOrg.x;
+ if(mask & GCTileStipYOrigin)
+ pGCPriv->patOrg.y = pGC->patOrg.y;
+ if(mask & GCClipXOrigin)
+ pGCPriv->clipOrg.x = pGC->clipOrg.x;
+ if(mask & GCClipYOrigin)
+ pGCPriv->clipOrg.y = pGC->clipOrg.y;
+
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XineramaCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst
+){
+ PanoramiXGCPtr pSrcPriv =
+ (PanoramiXGCPtr) pGCSrc->devPrivates[PanoramiXGCIndex].ptr;
+ Xinerama_GC_FUNC_PROLOGUE (pGCDst);
+
+ if(mask & GCTileStipXOrigin)
+ pGCPriv->patOrg.x = pSrcPriv->patOrg.x;
+ if(mask & GCTileStipYOrigin)
+ pGCPriv->patOrg.y = pSrcPriv->patOrg.y;
+ if(mask & GCClipXOrigin)
+ pGCPriv->clipOrg.x = pSrcPriv->clipOrg.x;
+ if(mask & GCClipYOrigin)
+ pGCPriv->clipOrg.y = pSrcPriv->clipOrg.y;
+
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ Xinerama_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+XineramaChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects
+){
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XineramaCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ Xinerama_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ Xinerama_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+XineramaDestroyClip(GCPtr pGC)
+{
+ Xinerama_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ Xinerama_GC_FUNC_EPILOGUE (pGC);
+}
+
+
+
+int
+XineramaDeleteResource(pointer data, XID id)
+{
+ xfree(data);
+ return 1;
+}
+
+
+static Bool
+XineramaFindIDOnAnyScreen(pointer resource, XID id, pointer privdata)
+{
+ PanoramiXRes *res = (PanoramiXRes*)resource;
+ int j;
+
+ FOR_NSCREENS(j)
+ if(res->info[j].id == *((XID*)privdata)) return TRUE;
+
+ return FALSE;
+}
+
+PanoramiXRes *
+PanoramiXFindIDOnAnyScreen(RESTYPE type, XID id)
+{
+ return LookupClientResourceComplex(clients[CLIENT_ID(id)], type,
+ XineramaFindIDOnAnyScreen, &id);
+}
+
+typedef struct {
+ int screen;
+ int id;
+} PanoramiXSearchData;
+
+
+static Bool
+XineramaFindIDByScrnum(pointer resource, XID id, pointer privdata)
+{
+ PanoramiXRes *res = (PanoramiXRes*)resource;
+ PanoramiXSearchData *data = (PanoramiXSearchData*)privdata;
+
+ return (res->info[data->screen].id == data->id);
+}
+
+PanoramiXRes *
+PanoramiXFindIDByScrnum(RESTYPE type, XID id, int screen)
+{
+ PanoramiXSearchData data;
+
+ if(!screen)
+ return LookupIDByType(id, type);
+
+ data.screen = screen;
+ data.id = id;
+
+ return LookupClientResourceComplex(clients[CLIENT_ID(id)], type,
+ XineramaFindIDByScrnum, &data);
+}
+
+WindowPtr
+PanoramiXChangeWindow(int ScrnNum, WindowPtr pWin)
+{
+ int num = pWin->drawable.pScreen->myNum;
+
+ if(num != ScrnNum) {
+ PanoramiXRes *win;
+
+ win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, num);
+
+ if (win)
+ pWin = (WindowPtr) LookupIDByType(win->info[ScrnNum].id, RT_WINDOW);
+ }
+
+ return pWin;
+}
+
+typedef struct _connect_callback_list {
+ void (*func)(void);
+ struct _connect_callback_list *next;
+} XineramaConnectionCallbackList;
+
+static XineramaConnectionCallbackList *ConnectionCallbackList = NULL;
+
+Bool
+XineramaRegisterConnectionBlockCallback(void (*func)(void))
+{
+ XineramaConnectionCallbackList *newlist;
+
+ if(!(newlist = xalloc(sizeof(XineramaConnectionCallbackList))))
+ return FALSE;
+
+ newlist->next = ConnectionCallbackList;
+ newlist->func = func;
+ ConnectionCallbackList = newlist;
+
+ return TRUE;
+}
/*
* PanoramiXExtensionInit():
@@ -134,14 +457,16 @@ int PanoramiXFreeColors(), PanoramiXStoreColors();
void PanoramiXExtensionInit(int argc, char *argv[])
{
- int i, j, PhyScrNum, ArgScrNum;
- Bool success = FALSE;
- ExtensionEntry *extEntry, *AddExtension();
- PanoramiXData *panoramiXtempPtr;
- ScreenPtr pScreen;
+ int i;
+ Bool success = FALSE;
+ ExtensionEntry *extEntry;
+ ScreenPtr pScreen;
+ PanoramiXScreenPtr pScreenPriv;
+ int w, h;
- if (!noPanoramiXExtension)
- {
+ if (noPanoramiXExtension)
+ return;
+
GlobalScrInfo = &screenInfo; /* For debug visibility */
PanoramiXNumScreens = screenInfo.numScreens;
if (PanoramiXNumScreens == 1) { /* Only 1 screen */
@@ -165,13 +490,43 @@ void PanoramiXExtensionInit(int argc, char *argv[])
* run in non-PanoramiXeen mode.
*/
- panoramiXdataPtr = (PanoramiXData *) Xcalloc(PanoramiXNumScreens * sizeof(PanoramiXData));
- PanoramiXWinRoot = (PanoramiXWindow *) Xcalloc(sizeof(PanoramiXWindow));
- PanoramiXGCRoot = (PanoramiXGC *) Xcalloc(sizeof(PanoramiXGC));
- PanoramiXCmapRoot = (PanoramiXCmap *) Xcalloc(sizeof(PanoramiXCmap));
- PanoramiXPmapRoot = (PanoramiXPmap *) Xcalloc(sizeof(PanoramiXPmap));
- BREAK_IF(!(panoramiXdataPtr && PanoramiXWinRoot && PanoramiXGCRoot &&
- PanoramiXCmapRoot && PanoramiXPmapRoot));
+ panoramiXdataPtr = (PanoramiXData *)
+ xcalloc(PanoramiXNumScreens, sizeof(PanoramiXData));
+
+ BREAK_IF(!panoramiXdataPtr);
+ BREAK_IF((PanoramiXGCIndex = AllocateGCPrivateIndex()) < 0);
+ BREAK_IF((PanoramiXScreenIndex = AllocateScreenPrivateIndex()) < 0);
+
+ for (i = 0; i < PanoramiXNumScreens; i++) {
+ pScreen = screenInfo.screens[i];
+ if(!AllocateGCPrivate(pScreen, PanoramiXGCIndex,
+ sizeof(PanoramiXGCRec))) {
+ noPanoramiXExtension = TRUE;
+ return;
+ }
+
+ pScreenPriv = xalloc(sizeof(PanoramiXScreenRec));
+ pScreen->devPrivates[PanoramiXScreenIndex].ptr =
+ (pointer)pScreenPriv;
+ if(!pScreenPriv) {
+ noPanoramiXExtension = TRUE;
+ return;
+ }
+
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+
+ pScreen->CreateGC = XineramaCreateGC;
+ pScreen->CloseScreen = XineramaCloseScreen;
+ }
+
+ XRC_DRAWABLE = CreateNewResourceClass();
+ XRT_WINDOW = CreateNewResourceType(XineramaDeleteResource) |
+ XRC_DRAWABLE;
+ XRT_PIXMAP = CreateNewResourceType(XineramaDeleteResource) |
+ XRC_DRAWABLE;
+ XRT_GC = CreateNewResourceType(XineramaDeleteResource);
+ XRT_COLORMAP = CreateNewResourceType(XineramaDeleteResource);
panoramiXGeneration = serverGeneration;
success = TRUE;
@@ -182,117 +537,40 @@ void PanoramiXExtensionInit(int argc, char *argv[])
ErrorF("%s Extension failed to initialize\n", PANORAMIX_PROTOCOL_NAME);
return;
}
-
- /* Set up a default configuration base on horizontal ordering */
- for (i = PanoramiXNumScreens -1; i >= 0 ; i--) {
- panoramiXdataPtr[i].above = panoramiXdataPtr[i].below = -1;
- panoramiXdataPtr[i].left = panoramiXdataPtr[i].right = -1;
- panoramiXEdgePtr[i].no_edges = TRUE;
- }
- for (i = PanoramiXNumScreens - 1; i >= 0; i--) {
- panoramiXdataPtr[i].left = i - 1;
- panoramiXdataPtr[i].right = i + 1;
- }
- panoramiXdataPtr[PanoramiXNumScreens - 1].right = -1;
+
- /*
- * Position the screens relative to each other based on
- * command line options.
- */
+ REGION_INIT(pScreen, &PanoramiXScreenRegion, NullBox, 1);
+ for (i = 0; i < PanoramiXNumScreens; i++) {
+ BoxRec TheBox;
-#if 0
- for (PhyScrNum = PanoramiXNumScreens - 1; PhyScrNum >= 0; PhyScrNum--) {
- if (wsRemapPhysToLogScreens)
- i = wsPhysToLogScreens[PhyScrNum];
- else
- i = PhyScrNum;
- if (i < 0)
- continue;
- panoramiXdataPtr[i].width = (screenInfo.screens[i])->width;
- panoramiXdataPtr[i].height = (screenInfo.screens[i])->height;
- if (screenArgs[i].flags & ARG_EDGE_L) {
- ArgScrNum = screenArgs[PhyScrNum].edge_left;
- if (ArgScrNum < 0)
- j = -1;
- else {
- if (wsRemapPhysToLogScreens)
- j = wsPhysToLogScreens[ArgScrNum];
- else
- j = ArgScrNum;
- }
- panoramiXdataPtr[i].left = j;
- panoramiXEdgePtr[i].no_edges = FALSE;
- if ( j >= 0)
- panoramiXdataPtr[j].right = i;
- else {
- if ( i >= 1 )
- panoramiXdataPtr[i - 1].right = -1;
- }
- }
- if (screenArgs[i].flags & ARG_EDGE_R) {
- ArgScrNum = screenArgs[PhyScrNum].edge_right;
- if (ArgScrNum < 0)
- j = -1;
- else {
- if (wsRemapPhysToLogScreens)
- j = wsPhysToLogScreens[ArgScrNum];
- else
- j = ArgScrNum;
- }
- panoramiXdataPtr[i].right = j;
- panoramiXEdgePtr[i].no_edges = FALSE;
- if ( j >= 0)
- panoramiXdataPtr[j].left = i;
- }
- if (screenArgs[i].flags & ARG_EDGE_T) {
- ArgScrNum = screenArgs[PhyScrNum].edge_top;
- if (ArgScrNum < 0)
- j = -1;
- else {
- if (wsRemapPhysToLogScreens)
- j = wsPhysToLogScreens[ArgScrNum];
- else
- j = ArgScrNum;
- }
- panoramiXdataPtr[i].above = j;
- panoramiXEdgePtr[i].no_edges = FALSE;
- if ( j >= 0)
- panoramiXdataPtr[j].below = i;
- }
- if (screenArgs[i].flags & ARG_EDGE_B) {
- ArgScrNum = screenArgs[PhyScrNum].edge_bottom;
- if (ArgScrNum < 0)
- j = -1;
- else {
- if (wsRemapPhysToLogScreens)
- j = wsPhysToLogScreens[ArgScrNum];
- else
- j = ArgScrNum;
- }
- panoramiXdataPtr[i].below = j;
- panoramiXEdgePtr[i].no_edges = FALSE;
- if ( j >= 0)
- panoramiXdataPtr[j].above = i;
- }
- }
-#else
- for (PhyScrNum = PanoramiXNumScreens - 1; PhyScrNum >= 0; PhyScrNum--) {
- i = PhyScrNum;
- if (i < 0)
- continue;
+ panoramiXdataPtr[i].x = dixScreenOrigins[i].x;
+ panoramiXdataPtr[i].y = dixScreenOrigins[i].y;
panoramiXdataPtr[i].width = (screenInfo.screens[i])->width;
panoramiXdataPtr[i].height = (screenInfo.screens[i])->height;
+
+ TheBox.x1 = panoramiXdataPtr[i].x;
+ TheBox.x2 = TheBox.x1 + panoramiXdataPtr[i].width;
+ TheBox.y1 = panoramiXdataPtr[i].y;
+ TheBox.y2 = TheBox.y1 + panoramiXdataPtr[i].height;
+
+ REGION_INIT(pScreen, &XineramaScreenRegions[i], &TheBox, 1);
+ REGION_UNION(pScreen, &PanoramiXScreenRegion, &PanoramiXScreenRegion,
+ &XineramaScreenRegions[i]);
}
-#endif
- /*
- * Find the upper-left screen and then locate all the others
- */
- panoramiXtempPtr = panoramiXdataPtr;
- for (i = PanoramiXNumScreens; i; i--, panoramiXtempPtr++)
- if (panoramiXtempPtr->above == -1 && panoramiXtempPtr->left == -1)
- break;
- locate_neighbors(PanoramiXNumScreens - i);
+
+ PanoramiXPixWidth = panoramiXdataPtr[0].x + panoramiXdataPtr[0].width;
+ PanoramiXPixHeight = panoramiXdataPtr[0].y + panoramiXdataPtr[0].height;
+
+ for (i = 1; i < PanoramiXNumScreens; i++) {
+ w = panoramiXdataPtr[i].x + panoramiXdataPtr[i].width;
+ h = panoramiXdataPtr[i].y + panoramiXdataPtr[i].height;
+
+ if(PanoramiXPixWidth < w)
+ PanoramiXPixWidth = w;
+ if(PanoramiXPixHeight < h)
+ PanoramiXPixHeight = h;
+ }
/*
* Put our processes into the ProcVector
@@ -314,9 +592,7 @@ void PanoramiXExtensionInit(int argc, char *argv[])
ProcVector[X_ConfigureWindow] = PanoramiXConfigureWindow;
ProcVector[X_CirculateWindow] = PanoramiXCirculateWindow;
ProcVector[X_GetGeometry] = PanoramiXGetGeometry;
- ProcVector[X_ChangeProperty] = PanoramiXChangeProperty;
- ProcVector[X_DeleteProperty] = PanoramiXDeleteProperty;
- ProcVector[X_SendEvent] = PanoramiXSendEvent;
+ ProcVector[X_TranslateCoords] = PanoramiXTranslateCoords;
ProcVector[X_CreatePixmap] = PanoramiXCreatePixmap;
ProcVector[X_FreePixmap] = PanoramiXFreePixmap;
ProcVector[X_CreateGC] = PanoramiXCreateGC;
@@ -344,252 +620,262 @@ void PanoramiXExtensionInit(int argc, char *argv[])
ProcVector[X_ImageText16] = PanoramiXImageText16;
ProcVector[X_CreateColormap] = PanoramiXCreateColormap;
ProcVector[X_FreeColormap] = PanoramiXFreeColormap;
+ ProcVector[X_CopyColormapAndFree] = PanoramiXCopyColormapAndFree;
ProcVector[X_InstallColormap] = PanoramiXInstallColormap;
ProcVector[X_UninstallColormap] = PanoramiXUninstallColormap;
ProcVector[X_AllocColor] = PanoramiXAllocColor;
ProcVector[X_AllocNamedColor] = PanoramiXAllocNamedColor;
ProcVector[X_AllocColorCells] = PanoramiXAllocColorCells;
+ ProcVector[X_AllocColorPlanes] = PanoramiXAllocColorPlanes;
ProcVector[X_FreeColors] = PanoramiXFreeColors;
- ProcVector[X_StoreColors] = PanoramiXStoreColors;
+ ProcVector[X_StoreColors] = PanoramiXStoreColors;
+ ProcVector[X_StoreNamedColor] = PanoramiXStoreNamedColor;
- }
- else
- return;
+#ifdef RENDER
+ PanoramiXRenderInit ();
+#endif
}
-extern
+
+extern Bool CreateConnectionBlock(void);
+
Bool PanoramiXCreateConnectionBlock(void)
{
- int i;
+ int i, j, length;
+ Bool disableBackingStore = FALSE;
+ Bool disableSaveUnders = FALSE;
int old_width, old_height;
- int width_mult, height_mult;
+ float width_mult, height_mult;
xWindowRoot *root;
xConnSetup *setup;
+ xVisualType *visual;
+ xDepth *depth;
+ VisualPtr pVisual;
+ ScreenPtr pScreen;
/*
* Do normal CreateConnectionBlock but faking it for only one screen
*/
+ if(!PanoramiXNumDepths) {
+ ErrorF("PanoramiX error: Incompatible screens. No common visuals\n");
+ return FALSE;
+ }
+
+ for(i = 1; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
+ if(pScreen->rootDepth != screenInfo.screens[0]->rootDepth) {
+ ErrorF("PanoramiX error: Incompatible screens. Root window depths differ\n");
+ return FALSE;
+ }
+ if(pScreen->backingStoreSupport != screenInfo.screens[0]->backingStoreSupport)
+ disableBackingStore = TRUE;
+ if(pScreen->saveUnderSupport != screenInfo.screens[0]->saveUnderSupport)
+ disableSaveUnders = TRUE;
+ }
+
+ if(disableBackingStore || disableSaveUnders) {
+ for(i = 0; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
+ if(disableBackingStore)
+ pScreen->backingStoreSupport = NotUseful;
+ if(disableSaveUnders)
+ pScreen->saveUnderSupport = NotUseful;
+ }
+ }
+
+ i = screenInfo.numScreens;
+ screenInfo.numScreens = 1;
if (!CreateConnectionBlock()) {
+ screenInfo.numScreens = i;
return FALSE;
}
+ screenInfo.numScreens = i;
+
+ setup = (xConnSetup *) ConnectionInfo;
+ root = (xWindowRoot *) (ConnectionInfo + connBlockScreenStart);
+ length = connBlockScreenStart + sizeof(xWindowRoot);
+
+ /* overwrite the connection block */
+ root->nDepths = PanoramiXNumDepths;
+
+ for (i = 0; i < PanoramiXNumDepths; i++) {
+ depth = (xDepth *) (ConnectionInfo + length);
+ depth->depth = PanoramiXDepths[i].depth;
+ depth->nVisuals = PanoramiXDepths[i].numVids;
+ length += sizeof(xDepth);
+ visual = (xVisualType *)(ConnectionInfo + length);
+
+ for (j = 0; j < depth->nVisuals; j++, visual++) {
+ visual->visualID = PanoramiXDepths[i].vids[j];
+
+ for (pVisual = PanoramiXVisuals;
+ pVisual->vid != visual->visualID;
+ pVisual++)
+ ;
+
+ visual->class = pVisual->class;
+ visual->bitsPerRGB = pVisual->bitsPerRGBValue;
+ visual->colormapEntries = pVisual->ColormapEntries;
+ visual->redMask = pVisual->redMask;
+ visual->greenMask = pVisual->greenMask;
+ visual->blueMask = pVisual->blueMask;
+ }
+
+ length += (depth->nVisuals * sizeof(xVisualType));
+ }
+
+ connSetupPrefix.length = length >> 2;
+
+ xfree(PanoramiXVisuals);
+ for (i = 0; i < PanoramiXNumDepths; i++)
+ xfree(PanoramiXDepths[i].vids);
+ xfree(PanoramiXDepths);
+
/*
* OK, change some dimensions so it looks as if it were one big screen
*/
-
- setup = (xConnSetup *) ConnectionInfo;
- setup->numRoots = 1;
- root = (xWindowRoot *) (ConnectionInfo + connBlockScreenStart);
old_width = root->pixWidth;
old_height = root->pixHeight;
- for (i = PanoramiXNumScreens - 1; i >= 0; i--) {
- if (panoramiXdataPtr[i].right == -1 )
- root->pixWidth = panoramiXdataPtr[i].x + panoramiXdataPtr[i].width;
- if (panoramiXdataPtr[i].below == -1)
- root->pixHeight = panoramiXdataPtr[i].y + panoramiXdataPtr[i].height;
- }
- PanoramiXPixWidth = root->pixWidth;
- PanoramiXPixHeight = root->pixHeight;
- width_mult = root->pixWidth / old_width;
- height_mult = root->pixHeight / old_height;
+
+ root->pixWidth = PanoramiXPixWidth;
+ root->pixHeight = PanoramiXPixHeight;
+ width_mult = (1.0 * root->pixWidth) / old_width;
+ height_mult = (1.0 * root->pixHeight) / old_height;
root->mmWidth *= width_mult;
root->mmHeight *= height_mult;
- return TRUE;
-}
-extern
-Bool PanoramiXCreateScreenRegion(pWin)
-WindowPtr pWin;
-{
- ScreenPtr pScreen;
- BoxRec box;
- int i;
- Bool ret;
-
- pScreen = pWin->drawable.pScreen;
- for (i = 0; i < PanoramiXNumScreens; i++) {
- box.x1 = 0 - panoramiXdataPtr[i].x;
- box.x2 = box.x1 + PanoramiXPixWidth;
- box.y1 = 0 - panoramiXdataPtr[i].y;
- box.y2 = box.y1 + PanoramiXPixHeight;
- REGION_INIT(pScreen, &PanoramiXScreenRegion[i], &box, 1);
- ret = REGION_NOTEMPTY(pScreen, &PanoramiXScreenRegion[i]);
- if (!ret)
- return ret;
- }
- return ret;
-}
+ while(ConnectionCallbackList) {
+ pointer tmp;
-extern
-void PanoramiXDestroyScreenRegion(pWin)
-WindowPtr pWin;
-{
- ScreenPtr pScreen;
- int i;
- Bool ret;
+ tmp = (pointer)ConnectionCallbackList;
+ (*ConnectionCallbackList->func)();
+ ConnectionCallbackList = ConnectionCallbackList->next;
+ xfree(tmp);
+ }
- pScreen = pWin->drawable.pScreen;
- for (i = 0; i < PanoramiXNumScreens; i++)
- REGION_DESTROY(pScreen, &PanoramiXScreenRegion[i]);
+ return TRUE;
}
-/*
- * Assign the Root window and colormap ID's in the PanoramiXScreen Root
- * linked lists. Note: WindowTable gets setup in dix_main by
- * InitRootWindow, and GlobalScrInfo is screenInfo which gets setup
- * by InitOutput.
- */
extern
void PanoramiXConsolidate(void)
{
- int i,j,k,v,d,n, thisMaxDepth;
- int depthIndex;
- DepthPtr pDepth, pLargeDepth;
- VisualPtr pVisual;
- VisualID it;
- register WindowPtr pWin, pLargeWin;
- Bool SameDepth;
-
- PanoramiXLargestScreenDepth.numDepths = (screenInfo.screens[PanoramiXNumScreens -1])->numDepths;
- PanoramiXLargestScreenDepth.screenNum = PanoramiXNumScreens - 1;
- SameDepth = TRUE;
- for (i = 0; i < 2; i++)
- {
- for (j =0; j < 6; j++)
- {
- PanoramiXColorDepthTable[i].panoramiXScreenMap[j].numDepths=0;
- for (n = 0; n < 6; n++)
- {
- PanoramiXColorDepthTable[i].panoramiXScreenMap[j].listDepths[n]=0;
+ int i, j, k;
+ VisualPtr pVisual, pVisual2;
+ ScreenPtr pScreen, pScreen2;
+ PanoramiXRes *root, *defmap;
+
+ if(!PanoramiXVisualTable)
+ PanoramiXVisualTable = xcalloc(256 * MAXSCREENS, sizeof(XID));
+
+ pScreen = screenInfo.screens[0];
+ pVisual = pScreen->visuals;
+
+ PanoramiXNumDepths = 0;
+ PanoramiXDepths = xcalloc(pScreen->numDepths,sizeof(DepthRec));
+ PanoramiXNumVisuals = 0;
+ PanoramiXVisuals = xcalloc(pScreen->numVisuals,sizeof(VisualRec));
+
+ for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
+ PanoramiXVisualTable[pVisual->vid * MAXSCREENS] = pVisual->vid;
+
+ /* check if the visual exists on all screens */
+ for (j = 1; j < PanoramiXNumScreens; j++) {
+ pScreen2 = screenInfo.screens[j];
+ pVisual2 = pScreen2->visuals;
+
+ for (k = 0; k < pScreen2->numVisuals; k++, pVisual2++) {
+ if ((pVisual->class == pVisual2->class) &&
+ (pVisual->ColormapEntries == pVisual2->ColormapEntries) &&
+ (pVisual->nplanes == pVisual2->nplanes) &&
+ (pVisual->redMask == pVisual2->redMask) &&
+ (pVisual->greenMask == pVisual2->greenMask) &&
+ (pVisual->blueMask == pVisual2->blueMask) &&
+ (pVisual->offsetRed == pVisual2->offsetRed) &&
+ (pVisual->offsetGreen == pVisual2->offsetGreen) &&
+ (pVisual->offsetBlue == pVisual2->offsetBlue))
+ {
+ Bool AlreadyUsed = FALSE;
+#if 0
+/* Open GL should do this reduction, not us */
+ for (l = 0; l < 256; l++) {
+ if (pVisual2->vid ==
+ PanoramiXVisualTable[(l * MAXSCREENS) + j])
+ {
+ AlreadyUsed = TRUE;
+ break;
+ }
+ }
+#endif
+ if (!AlreadyUsed) {
+ PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j] =
+ pVisual2->vid;
+ break;
+ }
+ }
+ }
}
- for (k = 0; k < 33; k++)
- {
- PanoramiXColorDepthTable[i].panoramiXScreenMap[j].vmap[k].numVids=0;
- for (v = 0; v < 10; v++)
- {
- PanoramiXColorDepthTable[i].panoramiXScreenMap[j].vmap[k].vid[v]=0;
+
+ /* if it doesn't exist on all screens we can't use it */
+ for (j = 0; j < PanoramiXNumScreens; j++) {
+ if (!PanoramiXVisualTable[(pVisual->vid * MAXSCREENS) + j]) {
+ PanoramiXVisualTable[pVisual->vid * MAXSCREENS] = 0;
+ break;
}
}
- }
- }
- for (i = PanoramiXNumScreens - 1; i >= 0; i--)
- {
- PanoramiXWinRoot->info[i].id = WindowTable[i]->drawable.id;
- PanoramiXCmapRoot->info[i].id = (screenInfo.screens[i])->defColormap;
-
- /* Create a Color-Depth-Table, this will help us deal
- with mixing graphics boards and visuals, of course
- given that the boards support multi-screen to begin
- with. Fill the panoramiXCDT table by screen, then
- visual type and allowable depths.
- */
- pWin = WindowTable[i];
- if ( (screenInfo.screens[i])->numDepths >
- PanoramiXLargestScreenDepth.numDepths )
- {
- PanoramiXLargestScreenDepth.numDepths = (screenInfo.screens[i])->numDepths;
- PanoramiXLargestScreenDepth.screenNum = i;
- SameDepth = FALSE;
- }
- for (v = 0, pVisual = pWin->drawable.pScreen->visuals;
- v < pWin->drawable.pScreen->numVisuals; v++, pVisual++)
- {
- PanoramiXColorDepthTable[i].panoramiXScreenMap[pVisual->class].numDepths = (screenInfo.screens[i])->numDepths;
- for ( j = 0; j < (screenInfo.screens[i])->numDepths; j++)
- {
- pDepth = (DepthPtr) &pWin->drawable.pScreen->allowedDepths[j];
- PanoramiXColorDepthTable[i].panoramiXScreenMap[pVisual->class].listDepths[j] = pDepth->depth;
- for (d = 0; d < pDepth->numVids; d++)
- {
- if (pVisual->vid == pDepth->vids[d])
- {
- PanoramiXColorDepthTable[i].
- panoramiXScreenMap[pVisual->class].vmap[pDepth->depth].
- vid[
- PanoramiXColorDepthTable[i].
- panoramiXScreenMap[pVisual->class].
- vmap[pDepth->depth].numVids++
- ]
- = pDepth->vids[d];
- }
- }
- }
- }
- PanoramiXColorDepthTable[i].numVisuals = 6;
- } /* for each screen */
- /* Fill in ColorDepthTable for mixed visuals with varying depth.
- Can't do that until we figure out how to handle mixed visuals
- and varying card visual/depth initialization. If we can decide
- how to map the relationship, then we can use this table to
- shove the information into and use for cross-referencing when
- necessary.
-
- In the meantime, check to see if the screens are the same,
- if they don't then disable panoramiX, print out a message,
- don't support this mode.
- */
-}
-/* Since locate_neighbors is recursive, a quick simple example
- is in order.This mostly so you can see what the initial values are.
-
- Given 3 screens:
- upperleft screen[0]
- panoramiXdataPtr[0].x = 0
- panoramiXdataPtr[0].y = 0
- panoramiXdataPtr[0].width = 640
- panoramiXdataPtr[0].height = 480
- panoramiXdataPtr[0].below = -1
- panoramiXdataPtr[0].right = 1
- panoramiXdataPtr[0].above = -1
- panoramiXdataPtr[0].left = -1
- middle screen[1]
- panoramiXdataPtr[1].x = 0
- panoramiXdataPtr[1].y = 0
- panoramiXdataPtr[1].width = 640
- panoramiXdataPtr[1].height = 480
- panoramiXdataPtr[1].below = -1
- panoramiXdataPtr[1].right = 2
- panoramiXdataPtr[1].above = -1
- panoramiXdataPtr[1].left = 0
- last right screen[2]
- panoramiXdataPtr[2].x = 0
- panoramiXdataPtr[2].y = 0
- panoramiXdataPtr[2].width = 640
- panoramiXdataPtr[2].height = 480
- panoramiXdataPtr[2].below = -1
- panoramiXdataPtr[2].right = -1
- panoramiXdataPtr[2].above = -1
- panoramiXdataPtr[2].left = 1
-
- Calling locate_neighbors(0) results in:
- panoramiXdataPtr[0].x = 0
- panoramiXdataPtr[0].y = 0
- panoramiXdataPtr[1].x = 640
- panoramiXdataPtr[1].y = 0
- panoramiXdataPtr[2].x = 1280
- panoramiXdataPtr[2].y = 0
-*/
-
-static void locate_neighbors(int i)
-{
- int j;
-
- j = panoramiXdataPtr[i].right;
- if ((j != -1) && !panoramiXdataPtr[j].x && !panoramiXdataPtr[j].y) {
- panoramiXdataPtr[j].x = panoramiXdataPtr[i].x + panoramiXdataPtr[i].width;
- panoramiXdataPtr[j].y = panoramiXdataPtr[i].y;
- locate_neighbors(j);
- }
- j = panoramiXdataPtr[i].below;
- if ((j != -1) && !panoramiXdataPtr[j].x && !panoramiXdataPtr[j].y) {
- panoramiXdataPtr[j].y = panoramiXdataPtr[i].y + panoramiXdataPtr[i].height;
- panoramiXdataPtr[j].x = panoramiXdataPtr[i].x;
- locate_neighbors(j);
+ /* if it does, make sure it's in the list of supported depths and visuals */
+ if(PanoramiXVisualTable[pVisual->vid * MAXSCREENS]) {
+ Bool GotIt = FALSE;
+
+ PanoramiXVisuals[PanoramiXNumVisuals].vid = pVisual->vid;
+ PanoramiXVisuals[PanoramiXNumVisuals].class = pVisual->class;
+ PanoramiXVisuals[PanoramiXNumVisuals].bitsPerRGBValue = pVisual->bitsPerRGBValue;
+ PanoramiXVisuals[PanoramiXNumVisuals].ColormapEntries = pVisual->ColormapEntries;
+ PanoramiXVisuals[PanoramiXNumVisuals].nplanes = pVisual->nplanes;
+ PanoramiXVisuals[PanoramiXNumVisuals].redMask = pVisual->redMask;
+ PanoramiXVisuals[PanoramiXNumVisuals].greenMask = pVisual->greenMask;
+ PanoramiXVisuals[PanoramiXNumVisuals].blueMask = pVisual->blueMask;
+ PanoramiXVisuals[PanoramiXNumVisuals].offsetRed = pVisual->offsetRed;
+ PanoramiXVisuals[PanoramiXNumVisuals].offsetGreen = pVisual->offsetGreen;
+ PanoramiXVisuals[PanoramiXNumVisuals].offsetBlue = pVisual->offsetBlue;
+ PanoramiXNumVisuals++;
+
+ for (j = 0; j < PanoramiXNumDepths; j++) {
+ if (PanoramiXDepths[j].depth == pVisual->nplanes) {
+ PanoramiXDepths[j].vids[PanoramiXDepths[j].numVids] = pVisual->vid;
+ PanoramiXDepths[j].numVids++;
+ GotIt = TRUE;
+ break;
+ }
+ }
+
+ if (!GotIt) {
+ PanoramiXDepths[PanoramiXNumDepths].depth = pVisual->nplanes;
+ PanoramiXDepths[PanoramiXNumDepths].numVids = 1;
+ PanoramiXDepths[PanoramiXNumDepths].vids = xalloc(sizeof(VisualID) * 256);
+ PanoramiXDepths[PanoramiXNumDepths].vids[0] = pVisual->vid;
+ PanoramiXNumDepths++;
+ }
+ }
+ }
+
+
+ root = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes));
+ root->type = XRT_WINDOW;
+ defmap = (PanoramiXRes *) xalloc(sizeof(PanoramiXRes));
+ defmap->type = XRT_COLORMAP;
+
+ for (i = 0; i < PanoramiXNumScreens; i++) {
+ root->info[i].id = WindowTable[i]->drawable.id;
+ root->u.win.class = InputOutput;
+ defmap->info[i].id = (screenInfo.screens[i])->defColormap;
}
-}
+ AddResource(root->info[0].id, XRT_WINDOW, root);
+ AddResource(defmap->info[0].id, XRT_COLORMAP, defmap);
+}
/*
@@ -597,46 +883,25 @@ static void locate_neighbors(int i)
* Exit, deallocating as needed.
*/
-static void PanoramiXResetProc(extEntry)
- ExtensionEntry* extEntry;
+static void PanoramiXResetProc(ExtensionEntry* extEntry)
{
int i;
- PanoramiXList *pPanoramiXList;
- PanoramiXList *tempList;
- for (pPanoramiXList = PanoramiXPmapRoot; pPanoramiXList; pPanoramiXList = tempList){
- tempList = pPanoramiXList->next;
- Xfree(pPanoramiXList);
- }
- for (pPanoramiXList = PanoramiXCmapRoot; pPanoramiXList; pPanoramiXList = tempList){
- tempList = pPanoramiXList->next;
- Xfree(pPanoramiXList);
- }
- for (pPanoramiXList = PanoramiXGCRoot; pPanoramiXList; pPanoramiXList = tempList) {
- tempList = pPanoramiXList->next;
- Xfree(pPanoramiXList);
- }
- for (pPanoramiXList = PanoramiXWinRoot; pPanoramiXList; pPanoramiXList = tempList) {
- tempList = pPanoramiXList->next;
- Xfree(pPanoramiXList);
- }
+#ifdef RENDER
+ PanoramiXRenderReset ();
+#endif
screenInfo.numScreens = PanoramiXNumScreens;
for (i = 256; i--; )
ProcVector[i] = SavedProcVector[i];
- Xfree(panoramiXdataPtr);
-
+
+ Xfree(panoramiXdataPtr);
}
int
-#if NeedFunctionPrototypes
ProcPanoramiXQueryVersion (ClientPtr client)
-#else
-ProcPanoramiXQueryVersion (client)
- register ClientPtr client;
-#endif
{
- REQUEST(xPanoramiXQueryVersionReq);
+ /* REQUEST(xPanoramiXQueryVersionReq); */
xPanoramiXQueryVersionReply rep;
register int n;
@@ -649,18 +914,15 @@ ProcPanoramiXQueryVersion (client)
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
-#if NeedFunctionPrototypes
ProcPanoramiXGetState(ClientPtr client)
-#else
-ProcPanoramiXGetState(client)
- register ClientPtr client;
-#endif
{
REQUEST(xPanoramiXGetStateReq);
WindowPtr pWin;
@@ -686,12 +948,7 @@ ProcPanoramiXGetState(client)
}
int
-#if NeedFunctionPrototypes
ProcPanoramiXGetScreenCount(ClientPtr client)
-#else
-ProcPanoramiXGetScreenCount(client)
- register ClientPtr client;
-#endif
{
REQUEST(xPanoramiXGetScreenCountReq);
WindowPtr pWin;
@@ -716,12 +973,7 @@ ProcPanoramiXGetScreenCount(client)
}
int
-#if NeedFunctionPrototypes
ProcPanoramiXGetScreenSize(ClientPtr client)
-#else
-ProcPanoramiXGetScreenSize(client)
- register ClientPtr client;
-#endif
{
REQUEST(xPanoramiXGetScreenSizeReq);
WindowPtr pWin;
@@ -741,29 +993,84 @@ ProcPanoramiXGetScreenSize(client)
if (client->swapped) {
swaps (&rep.sequenceNumber, n);
swapl (&rep.length, n);
- swaps (rep.width, n);
- swaps (rep.height, n);
+ swaps (&rep.width, n);
+ swaps (&rep.height, n);
}
WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), (char *) &rep);
return client->noClientException;
}
-void PrintList(PanoramiXList *head)
+int
+ProcXineramaIsActive(ClientPtr client)
+{
+ /* REQUEST(xXineramaIsActiveReq); */
+ xXineramaIsActiveReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !noPanoramiXExtension;
+ 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
+ProcXineramaQueryScreens(ClientPtr client)
{
- int i = 0;
+ /* REQUEST(xXineramaQueryScreensReq); */
+ xXineramaQueryScreensReply rep;
+
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens;
+ 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);
- for (; head; i++, head = head->next)
- fprintf(stderr, "%2d next = 0x%010lx, id[0] = 0x%08x, id[1] = 0x%08x\n",
- i, head->next, head->info[0].id, head->info[1].id);
+ if(!noPanoramiXExtension) {
+ xXineramaScreenInfo scratch;
+ int i;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ scratch.x_org = panoramiXdataPtr[i].x;
+ scratch.y_org = panoramiXdataPtr[i].y;
+ scratch.width = panoramiXdataPtr[i].width;
+ scratch.height = panoramiXdataPtr[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
-#if NeedFunctionPrototypes
ProcPanoramiXDispatch (ClientPtr client)
-#else
-ProcPanoramiXDispatch (client)
- ClientPtr client;
-#endif
{ REQUEST(xReq);
switch (stuff->data)
{
@@ -775,6 +1082,184 @@ ProcPanoramiXDispatch (client)
return ProcPanoramiXGetScreenCount(client);
case X_PanoramiXGetScreenSize:
return ProcPanoramiXGetScreenSize(client);
+ case X_XineramaIsActive:
+ return ProcXineramaIsActive(client);
+ case X_XineramaQueryScreens:
+ return ProcXineramaQueryScreens(client);
}
return BadRequest;
}
+
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+#define SHIFT_L(v,s) (v) << (s)
+#define SHIFT_R(v,s) (v) >> (s)
+#else
+#define SHIFT_L(v,s) (v) >> (s)
+#define SHIFT_R(v,s) (v) << (s)
+#endif
+
+static void
+CopyBits(char *dst, int shiftL, char *src, int bytes)
+{
+ /* Just get it to work. Worry about speed later */
+ int shiftR = 8 - shiftL;
+
+ while(bytes--) {
+ *dst |= SHIFT_L(*src, shiftL);
+ *(dst + 1) |= SHIFT_R(*src, shiftR);
+ dst++; src++;
+ }
+}
+
+
+/* Caution. This doesn't support 2 and 4 bpp formats. We expect
+ 1 bpp and planar data to be already cleared when presented
+ to this function */
+
+void
+XineramaGetImageData(
+ DrawablePtr *pDrawables,
+ int left,
+ int top,
+ int width,
+ int height,
+ unsigned int format,
+ unsigned long planemask,
+ char *data,
+ int pitch,
+ Bool isRoot
+){
+ RegionRec SrcRegion, GrabRegion;
+ BoxRec SrcBox, *pbox;
+ int x, y, w, h, i, j, nbox, size, sizeNeeded, ScratchPitch, inOut, depth;
+ DrawablePtr pDraw = pDrawables[0];
+ char *ScratchMem = NULL;
+
+ size = 0;
+
+ /* find box in logical screen space */
+ SrcBox.x1 = left;
+ SrcBox.y1 = top;
+ if(!isRoot) {
+ SrcBox.x1 += pDraw->x + panoramiXdataPtr[0].x;
+ SrcBox.y1 += pDraw->y + panoramiXdataPtr[0].y;
+ }
+ SrcBox.x2 = SrcBox.x1 + width;
+ SrcBox.y2 = SrcBox.y1 + height;
+
+ REGION_INIT(pScreen, &SrcRegion, &SrcBox, 1);
+ REGION_INIT(pScreen, &GrabRegion, NullBox, 1);
+
+ depth = (format == XYPixmap) ? 1 : pDraw->depth;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ pDraw = pDrawables[i];
+
+ inOut = RECT_IN_REGION(pScreen,&XineramaScreenRegions[i],&SrcBox);
+
+ if(inOut == rgnIN) {
+ (*pDraw->pScreen->GetImage)(pDraw,
+ SrcBox.x1 - pDraw->x - panoramiXdataPtr[i].x,
+ SrcBox.y1 - pDraw->y - panoramiXdataPtr[i].y,
+ width, height, format, planemask, data);
+ break;
+ } else if (inOut == rgnOUT)
+ continue;
+
+ REGION_INTERSECT(pScreen, &GrabRegion, &SrcRegion,
+ &XineramaScreenRegions[i]);
+
+ nbox = REGION_NUM_RECTS(&GrabRegion);
+
+ if(nbox) {
+ pbox = REGION_RECTS(&GrabRegion);
+
+ while(nbox--) {
+ w = pbox->x2 - pbox->x1;
+ h = pbox->y2 - pbox->y1;
+ ScratchPitch = PixmapBytePad(w, depth);
+ sizeNeeded = ScratchPitch * h;
+
+ if(sizeNeeded > size) {
+ char *tmpdata = ScratchMem;
+ ScratchMem = xrealloc(ScratchMem, sizeNeeded);
+ if(ScratchMem)
+ size = sizeNeeded;
+ else {
+ ScratchMem = tmpdata;
+ break;
+ }
+ }
+
+ x = pbox->x1 - pDraw->x - panoramiXdataPtr[i].x;
+ y = pbox->y1 - pDraw->y - panoramiXdataPtr[i].y;
+
+ (*pDraw->pScreen->GetImage)(pDraw, x, y, w, h,
+ format, planemask, ScratchMem);
+
+ /* copy the memory over */
+
+ if(depth == 1) {
+ int k, shift, leftover, index, index2;
+
+ x = pbox->x1 - SrcBox.x1;
+ y = pbox->y1 - SrcBox.y1;
+ shift = x & 7;
+ x >>= 3;
+ leftover = w & 7;
+ w >>= 3;
+
+ /* clean up the edge */
+ if(leftover) {
+ int mask = (1 << leftover) - 1;
+ for(j = h, k = w; j--; k += ScratchPitch)
+ ScratchMem[k] &= mask;
+ }
+
+ for(j = 0, index = (pitch * y) + x, index2 = 0; j < h;
+ j++, index += pitch, index2 += ScratchPitch)
+ {
+ if(w) {
+ if(!shift)
+ memcpy(data + index, ScratchMem + index2, w);
+ else
+ CopyBits(data + index, shift,
+ ScratchMem + index2, w);
+ }
+
+ if(leftover) {
+ data[index + w] |=
+ SHIFT_L(ScratchMem[index2 + w], shift);
+ if((shift + leftover) > 8)
+ data[index + w + 1] |=
+ SHIFT_R(ScratchMem[index2 + w],(8 - shift));
+ }
+ }
+ } else {
+ j = BitsPerPixel(depth) >> 3;
+ x = (pbox->x1 - SrcBox.x1) * j;
+ y = pbox->y1 - SrcBox.y1;
+ w *= j;
+
+ for(j = 0; j < h; j++) {
+ memcpy(data + (pitch * (y + j)) + x,
+ ScratchMem + (ScratchPitch * j), w);
+ }
+ }
+ pbox++;
+ }
+
+ REGION_SUBTRACT(pScreen, &SrcRegion, &SrcRegion, &GrabRegion);
+ if(!REGION_NOTEMPTY(pScreen, &SrcRegion))
+ break;
+ }
+
+ }
+
+ if(ScratchMem)
+ xfree(ScratchMem);
+
+ REGION_UNINIT(pScreen, &SrcRegion);
+ REGION_UNINIT(pScreen, &GrabRegion);
+}