diff options
Diffstat (limited to 'hw/xfree86/common/xf86Cursor.c')
-rw-r--r-- | hw/xfree86/common/xf86Cursor.c | 750 |
1 files changed, 588 insertions, 162 deletions
diff --git a/hw/xfree86/common/xf86Cursor.c b/hw/xfree86/common/xf86Cursor.c index 6c0943b41..1a214c4ad 100644 --- a/hw/xfree86/common/xf86Cursor.c +++ b/hw/xfree86/common/xf86Cursor.c @@ -1,27 +1,5 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Cursor.c,v 3.13 1996/12/23 06:43:22 dawes Exp $ */ -/* - * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Thomas Roell not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Thomas Roell makes no representations - * about the suitability of this software for any purpose. It is provided - * "as is" without express or implied warranty. - * - * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - * - */ -/* $Xorg: xf86Cursor.c,v 1.3 2000/08/17 19:50:29 cpqbld Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86Cursor.c,v 3.35 2003/02/13 10:49:38 eich Exp $ */ +/* $XConsortium: xf86Cursor.c /main/10 1996/10/19 17:58:23 kaleb $ */ #define NEED_EVENTS #include "X.h" @@ -30,73 +8,72 @@ #include "cursor.h" #include "mipointer.h" #include "scrnintstr.h" +#include "globals.h" #include "compiler.h" #include "xf86.h" -#include "xf86Procs.h" -#ifdef XFreeXDGA -#include "Xproto.h" -#include "extnsionst.h" -#include "scrnintstr.h" -#include "servermd.h" - -#define _XF86DGA_SERVER_ -#include "extensions/xf86dgastr.h" -#endif +#include "xf86Priv.h" +#include "xf86_OSproc.h" #ifdef XINPUT -#include "xf86_Config.h" #include "XIproto.h" #include "xf86Xinput.h" #endif -/* #include "atKeynames.h" -hv- dont need that include here */ +#ifdef XFreeXDGA +#include "dgaproc.h" +#endif +typedef struct _xf86EdgeRec { + short screen; + short start; + short end; + DDXPointRec offset; + struct _xf86EdgeRec *next; +} xf86EdgeRec, *xf86EdgePtr; -static Bool xf86CursorOffScreen( -#if NeedFunctionPrototypes - ScreenPtr *pScreen, - int *x, - int *y -#endif -); -static void xf86CrossScreen( -#if NeedFunctionPrototypes - ScreenPtr pScreen, - Bool entering -#endif -); -static void xf86WrapCursor( -#if NeedFunctionPrototypes - ScreenPtr pScreen, - int x, - int y -#endif -); +typedef struct { + xf86EdgePtr left, right, up, down; +} xf86ScreenLayoutRec, *xf86ScreenLayoutPtr; + +static Bool xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y); +static void xf86CrossScreen(ScreenPtr pScreen, Bool entering); +static void xf86WarpCursor(ScreenPtr pScreen, int x, int y); + +static void xf86PointerMoved(int scrnIndex, int x, int y); -miPointerScreenFuncRec xf86PointerScreenFuncs = { +static miPointerScreenFuncRec xf86PointerScreenFuncs = { xf86CursorOffScreen, xf86CrossScreen, - xf86WrapCursor, + xf86WarpCursor, #ifdef XINPUT xf86eqEnqueue, + xf86eqSwitchScreen +#else + /* let miPointerInitialize take care of these */ + NULL, + NULL #endif }; +static xf86ScreenLayoutRec xf86ScreenLayout[MAXSCREENS]; +static Bool HardEdges; /* * xf86InitViewport -- * Initialize paning & zooming parameters, so that a driver must only * check what resolutions are possible and whether the virtual area - * is valid if specifyed. + * is valid if specified. */ void -xf86InitViewport(pScr) - ScrnInfoPtr pScr; +xf86InitViewport(ScrnInfoPtr pScr) { + + pScr->PointerMoved = xf86PointerMoved; + /* * Compute the initial Viewport if necessary */ @@ -131,163 +108,269 @@ xf86InitViewport(pScr) */ void -xf86SetViewport(pScreen, x, y) - ScreenPtr pScreen; - int x, y; +xf86SetViewport(ScreenPtr pScreen, int x, int y) { - Bool frameChanged = FALSE; ScrnInfoPtr pScr = XF86SCRNINFO(pScreen); + (*pScr->PointerMoved)(pScreen->myNum, x, y); +} + + +static void +xf86PointerMoved(int scrnIndex, int x, int y) +{ + Bool frameChanged = FALSE; + ScrnInfoPtr pScr = xf86Screens[scrnIndex]; + /* * check wether (x,y) belongs to the visual part of the screen * if not, change the base of the displayed frame accoring */ if ( pScr->frameX0 > x) { pScr->frameX0 = x; - pScr->frameX1 = x + pScr->modes->HDisplay - 1; + pScr->frameX1 = x + pScr->currentMode->HDisplay - 1; frameChanged = TRUE ; } if ( pScr->frameX1 < x) { pScr->frameX1 = x + 1; - pScr->frameX0 = x - pScr->modes->HDisplay + 1; + pScr->frameX0 = x - pScr->currentMode->HDisplay + 1; frameChanged = TRUE ; } if ( pScr->frameY0 > y) { pScr->frameY0 = y; - pScr->frameY1 = y + pScr->modes->VDisplay - 1; + pScr->frameY1 = y + pScr->currentMode->VDisplay - 1; frameChanged = TRUE; } if ( pScr->frameY1 < y) { pScr->frameY1 = y; - pScr->frameY0 = y - pScr->modes->VDisplay + 1; + pScr->frameY0 = y - pScr->currentMode->VDisplay + 1; frameChanged = TRUE; } - if (frameChanged) (pScr->AdjustFrame)(pScr->frameX0, pScr->frameY0); + if (frameChanged && pScr->AdjustFrame != NULL) + pScr->AdjustFrame(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0); } - -static Bool xf86ZoomLocked = FALSE; - /* * xf86LockZoom -- * Enable/disable ZoomViewport */ void -xf86LockZoom (pScreen, lock) - ScreenPtr pScreen; - Bool lock; +xf86LockZoom(ScreenPtr pScreen, Bool lock) { - /* - * pScreen is currently ignored, but may be used later to enable locking - * of individual screens. - */ - - xf86ZoomLocked = lock; + XF86SCRNINFO(pScreen)->zoomLocked = lock; } /* - * xf86ZoomViewport -- - * Reinitialize the visual part of the screen for another modes-> + * xf86SwitchMode -- + * This is called by both keyboard processing and the VidMode extension to + * set a new mode. */ -void -xf86ZoomViewport (pScreen, zoom) - ScreenPtr pScreen; - int zoom; +Bool +xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode) { - ScrnInfoPtr pScr = XF86SCRNINFO(pScreen); + ScrnInfoPtr pScr = XF86SCRNINFO(pScreen); + ScreenPtr pCursorScreen; + Bool Switched; + int px, py; - if (xf86ZoomLocked) - return; + if (!pScr->vtSema || !mode || !pScr->SwitchMode) + return FALSE; #ifdef XFreeXDGA - /* - * We should really send the mode change request to the DGA client and let - * it decide what to do. For now just bin the request - */ - if (((ScrnInfoPtr)(xf86Info.currentScreen->devPrivates[xf86ScreenIndex].ptr))->directMode&XF86DGADirectGraphics) - return; + if (DGAActive(pScr->scrnIndex)) + return FALSE; #endif - if (pScr->modes != pScr->modes->next) - { - pScr->modes = zoom > 0 ? pScr->modes->next : pScr->modes->prev; + if (mode == pScr->currentMode) + return TRUE; + + if (mode->HDisplay > pScreen->width || mode->VDisplay > pScreen->height) + return FALSE; + + pCursorScreen = miPointerCurrentScreen(); + if (pScreen == pCursorScreen) + miPointerPosition(&px, &py); + + xf86EnterServerState(SETUP); + Switched = (*pScr->SwitchMode)(pScr->scrnIndex, mode, 0); + xf86EnterServerState(OPERATING); + if (Switched) { + pScr->currentMode = mode; + + /* + * Adjust frame for new display size. + */ + if (pScreen == pCursorScreen) + pScr->frameX0 = px - (mode->HDisplay / 2) + 1; + else + pScr->frameX0 = (pScr->frameX0 + pScr->frameX1 + 1 - mode->HDisplay) / 2; + + if (pScr->frameX0 < 0) + pScr->frameX0 = 0; + + pScr->frameX1 = pScr->frameX0 + mode->HDisplay - 1; + if (pScr->frameX1 >= pScr->virtualX) { + pScr->frameX0 = pScr->virtualX - mode->HDisplay; + pScr->frameX1 = pScr->virtualX - 1; + } - if ((pScr->SwitchMode)(pScr->modes)) - { - /* - * adjust new frame for the displaysize - */ - pScr->frameX0 = (pScr->frameX1 + pScr->frameX0 -pScr->modes->HDisplay)/2; - pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1; - - if (pScr->frameX0 < 0) - { - pScr->frameX0 = 0; - pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1; - } - else if (pScr->frameX1 >= pScr->virtualX) - { - pScr->frameX0 = pScr->virtualX - pScr->modes->HDisplay; - pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1; - } - - pScr->frameY0 = (pScr->frameY1 + pScr->frameY0 - pScr->modes->VDisplay)/2; - pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1; - - if (pScr->frameY0 < 0) - { - pScr->frameY0 = 0; - pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1; - } - else if (pScr->frameY1 >= pScr->virtualY) - { - pScr->frameY0 = pScr->virtualY - pScr->modes->VDisplay; - pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1; - } + if (pScreen == pCursorScreen) + pScr->frameY0 = py - (mode->VDisplay / 2) + 1; + else + pScr->frameY0 = (pScr->frameY0 + pScr->frameY1 + 1 - mode->VDisplay) / 2; + + if (pScr->frameY0 < 0) + pScr->frameY0 = 0; + + pScr->frameY1 = pScr->frameY0 + mode->VDisplay - 1; + if (pScr->frameY1 >= pScr->virtualY) { + pScr->frameY0 = pScr->virtualY - mode->VDisplay; + pScr->frameY1 = pScr->virtualY - 1; } - else /* switch failed, so go back to old mode */ - pScr->modes = zoom > 0 ? pScr->modes->prev : pScr->modes->next; } - (pScr->AdjustFrame)(pScr->frameX0, pScr->frameY0); + if (pScr->AdjustFrame) + (*pScr->AdjustFrame)(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0); + + if (pScreen == pCursorScreen) + xf86WarpCursor(pScreen, px, py); + + return Switched; } + +/* + * xf86ZoomViewport -- + * Reinitialize the visual part of the screen for another mode. + */ +void +xf86ZoomViewport(ScreenPtr pScreen, int zoom) +{ + ScrnInfoPtr pScr = XF86SCRNINFO(pScreen); + DisplayModePtr mode; + + if (pScr->zoomLocked || !(mode = pScr->currentMode)) + return; + + do { + if (zoom > 0) + mode = mode->next; + else + mode = mode->prev; + } while (mode != pScr->currentMode && !(mode->type & M_T_USERDEF)); + + (void)xf86SwitchMode(pScreen, mode); +} + + +static xf86EdgePtr +FindEdge(xf86EdgePtr edge, int val) +{ + while(edge && (edge->end <= val)) + edge = edge->next; + if(edge && (edge->start <= val)) + return edge; + + return NULL; +} /* * xf86CursorOffScreen -- * Check whether it is necessary to switch to another screen */ -/* ARGSUSED */ static Bool -xf86CursorOffScreen (pScreen, x, y) - ScreenPtr *pScreen; - int *x, *y; +xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y) { - int i; - - if ((screenInfo.numScreens > 1) && ((*x < 0) || ((*pScreen)->width <= *x))) { - i = (*pScreen)->myNum; - if (*x < 0) { - i = (i ? i : screenInfo.numScreens) -1; - *pScreen = screenInfo.screens[i]; - *x += (*pScreen)->width; + xf86EdgePtr edge; + int tmp; + + if(screenInfo.numScreens == 1) + return FALSE; + + if(*x < 0) { + tmp = *y; + if(tmp < 0) tmp = 0; + if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1; + + if((edge = xf86ScreenLayout[(*pScreen)->myNum].left)) + edge = FindEdge(edge, tmp); + + if(!edge) *x = 0; + else { + *x += edge->offset.x; + *y += edge->offset.y; + *pScreen = xf86Screens[edge->screen]->pScreen; + } + } + + if(*x >= (*pScreen)->width) { + tmp = *y; + if(tmp < 0) tmp = 0; + if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1; + + if((edge = xf86ScreenLayout[(*pScreen)->myNum].right)) + edge = FindEdge(edge, tmp); + + if(!edge) *x = (*pScreen)->width - 1; + else { + *x += edge->offset.x; + *y += edge->offset.y; + *pScreen = xf86Screens[edge->screen]->pScreen; + } } - else { - *x -= (*pScreen)->width; - i = (i+1) % screenInfo.numScreens; - *pScreen = screenInfo.screens[i]; + + if(*y < 0) { + tmp = *x; + if(tmp < 0) tmp = 0; + if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1; + + if((edge = xf86ScreenLayout[(*pScreen)->myNum].up)) + edge = FindEdge(edge, tmp); + + if(!edge) *y = 0; + else { + *x += edge->offset.x; + *y += edge->offset.y; + *pScreen = xf86Screens[edge->screen]->pScreen; + } } - return(TRUE); - } - return(FALSE); + + if(*y >= (*pScreen)->height) { + tmp = *x; + if(tmp < 0) tmp = 0; + if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1; + + if((edge = xf86ScreenLayout[(*pScreen)->myNum].down)) + edge = FindEdge(edge, tmp); + + if(!edge) *y = (*pScreen)->height - 1; + else { + *x += edge->offset.x; + *y += edge->offset.y; + (*pScreen) = xf86Screens[edge->screen]->pScreen; + } + } + + +#if 0 + /* This presents problems for overlapping screens when + HardEdges is used. Have to think about the logic more */ + if((*x < 0) || (*x >= (*pScreen)->width) || + (*y < 0) || (*y >= (*pScreen)->height)) { + /* We may have crossed more than one screen */ + xf86CursorOffScreen(pScreen, x, y); + } +#endif + + return TRUE; } @@ -297,30 +380,373 @@ xf86CursorOffScreen (pScreen, x, y) * Switch to another screen */ +/* NEED TO CHECK THIS */ /* ARGSUSED */ static void -xf86CrossScreen (pScreen, entering) - ScreenPtr pScreen; - Bool entering; +xf86CrossScreen (ScreenPtr pScreen, Bool entering) { +#if 0 if (xf86Info.sharedMonitor) (XF86SCRNINFO(pScreen)->EnterLeaveMonitor)(entering); (XF86SCRNINFO(pScreen)->EnterLeaveCursor)(entering); +#endif } /* - * xf86WrapCursor -- - * Wrap possible to another screen + * xf86WarpCursor -- + * Warp possible to another screen */ /* ARGSUSED */ static void -xf86WrapCursor (pScreen, x, y) - ScreenPtr pScreen; - int x,y; +xf86WarpCursor (ScreenPtr pScreen, int x, int y) { + int sigstate; + sigstate = xf86BlockSIGIO (); miPointerWarpCursor(pScreen,x,y); xf86Info.currentScreen = pScreen; + xf86UnblockSIGIO (sigstate); +} + + +void * +xf86GetPointerScreenFuncs(void) +{ + return (void *)&xf86PointerScreenFuncs; +} + + +static xf86EdgePtr +AddEdge( + xf86EdgePtr edge, + short min, + short max, + short dx, + short dy, + short screen +){ + xf86EdgePtr pEdge = edge, pPrev = NULL, pNew; + + while(1) { + while(pEdge && (min >= pEdge->end)) { + pPrev = pEdge; + pEdge = pEdge->next; + } + + if(!pEdge) { + if(!(pNew = xalloc(sizeof(xf86EdgeRec)))) + break; + + pNew->screen = screen; + pNew->start = min; + pNew->end = max; + pNew->offset.x = dx; + pNew->offset.y = dy; + pNew->next = NULL; + + if(pPrev) + pPrev->next = pNew; + else + edge = pNew; + + break; + } else if (min < pEdge->start) { + if(!(pNew = xalloc(sizeof(xf86EdgeRec)))) + break; + + pNew->screen = screen; + pNew->start = min; + pNew->offset.x = dx; + pNew->offset.y = dy; + pNew->next = pEdge; + + if(pPrev) pPrev->next = pNew; + else edge = pNew; + + if(max <= pEdge->start) { + pNew->end = max; + break; + } else { + pNew->end = pEdge->start; + min = pEdge->end; + } + } else + min = pEdge->end; + + pPrev = pEdge; + pEdge = pEdge->next; + + if(max <= min) break; + } + + return edge; +} + +static void +FillOutEdge(xf86EdgePtr pEdge, int limit) +{ + xf86EdgePtr pNext; + int diff; + + if(pEdge->start > 0) pEdge->start = 0; + + while((pNext = pEdge->next)) { + diff = pNext->start - pEdge->end; + if(diff > 0) { + pEdge->end += diff >> 1; + pNext->start -= diff - (diff >> 1); + } + pEdge = pNext; + } + + if(pEdge->end < limit) + pEdge->end = limit; +} + +/* + * xf86InitOrigins() can deal with a maximum of 32 screens + * on 32 bit architectures, 64 on 64 bit architectures. + */ + +void +xf86InitOrigins(void) +{ + unsigned long screensLeft, prevScreensLeft, mask; + screenLayoutPtr screen; + ScreenPtr pScreen; + int x1, x2, y1, y2, left, right, top, bottom; + int i, j, ref, minX, minY, min, max; + xf86ScreenLayoutPtr pLayout; + Bool OldStyleConfig = FALSE; + + /* need to have this set up with a config file option */ + HardEdges = FALSE; + + bzero(xf86ScreenLayout, MAXSCREENS * sizeof(xf86ScreenLayoutRec)); + + screensLeft = prevScreensLeft = (1 << xf86NumScreens) - 1; + + while(1) { + for(mask = screensLeft, i = 0; mask; mask >>= 1, i++) { + if(!(mask & 1L)) continue; + + screen = &xf86ConfigLayout.screens[i]; + + switch(screen->where) { + case PosObsolete: + OldStyleConfig = TRUE; + pLayout = &xf86ScreenLayout[i]; + /* force edge lists */ + if(screen->left) { + ref = screen->left->screennum; + pLayout->left = AddEdge(pLayout->left, + 0, xf86Screens[i]->pScreen->height, + xf86Screens[ref]->pScreen->width, 0, ref); + } + if(screen->right) { + ref = screen->right->screennum; + pScreen = xf86Screens[i]->pScreen; + pLayout->right = AddEdge(pLayout->right, + 0, pScreen->height, -pScreen->width, 0, ref); + } + if(screen->top) { + ref = screen->top->screennum; + pLayout->up = AddEdge(pLayout->up, + 0, xf86Screens[i]->pScreen->width, + 0, xf86Screens[ref]->pScreen->height, ref); + } + if(screen->bottom) { + ref = screen->bottom->screennum; + pScreen = xf86Screens[i]->pScreen; + pLayout->down = AddEdge(pLayout->down, + 0, pScreen->width, 0, -pScreen->height, ref); + } + /* we could also try to place it based on those + relative locations if we wanted to */ + screen->x = screen->y = 0; + /* FALLTHROUGH */ + case PosAbsolute: + dixScreenOrigins[i].x = screen->x; + dixScreenOrigins[i].y = screen->y; + screensLeft &= ~(1 << i); + break; + case PosRelative: + ref = screen->refscreen->screennum; + if(screensLeft & (1 << ref)) break; + dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->x; + dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->y; + screensLeft &= ~(1 << i); + break; + case PosRightOf: + ref = screen->refscreen->screennum; + if(screensLeft & (1 << ref)) break; + pScreen = xf86Screens[ref]->pScreen; + dixScreenOrigins[i].x = + dixScreenOrigins[ref].x + pScreen->width; + dixScreenOrigins[i].y = dixScreenOrigins[ref].y; + screensLeft &= ~(1 << i); + break; + case PosLeftOf: + ref = screen->refscreen->screennum; + if(screensLeft & (1 << ref)) break; + pScreen = xf86Screens[i]->pScreen; + dixScreenOrigins[i].x = + dixScreenOrigins[ref].x - pScreen->width; + dixScreenOrigins[i].y = dixScreenOrigins[ref].y; + screensLeft &= ~(1 << i); + break; + case PosBelow: + ref = screen->refscreen->screennum; + if(screensLeft & (1 << ref)) break; + pScreen = xf86Screens[ref]->pScreen; + dixScreenOrigins[i].x = dixScreenOrigins[ref].x; + dixScreenOrigins[i].y = + dixScreenOrigins[ref].y + pScreen->height; + screensLeft &= ~(1 << i); + break; + case PosAbove: + ref = screen->refscreen->screennum; + if(screensLeft & (1 << ref)) break; + pScreen = xf86Screens[i]->pScreen; + dixScreenOrigins[i].x = dixScreenOrigins[ref].x; + dixScreenOrigins[i].y = + dixScreenOrigins[ref].y - pScreen->height; + screensLeft &= ~(1 << i); + break; + default: + ErrorF("Illegal placement keyword in Layout!\n"); + break; + } + + } + + if(!screensLeft) break; + + if(screensLeft == prevScreensLeft) { + /* All the remaining screens are referencing each other. + Assign a value to one of them and go through again */ + i = 0; + while(!((1 << i) & screensLeft)){ i++; } + + ref = xf86ConfigLayout.screens[i].refscreen->screennum; + dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0; + screensLeft &= ~(1 << ref); + } + + prevScreensLeft = screensLeft; + } + + /* justify the topmost and leftmost to (0,0) */ + minX = dixScreenOrigins[0].x; + minY = dixScreenOrigins[0].y; + + for(i = 1; i < xf86NumScreens; i++) { + if(dixScreenOrigins[i].x < minX) + minX = dixScreenOrigins[i].x; + if(dixScreenOrigins[i].y < minY) + minY = dixScreenOrigins[i].y; + } + + if (minX || minY) { + for(i = 0; i < xf86NumScreens; i++) { + dixScreenOrigins[i].x -= minX; + dixScreenOrigins[i].y -= minY; + } + } + + + /* Create the edge lists */ + + if(!OldStyleConfig) { + for(i = 0; i < xf86NumScreens; i++) { + pLayout = &xf86ScreenLayout[i]; + + pScreen = xf86Screens[i]->pScreen; + + left = dixScreenOrigins[i].x; + right = left + pScreen->width; + top = dixScreenOrigins[i].y; + bottom = top + pScreen->height; + + for(j = 0; j < xf86NumScreens; j++) { + if(i == j) continue; + + x1 = dixScreenOrigins[j].x; + x2 = x1 + xf86Screens[j]->pScreen->width; + y1 = dixScreenOrigins[j].y; + y2 = y1 + xf86Screens[j]->pScreen->height; + + if((bottom > y1) && (top < y2)) { + min = y1 - top; + if(min < 0) min = 0; + max = pScreen->height - (bottom - y2); + if(max > pScreen->height) max = pScreen->height; + + if(((left - 1) >= x1) && ((left - 1) < x2)) + pLayout->left = AddEdge(pLayout->left, min, max, + dixScreenOrigins[i].x - dixScreenOrigins[j].x, + dixScreenOrigins[i].y - dixScreenOrigins[j].y, j); + + if((right >= x1) && (right < x2)) + pLayout->right = AddEdge(pLayout->right, min, max, + dixScreenOrigins[i].x - dixScreenOrigins[j].x, + dixScreenOrigins[i].y - dixScreenOrigins[j].y, j); + } + + + if((left < x2) && (right > x1)) { + min = x1 - left; + if(min < 0) min = 0; + max = pScreen->width - (right - x2); + if(max > pScreen->width) max = pScreen->width; + + if(((top - 1) >= y1) && ((top - 1) < y2)) + pLayout->up = AddEdge(pLayout->up, min, max, + dixScreenOrigins[i].x - dixScreenOrigins[j].x, + dixScreenOrigins[i].y - dixScreenOrigins[j].y, j); + + if((bottom >= y1) && (bottom < y2)) + pLayout->down = AddEdge(pLayout->down, min, max, + dixScreenOrigins[i].x - dixScreenOrigins[j].x, + dixScreenOrigins[i].y - dixScreenOrigins[j].y, j); + } + } + } + } + + if(!HardEdges && !OldStyleConfig) { + for(i = 0; i < xf86NumScreens; i++) { + pLayout = &xf86ScreenLayout[i]; + pScreen = xf86Screens[i]->pScreen; + if(pLayout->left) + FillOutEdge(pLayout->left, pScreen->height); + if(pLayout->right) + FillOutEdge(pLayout->right, pScreen->height); + if(pLayout->up) + FillOutEdge(pLayout->up, pScreen->width); + if(pLayout->down) + FillOutEdge(pLayout->down, pScreen->width); + } + } } + +void +xf86ReconfigureLayout(void) +{ + int i; + + for (i = 0; i < MAXSCREENS; i++) { + xf86ScreenLayoutPtr sl = &xf86ScreenLayout[i]; + /* we don't have to zero these, xf86InitOrigins() takes care of that */ + if (sl->left) xfree(sl->left); + if (sl->right) xfree(sl->right); + if (sl->up) xfree(sl->up); + if (sl->down) xfree(sl->down); + } + + xf86InitOrigins(); +} + + |