diff options
author | jensowen <jensowen> | 2002-07-30 20:58:18 +0000 |
---|---|---|
committer | jensowen <jensowen> | 2002-07-30 20:58:18 +0000 |
commit | 324ff3efd22c82a38df1d4e8e77c6668bb7f014f (patch) | |
tree | 8209754f737b4590a194b00b85de070b2df0df3d | |
parent | 36344aa9a4487dbc576427dd275734bd465ad7b3 (diff) |
Option to override standard root weave to black.
-rw-r--r-- | xc/programs/Xserver/dix/globals.c | 13 | ||||
-rw-r--r-- | xc/programs/Xserver/dix/window.c | 230 | ||||
-rw-r--r-- | xc/programs/Xserver/include/opaque.h | 14 | ||||
-rw-r--r-- | xc/programs/Xserver/os/utils.c | 677 |
4 files changed, 657 insertions, 277 deletions
diff --git a/xc/programs/Xserver/dix/globals.c b/xc/programs/Xserver/dix/globals.c index 887662dee..1601922a6 100644 --- a/xc/programs/Xserver/dix/globals.c +++ b/xc/programs/Xserver/dix/globals.c @@ -1,9 +1,13 @@ -/* $XFree86: xc/programs/Xserver/dix/globals.c,v 1.6 1998/10/04 09:38:09 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/dix/globals.c,v 1.9 2001/12/14 19:59:32 dawes Exp $ */ /************************************************************ Copyright 1987, 1998 The Open Group -All Rights Reserved. +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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -42,7 +46,7 @@ SOFTWARE. ********************************************************/ -/* $TOG: globals.c /main/21 1998/02/09 14:19:40 kaleb $ */ +/* $Xorg: globals.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */ #include "X.h" #include "Xmd.h" @@ -122,6 +126,7 @@ FontPtr defaultFont; /* not declared in dix.h to avoid including font.h in every compilation of dix code */ Bool loadableFonts = FALSE; CursorPtr rootCursor; +Bool blackRoot=FALSE; ClientPtr requestingClient; /* XXX this should be obsolete now, remove? */ TimeStamp currentTime; @@ -139,3 +144,5 @@ char *display; CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; int argcGlobal; char **argvGlobal; + +DDXPointRec dixScreenOrigins[MAXSCREENS]; diff --git a/xc/programs/Xserver/dix/window.c b/xc/programs/Xserver/dix/window.c index 686b261ee..df059c241 100644 --- a/xc/programs/Xserver/dix/window.c +++ b/xc/programs/Xserver/dix/window.c @@ -1,9 +1,13 @@ -/* $TOG: window.c /main/215 1998/04/22 16:33:01 msr $ */ +/* $Xorg: window.c,v 1.4 2001/02/09 02:04:41 xorgcvs Exp $ */ /* Copyright 1987, 1998 The Open Group -All Rights Reserved. +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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -66,7 +70,7 @@ SOFTWARE. * * *****************************************************************/ -/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.13 1999/05/23 06:33:37 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/dix/window.c,v 3.24 2001/12/14 19:59:34 dawes Exp $ */ #include "misc.h" #include "scrnintstr.h" @@ -84,9 +88,8 @@ SOFTWARE. #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" -#else -#include "dixevents.h" #endif +#include "dixevents.h" #include "globals.h" #ifdef XAPPGROUP @@ -98,6 +101,7 @@ SOFTWARE. #endif extern Bool permitOldBugs; +extern Bool blackRoot; #if defined(NEED_SCREEN_REGIONS) #define REGION_PTR(pScreen,pWin) \ @@ -206,33 +210,6 @@ PrintWindowTree() } #endif -#ifdef PANORAMIX -Bool -PanoramiXWindowOffScreen(pWin,w, h) - register WindowPtr pWin; - unsigned short w, h; -{ - int Scr; - - Scr = (pWin->drawable.pScreen)->myNum; - - if ((pWin->drawable.x < 0) && - ((pWin->drawable.x + w) < 0)) - return TRUE; - if ((pWin->drawable.x > panoramiXdataPtr[Scr].width) && - ((pWin->drawable.x + w) > panoramiXdataPtr[Scr].width)) - return TRUE; - if ((pWin->drawable.y < 0) && - ((pWin->drawable.y + h) < 0)) - return TRUE; - if ((pWin->drawable.y > panoramiXdataPtr[Scr].height) && - ((pWin->drawable.y + h) > panoramiXdataPtr[Scr].height) ) - return TRUE; - - return FALSE; -} -#endif - int TraverseTree(pWin, func, data) register WindowPtr pWin; @@ -343,7 +320,7 @@ MakeRootTile(pWin) register unsigned char *from, *to; register int i, j; - pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, len, 4, + pWin->background.pixmap = (*pScreen->CreatePixmap)(pScreen, 4, 4, pScreen->rootDepth); pWin->backgroundState = BackgroundPixmap; @@ -369,6 +346,9 @@ MakeRootTile(pWin) for (j = len; j > 0; j--) *to++ = *from; + if (blackRoot) + bzero(back, sizeof(back)); + (*pGC->ops->PutImage)((DrawablePtr)pWin->background.pixmap, pGC, 1, 0, 0, len, 4, 0, XYBitmap, (char *)back); @@ -581,44 +561,6 @@ ClippedRegionFromBox(pWin, Rgn, x, y, w, h) REGION_INTERSECT(pScreen, Rgn, Rgn, &pWin->winSize); } -/* Set the region to the intersection of the rectangle and the - * PanoramiX window size. The window is typically the parent of the - * window from which the region came. - */ - -#ifdef PANORAMIX -void -PanoramiXClippedRegion(pWin, Rgn, x, y, w, h) - register WindowPtr pWin; - RegionPtr Rgn; - register int x, y; - int w, h; -{ - register ScreenPtr pScreen = pWin->drawable.pScreen; - BoxRec box; - - box = *(REGION_EXTENTS(pScreen, &PanoramiXScreenRegion[pScreen->myNum])); - - /* we do these calculations to avoid overflows */ - if (x > box.x1) - box.x1 = x; - if (y > box.y1) - box.y1 = y; - x += w; - if (x < box.x2) - box.x2 = x; - y += h; - if (y < box.y2) - box.y2 = y; - if (box.x1 > box.x2) - box.x2 = box.x1; - if (box.y1 > box.y2) - box.y2 = box.y1; - REGION_RESET(pScreen, Rgn, &box); - REGION_INTERSECT(pScreen, Rgn, Rgn, &PanoramiXScreenRegion[pScreen->myNum]); -} -#endif - WindowPtr RealChildHead(pWin) register WindowPtr pWin; @@ -880,7 +822,6 @@ CreateWindow(wid, pParent, x, y, w, h, bw, class, vmask, vlist, event.u.createNotify.override = pWin->overrideRedirect; DeliverEvents(pParent, &event, 1, NullWindow); } - return pWin; } @@ -1457,7 +1398,7 @@ ChangeWindowAttributes(pWin, vmask, vlist, client) if (pChild->optional->colormap == cmap) CheckWindowOptionalNeed (pChild); } - + xE.u.u.type = ColormapNotify; xE.u.colormap.window = pWin->drawable.id; xE.u.colormap.colormap = cmap; @@ -1640,6 +1581,8 @@ MoveWindowInStack(pWin, pNextSib) if (pWin->nextSib != pNextSib) { + WindowPtr pOldNextSib = pWin->nextSib; + if (!pNextSib) /* move to bottom */ { if (pParent->firstChild == pWin) @@ -1696,6 +1639,8 @@ MoveWindowInStack(pWin, pNextSib) pFirstChange = pFirstChange->nextSib; } } + if(pWin->drawable.pScreen->RestackWindow) + (*pWin->drawable.pScreen->RestackWindow)(pWin, pOldNextSib); } return( pFirstChange ); @@ -1879,6 +1824,7 @@ ResizeChildrenWinSize(pWin, dx, dy, dw, dh) SetWinSize (pSib); SetBorderSize (pSib); (*pScreen->PositionWindow)(pSib, pSib->drawable.x, pSib->drawable.y); + if ( (pChild = pSib->firstChild) ) { while (1) @@ -2316,7 +2262,7 @@ ConfigureWindow(pWin, mask, vlist, client) #define REBORDER_WIN 3 register WindowPtr pSib = NullWindow; register WindowPtr pParent = pWin->parent; - Window sibwid; + Window sibwid = 0; Mask index2, tmask; register XID *pVlist; short x, y, beforeX, beforeY; @@ -2449,6 +2395,12 @@ ConfigureWindow(pWin, mask, vlist, client) event.u.u.detail = Above; event.u.configureRequest.x = x; event.u.configureRequest.y = y; +#ifdef PANORAMIX + if(!noPanoramiXExtension && (!pParent || !pParent->parent)) { + event.u.configureRequest.x += panoramiXdataPtr[0].x; + event.u.configureRequest.y += panoramiXdataPtr[0].y; + } +#endif event.u.configureRequest.width = w; event.u.configureRequest.height = h; event.u.configureRequest.borderWidth = bw; @@ -2526,29 +2478,17 @@ ActuallyDoSomething: event.u.configureNotify.aboveSibling = None; event.u.configureNotify.x = x; event.u.configureNotify.y = y; +#ifdef PANORAMIX + if(!noPanoramiXExtension && (!pParent || !pParent->parent)) { + event.u.configureNotify.x += panoramiXdataPtr[0].x; + event.u.configureNotify.y += panoramiXdataPtr[0].y; + } +#endif event.u.configureNotify.width = w; event.u.configureNotify.height = h; event.u.configureNotify.borderWidth = bw; event.u.configureNotify.override = pWin->overrideRedirect; -#ifdef PANORAMIX - /* In the case where a window is split between one - or more screen, a ConfigureNotify event will be written - to the client describing the section of the window - which is changed per screen. This causes a failure - in the vsw test CH03/mvrszwdw because the test is - not properly written and expects 1 event and fails - when it reads more than 1 event when the window is - split. The server is in fact doing the expected and - correct behavior. -mad 10/11/96 - */ - if (!noPanoramiXExtension) { - if (!PanoramiXWindowOffScreen(pWin, w, h)) - DeliverEvents(pWin, &event, 1, NullWindow); - }else - DeliverEvents(pWin, &event, 1, NullWindow); -#else DeliverEvents(pWin, &event, 1, NullWindow); -#endif } if (mask & CWBorderWidth) { @@ -2577,7 +2517,6 @@ ActuallyDoSomething: if (action != RESTACK_WIN) CheckCursorConfinement(pWin); - return(Success); #undef RESTACK_WIN #undef MOVE_WIN @@ -2703,6 +2642,12 @@ ReparentWindow(pWin, pParent, x, y, client) event.u.reparent.parent = pParent->drawable.id; event.u.reparent.x = x; event.u.reparent.y = y; +#ifdef PANORAMIX + if(!noPanoramiXExtension && !pParent->parent) { + event.u.reparent.x += panoramiXdataPtr[0].x; + event.u.reparent.y += panoramiXdataPtr[0].y; + } +#endif event.u.reparent.override = pWin->overrideRedirect; DeliverEvents(pWin, &event, 1, pParent); @@ -3081,6 +3026,15 @@ UnrealizeTree(pWin, fromConfigure) { pChild->realized = FALSE; pChild->visibility = VisibilityNotViewable; +#ifdef PANORAMIX + if(!noPanoramiXExtension && !pChild->drawable.pScreen->myNum) { + PanoramiXRes *win; + win = (PanoramiXRes*)LookupIDByType(pChild->drawable.id, + XRT_WINDOW); + if(win) + win->u.win.visibility = VisibilityNotViewable; + } +#endif (* Unrealize)(pChild); DeleteWindowFromAnyEvents(pChild, FALSE); if (pChild->viewable) @@ -3188,7 +3142,7 @@ UnmapSubwindows(pWin) Bool wasViewable = (Bool)pWin->viewable; Bool anyMarked = FALSE; Mask parentNotify; - WindowPtr pLayerWin; + WindowPtr pLayerWin = NULL; ScreenPtr pScreen = pWin->drawable.pScreen; if (!pWin->firstChild) @@ -3349,15 +3303,65 @@ NotClippedByChildren(pWin) return(pReg); } - void SendVisibilityNotify(pWin) WindowPtr pWin; { xEvent event; + unsigned int visibility = pWin->visibility; + +#ifdef PANORAMIX + /* This is not quite correct yet, but it's close */ + if(!noPanoramiXExtension) { + PanoramiXRes *win; + WindowPtr pWin2; + int i, Scrnum; + + Scrnum = pWin->drawable.pScreen->myNum; + + win = PanoramiXFindIDByScrnum(XRT_WINDOW, pWin->drawable.id, Scrnum); + + if(!win || (win->u.win.visibility == visibility)) + return; + + switch(visibility) { + case VisibilityUnobscured: + for(i = 0; i < PanoramiXNumScreens; i++) { + if(i == Scrnum) continue; + + pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW); + + if(pWin2->visibility == VisibilityPartiallyObscured) + return; + + if(!i) pWin = pWin2; + } + break; + case VisibilityPartiallyObscured: + if(Scrnum) + pWin = (WindowPtr)LookupIDByType(win->info[0].id, RT_WINDOW); + break; + case VisibilityFullyObscured: + for(i = 0; i < PanoramiXNumScreens; i++) { + if(i == Scrnum) continue; + + pWin2 = (WindowPtr)LookupIDByType(win->info[i].id, RT_WINDOW); + + if(pWin2->visibility != VisibilityFullyObscured) + return; + + if(!i) pWin = pWin2; + } + break; + } + + win->u.win.visibility = visibility; + } +#endif + event.u.u.type = VisibilityNotify; event.u.visibility.window = pWin->drawable.id; - event.u.visibility.state = pWin->visibility; + event.u.visibility.state = visibility; DeliverEvents(pWin, &event, 1, NullWindow); } @@ -3447,6 +3451,15 @@ SaveScreens(on, mode) #endif screenIsSaved = SCREEN_SAVER_ON; } + /* + * Call the DDX saver in case it wants to do something + * at cycle time + */ + else if (savedScreenInfo[i].blanked == SCREEN_IS_BLANKED) + { + (* screenInfo.screens[i]->SaveScreen) (screenInfo.screens[i], + type); + } break; case SCREEN_SAVER_ON: if (ScreenSaverBlanking != DontPreferBlanking) @@ -3494,7 +3507,7 @@ TileScreenSaver(i, kind) CursorMetricRec cm; unsigned char *srcbits, *mskbits; CursorPtr cursor; - XID cursorID; + XID cursorID = 0; int attri; mask = 0; @@ -3724,9 +3737,28 @@ DisposeWindowOptional (pWin) * everything is peachy. Delete the optional record * and clean up */ - if (pWin->cursorIsNone == FALSE) + /* + * TOG changed this code to: + * + * if (pWin->cursorIsNone == FALSE) + * FreeCursor (pWin->optional->cursor, (Cursor)0); + * pWin->cursorIsNone = TRUE; + * + * This is blatently wrong; windows without optionals can have + * two different cursor values, either None or sharing their + * parents cursor. This difference is controlled by the + * cursorIsNone value; when TRUE, the window has no cursor, + * when false, it shares its cursor with its parent; TOG + * made it impossible for a window to have a cursor without + * an optional record. + */ + if (pWin->optional->cursor) + { FreeCursor (pWin->optional->cursor, (Cursor)0); - pWin->cursorIsNone = TRUE; + pWin->cursorIsNone = FALSE; + } + else + pWin->cursorIsNone = TRUE; xfree (pWin->optional); pWin->optional = NULL; } diff --git a/xc/programs/Xserver/include/opaque.h b/xc/programs/Xserver/include/opaque.h index 0743f6975..048963991 100644 --- a/xc/programs/Xserver/include/opaque.h +++ b/xc/programs/Xserver/include/opaque.h @@ -1,9 +1,13 @@ -/* $TOG: opaque.h /main/20 1998/02/09 14:29:12 kaleb $ */ +/* $Xorg: opaque.h,v 1.4 2001/02/09 02:05:15 xorgcvs Exp $ */ /* Copyright 1987, 1998 The Open Group -All Rights Reserved. +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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -22,7 +26,7 @@ other dealings in this Software without prior written authorization from The Open Group. */ -/* $XFree86: xc/programs/Xserver/include/opaque.h,v 1.7 1999/03/20 08:59:33 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/include/opaque.h,v 1.10 2001/12/14 19:59:55 dawes Exp $ */ #ifndef OPAQUE_H #define OPAQUE_H @@ -70,10 +74,8 @@ extern int limitNoFile; #endif extern Bool permitOldBugs; extern Bool defeatAccessControl; -#ifdef SERVER_LOCK -static Bool nolock = FALSE; -#endif extern char* protNoListen; +extern Bool blackRoot; diff --git a/xc/programs/Xserver/os/utils.c b/xc/programs/Xserver/os/utils.c index de6d851c7..14015a91c 100644 --- a/xc/programs/Xserver/os/utils.c +++ b/xc/programs/Xserver/os/utils.c @@ -1,9 +1,13 @@ -/* $TOG: utils.c /main/138 1998/04/22 16:32:51 msr $ */ +/* $Xorg: utils.c,v 1.5 2001/02/09 02:05:24 xorgcvs Exp $ */ /* Copyright 1987, 1998 The Open Group -All Rights Reserved. +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. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -45,9 +49,14 @@ OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/os/utils.c,v 3.52 1999/05/15 12:10:35 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/os/utils.c,v 3.81 2002/01/16 20:39:51 dawes Exp $ */ -#ifdef WIN32 +#ifdef __CYGWIN__ +#include <stdlib.h> +#include <signal.h> +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) #include <X11/Xwinsock.h> #endif #include "Xos.h" @@ -55,6 +64,8 @@ OR PERFORMANCE OF THIS SOFTWARE. #include "misc.h" #include "X.h" #include "input.h" +#include "dixfont.h" +#include "osdep.h" #ifdef X_POSIX_C_SOURCE #define _POSIX_C_SOURCE X_POSIX_C_SOURCE #include <signal.h> @@ -69,39 +80,20 @@ OR PERFORMANCE OF THIS SOFTWARE. #endif #endif #include <sys/wait.h> -#if !defined(SYSV) && !defined(AMOEBA) && !defined(_MINIX) && !defined(WIN32) && !defined(Lynx) && !defined(QNX) +#if !defined(SYSV) && !defined(WIN32) && !defined(Lynx) && !defined(QNX4) #include <sys/resource.h> #endif #include <time.h> #include <sys/stat.h> #include <ctype.h> /* for isspace */ -#if NeedVarargsPrototypes #include <stdarg.h> -#endif #if defined(DGUX) #include <sys/resource.h> #include <netdb.h> #endif -#ifdef AMOEBA -#include "osdep.h" -#include <amoeba.h> -#include <module/mutex.h> - -static mutex print_lock; -#endif - -#if defined(__STDC__) || defined(AMOEBA) -/* DHD: SVR4.0 has a prototype for abs() in stdlib.h */ -/* DHD: might be better to move this include higher up? */ -#ifdef abs -#undef abs -#endif -#ifndef NOSTDHDRS #include <stdlib.h> /* for malloc() */ -#endif -#endif #if defined(TCPCONN) || defined(STREAMSCONN) # ifndef WIN32 @@ -111,14 +103,28 @@ static mutex print_lock; #include "opaque.h" +#ifdef SMART_SCHEDULE +#include "dixstruct.h" +#endif + +#ifdef XKB +#include "XKBsrv.h" +#endif +#ifdef XCSECURITY +#define _SECURITY_SERVER +#include "security.h" +#endif + +#define X_INCLUDE_NETDB_H +#include <X11/Xos_r.h> + #include <errno.h> -extern int errno; Bool CoreDump; Bool noTestExtensions; -Bool noPanoramiXExtension = TRUE; #ifdef PANORAMIX +Bool noPanoramiXExtension = TRUE; Bool PanoramiXVisibilityNotifySent = FALSE; Bool PanoramiXMapped = FALSE; Bool PanoramiXWindowExposureSent = FALSE; @@ -147,10 +153,8 @@ extern int SelectWaitTime; #ifdef MEMBUG #define MEM_FAIL_SCALE 100000 long Memory_fail = 0; -#ifdef linux #include <stdlib.h> /* for random() */ #endif -#endif #ifdef sgi int userdefinedfontpath = 0; @@ -177,7 +181,7 @@ OsSignal(sig, handler) return oact.sa_handler; #endif } - + #ifdef SERVER_LOCK /* * Explicit support for a server lock file like the ones used for UUCP. @@ -201,10 +205,6 @@ OsSignal(sig, handler) #include <sys/param.h> #endif -#ifdef _MINIX -#include <limits.h> /* For PATH_MAX */ -#endif - #ifdef __EMX__ #define link rename #endif @@ -226,6 +226,7 @@ OsSignal(sig, handler) static Bool StillLocking = FALSE; static char LockFile[PATH_MAX]; +static Bool nolock = FALSE; /* * LockServer -- @@ -236,7 +237,6 @@ static char LockFile[PATH_MAX]; void LockServer() { -#ifndef AMOEBA char tmp[PATH_MAX], pid_str[12]; int lfd, i, haslock, l_pid, t; char *tmppath = NULL; @@ -291,7 +291,7 @@ LockServer() } if (lfd < 0) FatalError("Could not create lock file in %s\n", tmp); - (void) sprintf(pid_str, "%10d\n", getpid()); + (void) sprintf(pid_str, "%10ld\n", (long)getpid()); (void) write(lfd, pid_str, 11); #ifndef __EMX__ #ifndef USE_CHMOD @@ -365,7 +365,6 @@ LockServer() if (!haslock) FatalError("Could not create server lock file: %s\n", LockFile); StillLocking = FALSE; -#endif /* !AMOEBA */ } /* @@ -375,7 +374,6 @@ LockServer() void UnlockServer() { -#ifndef AMOEBA if (nolock) return; if (!StillLocking){ @@ -385,8 +383,6 @@ UnlockServer() #endif /* __EMX__ */ (void) unlink(LockFile); } -#endif - } #endif /* SERVER_LOCK */ @@ -397,6 +393,8 @@ SIGVAL AutoResetServer (sig) int sig; { + int olderrno = errno; + dispatchException |= DE_RESET; isItTimeToYield = TRUE; #ifdef GPROF @@ -406,9 +404,7 @@ AutoResetServer (sig) #if defined(SYSV) && defined(X_NOT_POSIX) OsSignal (SIGHUP, AutoResetServer); #endif -#ifdef AMOEBA - WakeUpMainThread(); -#endif + errno = olderrno; } /* Force connections to close and then exit on SIGTERM, SIGINT */ @@ -418,15 +414,15 @@ SIGVAL GiveUp(sig) int sig; { + int olderrno = errno; + dispatchException |= DE_TERMINATE; isItTimeToYield = TRUE; #if defined(SYSV) && defined(X_NOT_POSIX) if (sig) OsSignal(sig, SIG_IGN); #endif -#ifdef AMOEBA - WakeUpMainThread(); -#endif + errno = olderrno; } #if __GNUC__ @@ -439,9 +435,6 @@ AbortServer() OsCleanup(); AbortDDX(); fflush(stderr); -#ifdef AMOEBA - IOPCleanUp(); -#endif if (CoreDump) abort(); exit (1); @@ -451,27 +444,17 @@ void Error(str) char *str; { -#ifdef AMOEBA - mu_lock(&print_lock); -#endif perror(str); -#ifdef AMOEBA - mu_unlock(&print_lock); -#endif } #ifndef DDXTIME CARD32 GetTimeInMillis() { -#ifndef AMOEBA struct timeval tp; X_GETTIMEOFDAY(&tp); return(tp.tv_sec * 1000) + (tp.tv_usec / 1000); -#else - return sys_milli(); -#endif } #endif @@ -504,11 +487,7 @@ AdjustWaitForDelay (waitTime, newdelay) void UseMsg() { #if !defined(AIXrt) && !defined(AIX386) -#ifndef AMOEBA ErrorF("use: X [:<display>] [option]\n"); -#else - ErrorF("use: X [[<host>]:<display>] [option]\n"); -#endif ErrorF("-a # mouse acceleration (pixels)\n"); ErrorF("-ac disable access control restrictions\n"); #ifdef MEMBUG @@ -517,6 +496,7 @@ void UseMsg() ErrorF("-audit int set audit trail level\n"); ErrorF("-auth file select authorization file\n"); ErrorF("bc enable bug compatibility\n"); + ErrorF("-br create root window with black background\n"); ErrorF("+bs enable any backing store support\n"); ErrorF("-bs disable any backing store support\n"); ErrorF("-c turns off key-click\n"); @@ -567,9 +547,6 @@ void UseMsg() #endif ErrorF("-su disable any save under support\n"); ErrorF("-t # mouse threshold (pixels)\n"); -#ifdef AMOEBA - ErrorF("-tcp capability specify TCP/IP server capability\n"); -#endif ErrorF("-terminate terminate at server reset\n"); ErrorF("-to # connection time out\n"); ErrorF("-tst disable testing extensions\n"); @@ -623,10 +600,6 @@ char *argv[]; { int i, skip; -#ifdef AMOEBA - mu_init(&print_lock); -#endif - defaultKeyboardControl.autoRepeat = TRUE; #ifdef PART_NET @@ -651,27 +624,6 @@ char *argv[]; exit(1); } } -#ifdef AMOEBA - else if (strchr(argv[i], ':') != NULL) { - char *p; - - XServerHostName = argv[i]; - if ((p = strchr(argv[i], ':')) != NULL) { - *p++ = '\0'; - display = p; - if( ! VerifyDisplayName( display ) ) { - ErrorF("Bad display name: %s\n", display); - UseMsg(); - exit(1); - } - } - } else if (strcmp( argv[i], "-tcp") == 0) { - if (++i < argc) - XTcpServerName = argv[i]; - else - UseMsg(); - } -#endif /* AMOEBA */ else if ( strcmp( argv[i], "-a") == 0) { if(++i < argc) @@ -708,6 +660,8 @@ char *argv[]; } else if ( strcmp( argv[i], "bc") == 0) permitOldBugs = TRUE; + else if ( strcmp( argv[i], "-br") == 0) + blackRoot = TRUE; else if ( strcmp( argv[i], "+bs") == 0) enableBackingStore = TRUE; else if ( strcmp( argv[i], "-bs") == 0) @@ -840,7 +794,7 @@ char *argv[]; #ifdef SERVER_LOCK else if ( strcmp ( argv[i], "-nolock") == 0) { -#if !defined(WIN32) && !defined(__EMX__) +#if !defined(WIN32) && !defined(__EMX__) && !defined(__CYGWIN__) if (getuid() != 0) ErrorF("Warning: the -nolock option can only be used by root\n"); else @@ -984,6 +938,31 @@ char *argv[]; SyncOn++; } #endif +#ifdef SMART_SCHEDULE + else if ( strcmp( argv[i], "-dumbSched") == 0) + { + SmartScheduleDisable = TRUE; + } + else if ( strcmp( argv[i], "-schedInterval") == 0) + { + if (++i < argc) + { + SmartScheduleInterval = atoi(argv[i]); + SmartScheduleSlice = SmartScheduleInterval; + } + else + UseMsg(); + } + else if ( strcmp( argv[i], "-schedMax") == 0) + { + if (++i < argc) + { + SmartScheduleMaxSlice = atoi(argv[i]); + } + else + UseMsg(); + } +#endif else { ErrorF("Unrecognized option: %s\n", argv[i]); @@ -1092,7 +1071,7 @@ ExpandCommandLine(pargc, pargv) { int i; -#if !defined(WIN32) && !defined(__EMX__) +#if !defined(WIN32) && !defined(__EMX__) && !defined(__CYGWIN__) if (getuid() != geteuid()) return; #endif @@ -1129,9 +1108,12 @@ pointer client; char hname[1024], *hnameptr; struct hostent *host; int len; +#ifdef XTHREADS_NEEDS_BYNAMEPARAMS + _Xgethostbynameparams hparams; +#endif gethostname(hname, 1024); - host = gethostbyname(hname); + host = _XGethostbyname(hname, hparams); if (host == NULL) hnameptr = hname; else @@ -1174,9 +1156,6 @@ void * Xalloc (amount) unsigned long amount; { -#if !defined(__STDC__) && !defined(AMOEBA) - char *malloc(); -#endif register pointer ptr; if ((long)amount <= 0) { @@ -1206,9 +1185,6 @@ void * XNFalloc (amount) unsigned long amount; { -#if !defined(__STDC__) && !defined(AMOEBA) - char *malloc(); -#endif register pointer ptr; if ((long)amount <= 0) @@ -1268,11 +1244,6 @@ Xrealloc (ptr, amount) register pointer ptr; unsigned long amount; { -#if !defined(__STDC__) && !defined(AMOEBA) - char *malloc(); - char *realloc(); -#endif - #ifdef MEMBUG if (!Must_have_memory && Memory_fail && ((random() % MEM_FAIL_SCALE) < Memory_fail)) @@ -1374,13 +1345,9 @@ XNFstrdup(const char *s) void AuditPrefix(f) - char *f; + const char *f; { -#ifdef X_NOT_STDC_ENV - long tm; -#else time_t tm; -#endif char *autime, *s; if (*f != ' ') { @@ -1396,59 +1363,32 @@ AuditPrefix(f) } } -/*VARARGS1*/ void -AuditF( -#if NeedVarargsPrototypes - const char * f, ...) -#else - f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */ - char *f; - char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9; -#endif +AuditF(const char * f, ...) { -#if NeedVarargsPrototypes va_list args; -#endif AuditPrefix(f); -#if NeedVarargsPrototypes va_start(args, f); VErrorF(f, args); va_end(args); -#else - ErrorF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); -#endif } -/*VARARGS1*/ void -FatalError( -#if NeedVarargsPrototypes - const char *f, ...) -#else -f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */ - const char *f; - char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9; -#endif +FatalError(const char *f, ...) { -#if NeedVarargsPrototypes va_list args; -#endif - static beenhere = 0; + static Bool beenhere = FALSE; if (beenhere) ErrorF("\nFatalError re-entered, aborting\n"); else ErrorF("\nFatal server error:\n"); -#if NeedVarargsPrototypes + va_start(args, f); VErrorF(f, args); va_end(args); -#else - ErrorF(f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); -#endif ErrorF("\n"); #ifdef DDXOSFATALERROR if (!beenhere) @@ -1457,14 +1397,14 @@ f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */ #ifdef ABORTONFATALERROR abort(); #endif - if (!beenhere) + if (!beenhere) { + beenhere = TRUE; AbortServer(); - else + } else abort(); /*NOTREACHED*/ } -#if NeedVarargsPrototypes void VErrorF(f, args) const char *f; @@ -1496,37 +1436,160 @@ VFatalError(const char *msg, va_list args) AbortServer(); /*NOTREACHED*/ } -#endif /* NeedVarargsPrototypes */ -/*VARARGS1*/ void -ErrorF( -#if NeedVarargsPrototypes - const char * f, ...) -#else - f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9) /* limit of ten args */ - char *f; - char *s0, *s1, *s2, *s3, *s4, *s5, *s6, *s7, *s8, *s9; -#endif +ErrorF(const char * f, ...) { -#if NeedVarargsPrototypes va_list args; va_start(args, f); VErrorF(f, args); va_end(args); +} + +#ifdef SMART_SCHEDULE + +unsigned long SmartScheduleIdleCount; +Bool SmartScheduleIdle; +Bool SmartScheduleTimerStopped; + +#ifdef SIGVTALRM +#define SMART_SCHEDULE_POSSIBLE +#endif + +#ifdef SMART_SCHEDULE_POSSIBLE +#define SMART_SCHEDULE_SIGNAL SIGALRM +#define SMART_SCHEDULE_TIMER ITIMER_REAL +#endif + +void +SmartScheduleStopTimer (void) +{ +#ifdef SMART_SCHEDULE_POSSIBLE + struct itimerval timer; + + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 0; + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = 0; + (void) setitimer (ITIMER_REAL, &timer, 0); + SmartScheduleTimerStopped = TRUE; +#endif +} + +Bool +SmartScheduleStartTimer (void) +{ +#ifdef SMART_SCHEDULE_POSSIBLE + struct itimerval timer; + + SmartScheduleTimerStopped = FALSE; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = SmartScheduleInterval * 1000; + timer.it_value.tv_sec = 0; + timer.it_value.tv_usec = SmartScheduleInterval * 1000; + return setitimer (ITIMER_REAL, &timer, 0) >= 0; +#endif + return FALSE; +} + +#ifdef SMART_SCHEDULE_POSSIBLE +void +SmartScheduleTimer (int sig) +{ + int olderrno = errno; + + SmartScheduleTime += SmartScheduleInterval; + if (SmartScheduleIdle) + { + SmartScheduleStopTimer (); + } + errno = olderrno; +} +#endif + +Bool +SmartScheduleInit (void) +{ +#ifdef SMART_SCHEDULE_POSSIBLE + struct sigaction act; + + if (SmartScheduleDisable) + return TRUE; + + bzero ((char *) &act, sizeof(struct sigaction)); + + /* Set up the timer signal function */ + act.sa_handler = SmartScheduleTimer; + sigemptyset (&act.sa_mask); + sigaddset (&act.sa_mask, SMART_SCHEDULE_SIGNAL); + if (sigaction (SMART_SCHEDULE_SIGNAL, &act, 0) < 0) + { + perror ("sigaction for smart scheduler"); + return FALSE; + } + /* Set up the virtual timer */ + if (!SmartScheduleStartTimer ()) + { + perror ("scheduling timer"); + return FALSE; + } + /* stop the timer and wait for WaitForSomething to start it */ + SmartScheduleStopTimer (); + return TRUE; #else -#ifdef AIXV3 - if (SyncOn) - sync(); -#else /* not AIXV3 */ -#ifdef AMOEBA - mu_lock(&print_lock); + return FALSE; #endif - fprintf( stderr, f, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9); -#ifdef AMOEBA - mu_unlock(&print_lock); +} #endif -#endif /* AIXV3 */ + +#ifdef SIG_BLOCK +static sigset_t PreviousSignalMask; +static int BlockedSignalCount; +#endif + +void +OsBlockSignals (void) +{ +#ifdef SIG_BLOCK + if (BlockedSignalCount++ == 0) + { + sigset_t set; + + sigemptyset (&set); +#ifdef SIGALRM + sigaddset (&set, SIGALRM); +#endif +#ifdef SIGVTALRM + sigaddset (&set, SIGVTALRM); +#endif +#ifdef SIGWINCH + sigaddset (&set, SIGWINCH); +#endif +#ifdef SIGIO + sigaddset (&set, SIGIO); +#endif +#ifdef SIGTSTP + sigaddset (&set, SIGTSTP); +#endif +#ifdef SIGTTIN + sigaddset (&set, SIGTTIN); +#endif +#ifdef SIGTTOU + sigaddset (&set, SIGTTOU); +#endif + sigprocmask (SIG_BLOCK, &set, &PreviousSignalMask); + } +#endif +} + +void +OsReleaseSignals (void) +{ +#ifdef SIG_BLOCK + if (--BlockedSignalCount == 0) + { + sigprocmask (SIG_SETMASK, &PreviousSignalMask, 0); + } #endif } @@ -1536,6 +1599,9 @@ ErrorF( * all privs before running a command. * * This is based on the code in FreeBSD 2.2 libc. + * + * XXX It'd be good to redirect stderr so that it ends up in the log file + * as well. As it is now, xkbcomp messages don't end up in the log file. */ int @@ -1543,7 +1609,9 @@ System(command) char *command; { int pid, p; - void (*csig)(); +#ifdef SIGCHLD + void (*csig)(int); +#endif int status; if (!command) @@ -1553,7 +1621,9 @@ System(command) csig = signal(SIGCHLD, SIG_DFL); #endif +#ifdef DEBUG ErrorF("System: `%s'\n", command); +#endif switch (pid = fork()) { case -1: /* error */ @@ -1591,7 +1661,6 @@ Popen(command, type) struct pid *cur; FILE *iop; int pdes[2], pid; - void (*csig)(); if (command == NULL || type == NULL) return NULL; @@ -1635,6 +1704,9 @@ Popen(command, type) _exit(127); } + /* Avoid EINTR during stdio calls */ + OsBlockSignals (); + /* parent */ if (*type == 'r') { iop = fdopen(pdes[0], type); @@ -1649,7 +1721,7 @@ Popen(command, type) cur->next = pidlist; pidlist = cur; -#if 0 +#ifdef DEBUG ErrorF("Popen: `%s', fp = %p\n", command, iop); #endif @@ -1661,11 +1733,10 @@ Pclose(iop) pointer iop; { struct pid *cur, *last; - int omask; int pstat; int pid; -#if 0 +#ifdef DEBUG ErrorF("Pclose: fp = %p\n", iop); #endif @@ -1687,6 +1758,274 @@ Pclose(iop) last->next = cur->next; xfree(cur); + /* allow EINTR again */ + OsReleaseSignals (); + return pid == -1 ? -1 : pstat; } #endif /* !WIN32 && !__EMX__ */ + + +/* + * CheckUserParameters: check for long command line arguments and long + * environment variables. By default, these checks are only done when + * the server's euid != ruid. In 3.3.x, these checks were done in an + * external wrapper utility. + */ + +/* Consider LD* variables insecure? */ +#ifndef REMOVE_ENV_LD +#define REMOVE_ENV_LD 1 +#endif + +/* Remove long environment variables? */ +#ifndef REMOVE_LONG_ENV +#define REMOVE_LONG_ENV 1 +#endif + +/* + * Disallow stdout or stderr as pipes? It's possible to block the X server + * when piping stdout+stderr to a pipe. + * + * Don't enable this because it looks like it's going to cause problems. + */ +#ifndef NO_OUTPUT_PIPES +#define NO_OUTPUT_PIPES 0 +#endif + + +/* Check args and env only if running setuid (euid == 0 && euid != uid) ? */ +#ifndef CHECK_EUID +#define CHECK_EUID 1 +#endif + +/* + * Maybe the locale can be faked to make isprint(3) report that everything + * is printable? Avoid it by default. + */ +#ifndef USE_ISPRINT +#define USE_ISPRINT 0 +#endif + +#define MAX_ARG_LENGTH 128 +#define MAX_ENV_LENGTH 256 +#define MAX_ENV_PATH_LENGTH 2048 /* Limit for *PATH and TERMCAP */ + +#if USE_ISPRINT +#include <ctype.h> +#define checkPrintable(c) isprint(c) +#else +#define checkPrintable(c) (((c) & 0x7f) >= 0x20 && ((c) & 0x7f) != 0x7f) +#endif + +enum BadCode { + NotBad = 0, + UnsafeArg, + ArgTooLong, + UnprintableArg, + EnvTooLong, + OutputIsPipe, + InternalError +}; + +#define ARGMSG \ + "\nIf the arguments used are valid, and have been rejected incorrectly\n" \ + "please send details of the arguments and why they are valid to\n" \ + "XFree86@XFree86.org. In the meantime, you can start the Xserver as\n" \ + "the \"super user\" (root).\n" + +#define ENVMSG \ + "\nIf the environment is valid, and have been rejected incorrectly\n" \ + "please send details of the environment and why it is valid to\n" \ + "XFree86@XFree86.org. In the meantime, you can start the Xserver as\n" \ + "the \"super user\" (root).\n" + +void +CheckUserParameters(int argc, char **argv, char **envp) +{ + enum BadCode bad = NotBad; + int i = 0, j; + char *a, *e = NULL; +#if defined(__QNX__) && !defined(__QNXNTO__) + char cmd_name[64]; +#endif + +#if CHECK_EUID + if (geteuid() == 0 && getuid() != geteuid()) +#endif + { + /* Check each argv[] */ + for (i = 1; i < argc; i++) { + if (strlen(argv[i]) > MAX_ARG_LENGTH) { + bad = ArgTooLong; + break; + } + a = argv[i]; + while (*a) { + if (checkPrintable(*a) == 0) { + bad = UnprintableArg; + break; + } + a++; + } + if (bad) + break; + } + if (!bad) { + /* Check each envp[] */ + for (i = 0; envp[i]; i++) { + + /* Check for bad environment variables and values */ +#if REMOVE_ENV_LD + while (envp[i] && (strncmp(envp[i], "LD", 2) == 0)) { +#ifdef ENVDEBUG + ErrorF("CheckUserParameters: removing %s from the " + "environment\n", strtok(envp[i], "=")); +#endif + for (j = i; envp[j]; j++) { + envp[j] = envp[j+1]; + } + } +#endif + if (envp[i] && (strlen(envp[i]) > MAX_ENV_LENGTH)) { +#if REMOVE_LONG_ENV +#ifdef ENVDEBUG + ErrorF("CheckUserParameters: removing %s from the " + "environment\n", strtok(envp[i], "=")); +#endif + for (j = i; envp[j]; j++) { + envp[j] = envp[j+1]; + } + i--; +#else + char *eq; + int len; + + eq = strchr(envp[i], '='); + if (!eq) + continue; + len = eq - envp[i]; + e = malloc(len + 1); + if (!e) { + bad = InternalError; + break; + } + strncpy(e, envp[i], len); + e[len] = 0; + if (len >= 4 && + (strcmp(e + len - 4, "PATH") == 0 || + strcmp(e, "TERMCAP") == 0)) { + if (strlen(envp[i]) > MAX_ENV_PATH_LENGTH) { + bad = EnvTooLong; + break; + } else { + free(e); + } + } else { + bad = EnvTooLong; + break; + } +#endif + } + } + } +#if NO_OUTPUT_PIPES + if (!bad) { + struct stat buf; + + if (fstat(fileno(stdout), &buf) == 0 && S_ISFIFO(buf.st_mode)) + bad = OutputIsPipe; + if (fstat(fileno(stderr), &buf) == 0 && S_ISFIFO(buf.st_mode)) + bad = OutputIsPipe; + } +#endif + } + switch (bad) { + case NotBad: + return; + case UnsafeArg: + ErrorF("Command line argument number %d is unsafe\n", i); + ErrorF(ARGMSG); + break; + case ArgTooLong: + ErrorF("Command line argument number %d is too long\n", i); + ErrorF(ARGMSG); + break; + case UnprintableArg: + ErrorF("Command line argument number %d contains unprintable" + " characters\n", i); + ErrorF(ARGMSG); + break; + case EnvTooLong: + ErrorF("Environment variable `%s' is too long\n", e); + ErrorF(ENVMSG); + break; + case OutputIsPipe: + ErrorF("Stdout and/or stderr is a pipe\n"); + break; + case InternalError: + ErrorF("Internal Error\n"); + break; + default: + ErrorF("Unknown error\n"); + ErrorF(ARGMSG); + ErrorF(ENVMSG); + break; + } + FatalError("X server aborted because of unsafe environment\n"); +} + +/* + * CheckUserAuthorization: check if the user is allowed to start the + * X server. This usually means some sort of PAM checking, and it is + * usually only done for setuid servers (uid != euid). + */ + +#ifdef USE_PAM +#include <security/pam_appl.h> +#include <security/pam_misc.h> +#include <pwd.h> +#endif /* USE_PAM */ + +void +CheckUserAuthorization() +{ +#ifdef USE_PAM + static struct pam_conv conv = { + misc_conv, + NULL + }; + + pam_handle_t *pamh = NULL; + struct passwd *pw; + int retval; + + if (getuid() != geteuid()) { + pw = getpwuid(getuid()); + if (pw == NULL) + FatalError("getpwuid() failed for uid %d\n", getuid()); + + retval = pam_start("xserver", pw->pw_name, &conv, &pamh); + if (retval != PAM_SUCCESS) + FatalError("pam_start() failed.\n" + "\tMissing or mangled PAM config file or module?\n"); + + retval = pam_authenticate(pamh, 0); + if (retval != PAM_SUCCESS) { + pam_end(pamh, retval); + FatalError("PAM authentication failed, cannot start X server.\n" + "\tPerhaps you do not have console ownership?\n"); + } + + retval = pam_acct_mgmt(pamh, 0); + if (retval != PAM_SUCCESS) { + pam_end(pamh, retval); + FatalError("PAM authentication failed, cannot start X server.\n" + "\tPerhaps you do not have console ownership?\n"); + } + + /* this is not a session, so do not do session management */ + pam_end(pamh, PAM_SUCCESS); + } +#endif +} |