#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xos.h>
#include <X11/Xproto.h>
#include "scrnintstr.h"
#include "misc.h"
#include "os.h"
#include "windowstr.h"
#include "resource.h"
#include "dixstruct.h"
#include "gcstruct.h"
#include "extension.h"
#include "colormap.h"
#include "colormapst.h"
#include "cursorstr.h"
#include "selection.h"
#include <X11/fonts/font.h>
#include "opaque.h"
#include "servermd.h"
#include "hotplug.h"
#include "site.h"
#include "dixfont.h"
#include "extnsionst.h"
#include "privates.h"
#include "registry.h"
#ifdef PANORAMIX
#include "panoramiXsrv.h"
#else
#include "dixevents.h"
#include "dispatch.h"
#endif
#ifdef DPMSExtension
#include <X11/extensions/dpmsconst.h>
#include "dpmsproc.h"
#endif
extern void Dispatch(void);
xConnSetupPrefix connSetupPrefix;
extern FontPtr defaultFont;
extern void InitProcVectors(void);
extern Bool CreateGCperDepthArray(void);
#ifndef PANORAMIX
static
#endif
Bool CreateConnectionBlock(void);
_X_EXPORT PaddingInfo PixmapWidthPaddingInfo[33];
int connBlockScreenStart;
_X_EXPORT void
NotImplemented(xEvent *from, xEvent *to)
{
FatalError("Not implemented");
}
void
ReplyNotSwappd(
ClientPtr pClient ,
int size ,
void * pbuf
)
{
FatalError("Not implemented");
}
static int answer[6][4] = {
{ 3, 4, 5 , 6 },
{ 1, 2, 3 , 4 },
{ 0, 1, 2 , 3 },
{ ~0, 0, 1 , 2 },
{ ~0, ~0, 0 , 1 },
{ ~0, ~0, 0 , 1 }
};
static int indexForBitsPerPixel[ 33 ] = {
~0, 0, ~0, ~0,
1, ~0, ~0, ~0,
2, ~0, ~0, ~0,
~0,~0, ~0, ~0,
3, ~0, ~0, ~0,
~0,~0, ~0, ~0,
4, ~0, ~0, ~0,
~0,~0, ~0, ~0,
5
};
static int answerBytesPerPixel[ 33 ] = {
~0, 0, ~0, ~0,
0, ~0, ~0, ~0,
0, ~0, ~0, ~0,
~0,~0, ~0, ~0,
0, ~0, ~0, ~0,
~0,~0, ~0, ~0,
3, ~0, ~0, ~0,
~0,~0, ~0, ~0,
0
};
static int indexForScanlinePad[ 65 ] = {
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
1, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
2, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
~0, ~0, ~0, ~0,
3
};
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifdef XQUARTZ
#include <pthread.h>
BOOL serverInitComplete = FALSE;
pthread_mutex_t serverInitCompleteMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t serverInitCompleteCond = PTHREAD_COND_INITIALIZER;
int dix_main(int argc, char *argv[], char *envp[])
#else
int main(int argc, char *argv[], char *envp[])
#endif
{
int i;
HWEventQueueType alwaysCheckForInput[2];
display = "0";
InitRegions();
CheckUserParameters(argc, argv, envp);
CheckUserAuthorization();
InitConnectionLimits();
ProcessCommandLine(argc, argv);
alwaysCheckForInput[0] = 0;
alwaysCheckForInput[1] = 1;
while(1)
{
serverGeneration++;
ScreenSaverTime = defaultScreenSaverTime;
ScreenSaverInterval = defaultScreenSaverInterval;
ScreenSaverBlanking = defaultScreenSaverBlanking;
ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
#ifdef DPMSExtension
DPMSStandbyTime = defaultDPMSStandbyTime;
DPMSSuspendTime = defaultDPMSSuspendTime;
DPMSOffTime = defaultDPMSOffTime;
DPMSEnabled = defaultDPMSEnabled;
DPMSPowerLevel = 0;
#endif
InitBlockAndWakeupHandlers();
OsInit();
config_init();
if(serverGeneration == 1)
{
CreateWellKnownSockets();
InitProcVectors();
for (i=1; i<MAXCLIENTS; i++)
clients[i] = NullClient;
serverClient = (ClientPtr)xalloc(sizeof(ClientRec));
if (!serverClient)
FatalError("couldn't create server client");
InitClient(serverClient, 0, (pointer)NULL);
}
else
ResetWellKnownSockets ();
clients[0] = serverClient;
currentMaxClients = 1;
if (!InitClientResources(serverClient))
FatalError("couldn't init server resources");
SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
screenInfo.arraySize = MAXSCREENS;
screenInfo.numScreens = 0;
InitAtoms();
InitEvents();
InitSelections();
InitGlyphCaching();
if (!dixResetPrivates())
FatalError("couldn't init private data storage");
dixResetRegistry();
ResetFontPrivateIndex();
InitCallbackManager();
InitOutput(&screenInfo, argc, argv);
if (screenInfo.numScreens < 1)
FatalError("no screens found");
InitExtensions(argc, argv);
for (i = 0; i < screenInfo.numScreens; i++)
{
ScreenPtr pScreen = screenInfo.screens[i];
if (!CreateScratchPixmapsForScreen(i))
FatalError("failed to create scratch pixmaps");
if (pScreen->CreateScreenResources &&
!(*pScreen->CreateScreenResources)(pScreen))
FatalError("failed to create screen resources");
if (!CreateGCperDepth(i))
FatalError("failed to create scratch GCs");
if (!CreateDefaultStipple(i))
FatalError("failed to create default stipple");
if (!CreateRootWindow(pScreen))
FatalError("failed to create root window");
}
InitFonts();
if (SetDefaultFontPath(defaultFontPath) != Success) {
ErrorF("[dix] failed to set default font path '%s'", defaultFontPath);
}
if (!SetDefaultFont(defaultTextFont)) {
FatalError("could not open default font '%s'", defaultTextFont);
}
if (!(rootCursor = CreateRootCursor(NULL, 0))) {
FatalError("could not open default cursor font '%s'",
defaultCursorFont);
}
#ifdef DPMSExtension
DPMSCapableFlag = DPMSSupported();
if (!DPMSCapableFlag)
DPMSEnabled = FALSE;
#endif
#ifdef PANORAMIX
if (!noPanoramiXExtension)
PanoramiXConsolidate();
#endif
for (i = 0; i < screenInfo.numScreens; i++)
InitRootWindow(WindowTable[i]);
DefineInitialRootWindow(WindowTable[0]);
InitCoreDevices();
InitInput(argc, argv);
InitAndStartDevices();
dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
if (!PanoramiXCreateConnectionBlock()) {
FatalError("could not create connection block info");
}
} else
#endif
{
if (!CreateConnectionBlock()) {
FatalError("could not create connection block info");
}
}
#ifdef XQUARTZ
pthread_mutex_lock(&serverInitCompleteMutex);
serverInitComplete = TRUE;
pthread_cond_broadcast(&serverInitCompleteCond);
pthread_mutex_unlock(&serverInitCompleteMutex);
#endif
NotifyParentProcess();
Dispatch();
UndisplayDevices();
if (screenIsSaved == SCREEN_SAVER_ON)
dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
FreeScreenSaverTimer();
CloseDownExtensions();
#ifdef PANORAMIX
{
Bool remember_it = noPanoramiXExtension;
noPanoramiXExtension = TRUE;
FreeAllResources();
noPanoramiXExtension = remember_it;
}
#else
FreeAllResources();
#endif
config_fini();
memset(WindowTable, 0, sizeof(WindowTable));
CloseDownDevices();
CloseDownEvents();
for (i = screenInfo.numScreens - 1; i >= 0; i--)
{
FreeScratchPixmapsForScreen(i);
FreeGCperDepth(i);
FreeDefaultStipple(i);
(* screenInfo.screens[i]->CloseScreen)(i, screenInfo.screens[i]);
dixFreePrivates(screenInfo.screens[i]->devPrivates);
xfree(screenInfo.screens[i]);
screenInfo.numScreens = i;
}
FreeFonts();
FreeAuditTimer();
dixFreePrivates(serverClient->devPrivates);
serverClient->devPrivates = NULL;
if (dispatchException & DE_TERMINATE)
{
CloseWellKnownConnections();
}
OsCleanup((dispatchException & DE_TERMINATE) != 0);
if (dispatchException & DE_TERMINATE)
{
ddxGiveUp();
break;
}
xfree(ConnectionInfo);
ConnectionInfo = NULL;
}
return(0);
}
static int VendorRelease = VENDOR_RELEASE;
static char *VendorString = VENDOR_NAME;
void
SetVendorRelease(int release)
{
VendorRelease = release;
}
void
SetVendorString(char *string)
{
VendorString = string;
}
static const int padlength[4] = {0, 3, 2, 1};
#ifndef PANORAMIX
static
#endif
Bool
CreateConnectionBlock(void)
{
xConnSetup setup;
xWindowRoot root;
xDepth depth;
xVisualType visual;
xPixmapFormat format;
unsigned long vid;
int i, j, k,
lenofblock,
sizesofar = 0;
char *pBuf;
setup.release = VendorRelease;
setup.imageByteOrder = screenInfo.imageByteOrder;
setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
setup.motionBufferSize = NumMotionEvents();
setup.numRoots = screenInfo.numScreens;
setup.nbytesVendor = strlen(VendorString);
setup.numFormats = screenInfo.numPixmapFormats;
setup.maxRequestSize = MAX_REQUEST_SIZE;
QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
lenofblock = sizeof(xConnSetup) +
((setup.nbytesVendor + 3) & ~3) +
(setup.numFormats * sizeof(xPixmapFormat)) +
(setup.numRoots * sizeof(xWindowRoot));
ConnectionInfo = (char *) xalloc(lenofblock);
if (!ConnectionInfo)
return FALSE;
memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
sizesofar = sizeof(xConnSetup);
pBuf = ConnectionInfo + sizeof(xConnSetup);
memmove(pBuf, VendorString, (int)setup.nbytesVendor);
sizesofar += setup.nbytesVendor;
pBuf += setup.nbytesVendor;
i = padlength[setup.nbytesVendor & 3];
sizesofar += i;
while (--i >= 0)
*pBuf++ = 0;
for (i=0; i<screenInfo.numPixmapFormats; i++)
{
format.depth = screenInfo.formats[i].depth;
format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
format.scanLinePad = screenInfo.formats[i].scanlinePad;
memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
pBuf += sizeof(xPixmapFormat);
sizesofar += sizeof(xPixmapFormat);
}
connBlockScreenStart = sizesofar;
for (i=0; i<screenInfo.numScreens; i++)
{
ScreenPtr pScreen;
DepthPtr pDepth;
VisualPtr pVisual;
pScreen = screenInfo.screens[i];
root.windowId = WindowTable[i]->drawable.id;
root.defaultColormap = pScreen->defColormap;
root.whitePixel = pScreen->whitePixel;
root.blackPixel = pScreen->blackPixel;
root.currentInputMask = 0;
root.pixWidth = pScreen->width;
root.pixHeight = pScreen->height;
root.mmWidth = pScreen->mmWidth;
root.mmHeight = pScreen->mmHeight;
root.minInstalledMaps = pScreen->minInstalledCmaps;
root.maxInstalledMaps = pScreen->maxInstalledCmaps;
root.rootVisualID = pScreen->rootVisual;
root.backingStore = pScreen->backingStoreSupport;
root.saveUnders = FALSE;
root.rootDepth = pScreen->rootDepth;
root.nDepths = pScreen->numDepths;
memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
sizesofar += sizeof(xWindowRoot);
pBuf += sizeof(xWindowRoot);
pDepth = pScreen->allowedDepths;
for(j = 0; j < pScreen->numDepths; j++, pDepth++)
{
lenofblock += sizeof(xDepth) +
(pDepth->numVids * sizeof(xVisualType));
pBuf = (char *)xrealloc(ConnectionInfo, lenofblock);
if (!pBuf)
{
xfree(ConnectionInfo);
return FALSE;
}
ConnectionInfo = pBuf;
pBuf += sizesofar;
depth.depth = pDepth->depth;
depth.nVisuals = pDepth->numVids;
memmove(pBuf, (char *)&depth, sizeof(xDepth));
pBuf += sizeof(xDepth);
sizesofar += sizeof(xDepth);
for(k = 0; k < pDepth->numVids; k++)
{
vid = pDepth->vids[k];
for (pVisual = pScreen->visuals;
pVisual->vid != vid;
pVisual++)
;
visual.visualID = vid;
visual.class = pVisual->class;
visual.bitsPerRGB = pVisual->bitsPerRGBValue;
visual.colormapEntries = pVisual->ColormapEntries;
visual.redMask = pVisual->redMask;
visual.greenMask = pVisual->greenMask;
visual.blueMask = pVisual->blueMask;
memmove(pBuf, (char *)&visual, sizeof(xVisualType));
pBuf += sizeof(xVisualType);
sizesofar += sizeof(xVisualType);
}
}
}
connSetupPrefix.success = xTrue;
connSetupPrefix.length = lenofblock/4;
connSetupPrefix.majorVersion = X_PROTOCOL;
connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
return TRUE;
}
int
AddScreen(
Bool (* pfnInit)(
int ,
ScreenPtr ,
int ,
char **
),
int argc,
char **argv)
{
int i;
int scanlinepad, format, depth, bitsPerPixel, j, k;
ScreenPtr pScreen;
i = screenInfo.numScreens;
if (i == MAXSCREENS)
return -1;
pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec));
if (!pScreen)
return -1;
pScreen->devPrivates = NULL;
pScreen->myNum = i;
pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
pScreen->ClipNotify = 0;
pScreen->CreateScreenResources = 0;
for (format=0; format<screenInfo.numPixmapFormats; format++)
{
depth = screenInfo.formats[format].depth;
bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
scanlinepad = screenInfo.formats[format].scanlinePad;
j = indexForBitsPerPixel[ bitsPerPixel ];
k = indexForScanlinePad[ scanlinepad ];
PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
PixmapWidthPaddingInfo[ depth ].padRoundUp =
(scanlinepad/bitsPerPixel) - 1;
j = indexForBitsPerPixel[ 8 ];
PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
if (answerBytesPerPixel[bitsPerPixel])
{
PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
answerBytesPerPixel[bitsPerPixel];
}
else
{
PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
}
}
pScreen->rgf = ~0L;
WindowTable[i] = NullWindow;
screenInfo.screens[i] = pScreen;
screenInfo.numScreens++;
if (!(*pfnInit)(i, pScreen, argc, argv))
{
dixFreePrivates(pScreen->devPrivates);
xfree(pScreen);
screenInfo.numScreens--;
return -1;
}
return i;
}