main.c revision 4642e01f
1/***********************************************************
2
3Copyright 1987, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25
26Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28                        All Rights Reserved
29
30Permission to use, copy, modify, and distribute this software and its
31documentation for any purpose and without fee is hereby granted,
32provided that the above copyright notice appear in all copies and that
33both that copyright notice and this permission notice appear in
34supporting documentation, and that the name of Digital not be
35used in advertising or publicity pertaining to distribution of the
36software without specific, written prior permission.
37
38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44SOFTWARE.
45
46******************************************************************/
47
48/* The panoramix components contained the following notice */
49/*****************************************************************
50
51Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
52
53Permission is hereby granted, free of charge, to any person obtaining a copy
54of this software and associated documentation files (the "Software"), to deal
55in the Software without restriction, including without limitation the rights
56to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
57copies of the Software.
58
59The above copyright notice and this permission notice shall be included in
60all copies or substantial portions of the Software.
61
62THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
65DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
66BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
67WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
68IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
69
70Except as contained in this notice, the name of Digital Equipment Corporation
71shall not be used in advertising or otherwise to promote the sale, use or other
72dealings in this Software without prior written authorization from Digital
73Equipment Corporation.
74
75******************************************************************/
76
77#define NEED_EVENTS
78#ifdef HAVE_DIX_CONFIG_H
79#include <dix-config.h>
80#endif
81
82#include <X11/X.h>
83#include <X11/Xos.h>   /* for unistd.h  */
84#include <X11/Xproto.h>
85#include "scrnintstr.h"
86#include "misc.h"
87#include "os.h"
88#include "windowstr.h"
89#include "resource.h"
90#include "dixstruct.h"
91#include "gcstruct.h"
92#include "extension.h"
93#include "colormap.h"
94#include "colormapst.h"
95#include "cursorstr.h"
96#include "selection.h"
97#include <X11/fonts/font.h>
98#include "opaque.h"
99#include "servermd.h"
100#include "hotplug.h"
101#include "site.h"
102#include "dixfont.h"
103#include "extnsionst.h"
104#include "privates.h"
105#include "registry.h"
106#ifdef PANORAMIX
107#include "panoramiXsrv.h"
108#else
109#include "dixevents.h"		/* InitEvents() */
110#include "dispatch.h"		/* InitProcVectors() */
111#endif
112
113#ifdef DPMSExtension
114#define DPMS_SERVER
115#include <X11/extensions/dpms.h>
116#include "dpmsproc.h"
117#endif
118
119extern void Dispatch(void);
120
121xConnSetupPrefix connSetupPrefix;
122
123extern FontPtr defaultFont;
124
125extern void InitProcVectors(void);
126extern Bool CreateGCperDepthArray(void);
127
128#ifndef PANORAMIX
129static
130#endif
131Bool CreateConnectionBlock(void);
132
133_X_EXPORT PaddingInfo PixmapWidthPaddingInfo[33];
134
135int connBlockScreenStart;
136
137_X_EXPORT void
138NotImplemented(xEvent *from, xEvent *to)
139{
140    FatalError("Not implemented");
141}
142
143/*
144 * Dummy entry for ReplySwapVector[]
145 */
146
147void
148ReplyNotSwappd(
149	ClientPtr pClient ,
150	int size ,
151	void * pbuf
152	)
153{
154    FatalError("Not implemented");
155}
156
157/*
158 * This array encodes the answer to the question "what is the log base 2
159 * of the number of pixels that fit in a scanline pad unit?"
160 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
161 */
162static int answer[6][4] = {
163	/* pad   pad   pad     pad*/
164	/*  8     16    32    64 */
165
166	{   3,     4,    5 ,   6 },	/* 1 bit per pixel */
167	{   1,     2,    3 ,   4 },	/* 4 bits per pixel */
168	{   0,     1,    2 ,   3 },	/* 8 bits per pixel */
169	{   ~0,    0,    1 ,   2 },	/* 16 bits per pixel */
170	{   ~0,    ~0,   0 ,   1 },	/* 24 bits per pixel */
171	{   ~0,    ~0,   0 ,   1 }	/* 32 bits per pixel */
172};
173
174/*
175 * This array gives the answer to the question "what is the first index for
176 * the answer array above given the number of bits per pixel?"
177 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
178 */
179static int indexForBitsPerPixel[ 33 ] = {
180	~0, 0, ~0, ~0,	/* 1 bit per pixel */
181	1, ~0, ~0, ~0,	/* 4 bits per pixel */
182	2, ~0, ~0, ~0,	/* 8 bits per pixel */
183	~0,~0, ~0, ~0,
184	3, ~0, ~0, ~0,	/* 16 bits per pixel */
185	~0,~0, ~0, ~0,
186	4, ~0, ~0, ~0,	/* 24 bits per pixel */
187	~0,~0, ~0, ~0,
188	5		/* 32 bits per pixel */
189};
190
191/*
192 * This array gives the bytesperPixel value for cases where the number
193 * of bits per pixel is a multiple of 8 but not a power of 2.
194 */
195static int answerBytesPerPixel[ 33 ] = {
196	~0, 0, ~0, ~0,	/* 1 bit per pixel */
197	0, ~0, ~0, ~0,	/* 4 bits per pixel */
198	0, ~0, ~0, ~0,	/* 8 bits per pixel */
199	~0,~0, ~0, ~0,
200	0, ~0, ~0, ~0,	/* 16 bits per pixel */
201	~0,~0, ~0, ~0,
202	3, ~0, ~0, ~0,	/* 24 bits per pixel */
203	~0,~0, ~0, ~0,
204	0		/* 32 bits per pixel */
205};
206
207/*
208 * This array gives the answer to the question "what is the second index for
209 * the answer array above given the number of bits per scanline pad unit?"
210 * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
211 */
212static int indexForScanlinePad[ 65 ] = {
213	~0, ~0, ~0, ~0,
214	~0, ~0, ~0, ~0,
215	 0, ~0, ~0, ~0,	/* 8 bits per scanline pad unit */
216	~0, ~0, ~0, ~0,
217	 1, ~0, ~0, ~0,	/* 16 bits per scanline pad unit */
218	~0, ~0, ~0, ~0,
219	~0, ~0, ~0, ~0,
220	~0, ~0, ~0, ~0,
221	 2, ~0, ~0, ~0,	/* 32 bits per scanline pad unit */
222	~0, ~0, ~0, ~0,
223	~0, ~0, ~0, ~0,
224	~0, ~0, ~0, ~0,
225	~0, ~0, ~0, ~0,
226	~0, ~0, ~0, ~0,
227	~0, ~0, ~0, ~0,
228	~0, ~0, ~0, ~0,
229	 3		/* 64 bits per scanline pad unit */
230};
231
232#ifndef MIN
233#define MIN(a,b) (((a) < (b)) ? (a) : (b))
234#endif
235
236#ifdef XQUARTZ
237#include <pthread.h>
238
239BOOL serverInitComplete = FALSE;
240pthread_mutex_t serverInitCompleteMutex = PTHREAD_MUTEX_INITIALIZER;
241pthread_cond_t serverInitCompleteCond = PTHREAD_COND_INITIALIZER;
242
243int dix_main(int argc, char *argv[], char *envp[])
244#else
245int main(int argc, char *argv[], char *envp[])
246#endif
247{
248    int		i;
249    HWEventQueueType	alwaysCheckForInput[2];
250
251    display = "0";
252
253    InitRegions();
254
255    CheckUserParameters(argc, argv, envp);
256
257    CheckUserAuthorization();
258
259    InitConnectionLimits();
260
261    ProcessCommandLine(argc, argv);
262
263    alwaysCheckForInput[0] = 0;
264    alwaysCheckForInput[1] = 1;
265    while(1)
266    {
267	serverGeneration++;
268	ScreenSaverTime = defaultScreenSaverTime;
269	ScreenSaverInterval = defaultScreenSaverInterval;
270	ScreenSaverBlanking = defaultScreenSaverBlanking;
271	ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
272#ifdef DPMSExtension
273	DPMSStandbyTime = defaultDPMSStandbyTime;
274	DPMSSuspendTime = defaultDPMSSuspendTime;
275	DPMSOffTime = defaultDPMSOffTime;
276	DPMSEnabled = defaultDPMSEnabled;
277	DPMSPowerLevel = 0;
278#endif
279	InitBlockAndWakeupHandlers();
280	/* Perform any operating system dependent initializations you'd like */
281	OsInit();
282        config_init();
283	if(serverGeneration == 1)
284	{
285	    CreateWellKnownSockets();
286	    InitProcVectors();
287	    for (i=1; i<MAXCLIENTS; i++)
288		clients[i] = NullClient;
289	    serverClient = (ClientPtr)xalloc(sizeof(ClientRec));
290	    if (!serverClient)
291		FatalError("couldn't create server client");
292	    InitClient(serverClient, 0, (pointer)NULL);
293	}
294	else
295	    ResetWellKnownSockets ();
296	clients[0] = serverClient;
297	currentMaxClients = 1;
298
299	if (!InitClientResources(serverClient))      /* for root resources */
300	    FatalError("couldn't init server resources");
301
302	SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
303	screenInfo.arraySize = MAXSCREENS;
304	screenInfo.numScreens = 0;
305
306	InitAtoms();
307	InitEvents();
308	InitSelections();
309	InitGlyphCaching();
310	if (!dixResetPrivates())
311	    FatalError("couldn't init private data storage");
312	dixResetRegistry();
313	ResetFontPrivateIndex();
314	InitCallbackManager();
315	InitOutput(&screenInfo, argc, argv);
316
317	if (screenInfo.numScreens < 1)
318	    FatalError("no screens found");
319	InitExtensions(argc, argv);
320	for (i = 0; i < screenInfo.numScreens; i++)
321	{
322	    ScreenPtr pScreen = screenInfo.screens[i];
323	    if (!CreateScratchPixmapsForScreen(i))
324		FatalError("failed to create scratch pixmaps");
325	    if (pScreen->CreateScreenResources &&
326		!(*pScreen->CreateScreenResources)(pScreen))
327		FatalError("failed to create screen resources");
328	    if (!CreateGCperDepth(i))
329		FatalError("failed to create scratch GCs");
330	    if (!CreateDefaultStipple(i))
331		FatalError("failed to create default stipple");
332	    if (!CreateRootWindow(pScreen))
333		FatalError("failed to create root window");
334	}
335
336	InitFonts();
337	if (SetDefaultFontPath(defaultFontPath) != Success) {
338	    ErrorF("[dix] failed to set default font path '%s'", defaultFontPath);
339	}
340	if (!SetDefaultFont(defaultTextFont)) {
341	    FatalError("could not open default font '%s'", defaultTextFont);
342	}
343
344	if (!(rootCursor = CreateRootCursor(NULL, 0))) {
345	    FatalError("could not open default cursor font '%s'",
346		       defaultCursorFont);
347	}
348
349#ifdef DPMSExtension
350 	/* check all screens, looking for DPMS Capabilities */
351 	DPMSCapableFlag = DPMSSupported();
352	if (!DPMSCapableFlag)
353     	    DPMSEnabled = FALSE;
354#endif
355
356#ifdef PANORAMIX
357	/*
358	 * Consolidate window and colourmap information for each screen
359	 */
360	if (!noPanoramiXExtension)
361	    PanoramiXConsolidate();
362#endif
363
364	for (i = 0; i < screenInfo.numScreens; i++)
365	    InitRootWindow(WindowTable[i]);
366	DefineInitialRootWindow(WindowTable[0]);
367
368        InitCoreDevices();
369	InitInput(argc, argv);
370	InitAndStartDevices();
371
372	dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
373
374#ifdef PANORAMIX
375	if (!noPanoramiXExtension) {
376	    if (!PanoramiXCreateConnectionBlock()) {
377		FatalError("could not create connection block info");
378	    }
379	} else
380#endif
381	{
382	    if (!CreateConnectionBlock()) {
383	    	FatalError("could not create connection block info");
384	    }
385	}
386
387#ifdef XQUARTZ
388    /* Let the other threads know the server is done with its init */
389    pthread_mutex_lock(&serverInitCompleteMutex);
390    serverInitComplete = TRUE;
391    pthread_cond_broadcast(&serverInitCompleteCond);
392    pthread_mutex_unlock(&serverInitCompleteMutex);
393#endif
394
395	NotifyParentProcess();
396
397	Dispatch();
398
399        UndisplayDevices();
400
401	/* Now free up whatever must be freed */
402	if (screenIsSaved == SCREEN_SAVER_ON)
403	    dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
404	FreeScreenSaverTimer();
405	CloseDownExtensions();
406
407#ifdef PANORAMIX
408	{
409	    Bool remember_it = noPanoramiXExtension;
410	    noPanoramiXExtension = TRUE;
411	    FreeAllResources();
412	    noPanoramiXExtension = remember_it;
413	}
414#else
415	FreeAllResources();
416#endif
417
418        config_fini();
419
420        memset(WindowTable, 0, sizeof(WindowTable));
421	CloseDownDevices();
422	CloseDownEvents();
423
424	for (i = screenInfo.numScreens - 1; i >= 0; i--)
425	{
426	    FreeScratchPixmapsForScreen(i);
427	    FreeGCperDepth(i);
428	    FreeDefaultStipple(i);
429	    (* screenInfo.screens[i]->CloseScreen)(i, screenInfo.screens[i]);
430	    dixFreePrivates(screenInfo.screens[i]->devPrivates);
431	    xfree(screenInfo.screens[i]);
432	    screenInfo.numScreens = i;
433	}
434	FreeFonts();
435
436	FreeAuditTimer();
437
438	dixFreePrivates(serverClient->devPrivates);
439	serverClient->devPrivates = NULL;
440
441	if (dispatchException & DE_TERMINATE)
442	{
443	    CloseWellKnownConnections();
444	}
445
446	OsCleanup((dispatchException & DE_TERMINATE) != 0);
447
448	if (dispatchException & DE_TERMINATE)
449	{
450	    ddxGiveUp();
451	    break;
452	}
453
454	xfree(ConnectionInfo);
455	ConnectionInfo = NULL;
456    }
457    return(0);
458}
459
460static int  VendorRelease = VENDOR_RELEASE;
461static char *VendorString = VENDOR_NAME;
462
463void
464SetVendorRelease(int release)
465{
466    VendorRelease = release;
467}
468
469void
470SetVendorString(char *string)
471{
472    VendorString = string;
473}
474
475static const int padlength[4] = {0, 3, 2, 1};
476
477#ifndef PANORAMIX
478static
479#endif
480Bool
481CreateConnectionBlock(void)
482{
483    xConnSetup setup;
484    xWindowRoot root;
485    xDepth	depth;
486    xVisualType visual;
487    xPixmapFormat format;
488    unsigned long vid;
489    int i, j, k,
490        lenofblock,
491        sizesofar = 0;
492    char *pBuf;
493
494
495    /* Leave off the ridBase and ridMask, these must be sent with
496       connection */
497
498    setup.release = VendorRelease;
499    /*
500     * per-server image and bitmap parameters are defined in Xmd.h
501     */
502    setup.imageByteOrder = screenInfo.imageByteOrder;
503
504    setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
505    setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
506
507    setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
508    setup.motionBufferSize = NumMotionEvents();
509    setup.numRoots = screenInfo.numScreens;
510    setup.nbytesVendor = strlen(VendorString);
511    setup.numFormats = screenInfo.numPixmapFormats;
512    setup.maxRequestSize = MAX_REQUEST_SIZE;
513    QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
514
515    lenofblock = sizeof(xConnSetup) +
516            ((setup.nbytesVendor + 3) & ~3) +
517	    (setup.numFormats * sizeof(xPixmapFormat)) +
518            (setup.numRoots * sizeof(xWindowRoot));
519    ConnectionInfo = (char *) xalloc(lenofblock);
520    if (!ConnectionInfo)
521	return FALSE;
522
523    memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
524    sizesofar = sizeof(xConnSetup);
525    pBuf = ConnectionInfo + sizeof(xConnSetup);
526
527    memmove(pBuf, VendorString, (int)setup.nbytesVendor);
528    sizesofar += setup.nbytesVendor;
529    pBuf += setup.nbytesVendor;
530    i = padlength[setup.nbytesVendor & 3];
531    sizesofar += i;
532    while (--i >= 0)
533	*pBuf++ = 0;
534
535    for (i=0; i<screenInfo.numPixmapFormats; i++)
536    {
537	format.depth = screenInfo.formats[i].depth;
538	format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
539	format.scanLinePad = screenInfo.formats[i].scanlinePad;
540	memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
541	pBuf += sizeof(xPixmapFormat);
542	sizesofar += sizeof(xPixmapFormat);
543    }
544
545    connBlockScreenStart = sizesofar;
546    for (i=0; i<screenInfo.numScreens; i++)
547    {
548	ScreenPtr	pScreen;
549	DepthPtr	pDepth;
550	VisualPtr	pVisual;
551
552	pScreen = screenInfo.screens[i];
553	root.windowId = WindowTable[i]->drawable.id;
554	root.defaultColormap = pScreen->defColormap;
555	root.whitePixel = pScreen->whitePixel;
556	root.blackPixel = pScreen->blackPixel;
557	root.currentInputMask = 0;    /* filled in when sent */
558	root.pixWidth = pScreen->width;
559	root.pixHeight = pScreen->height;
560	root.mmWidth = pScreen->mmWidth;
561	root.mmHeight = pScreen->mmHeight;
562	root.minInstalledMaps = pScreen->minInstalledCmaps;
563	root.maxInstalledMaps = pScreen->maxInstalledCmaps;
564	root.rootVisualID = pScreen->rootVisual;
565	root.backingStore = pScreen->backingStoreSupport;
566	root.saveUnders = FALSE;
567	root.rootDepth = pScreen->rootDepth;
568	root.nDepths = pScreen->numDepths;
569	memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
570	sizesofar += sizeof(xWindowRoot);
571	pBuf += sizeof(xWindowRoot);
572
573	pDepth = pScreen->allowedDepths;
574	for(j = 0; j < pScreen->numDepths; j++, pDepth++)
575	{
576	    lenofblock += sizeof(xDepth) +
577		    (pDepth->numVids * sizeof(xVisualType));
578	    pBuf = (char *)xrealloc(ConnectionInfo, lenofblock);
579	    if (!pBuf)
580	    {
581		xfree(ConnectionInfo);
582		return FALSE;
583	    }
584	    ConnectionInfo = pBuf;
585	    pBuf += sizesofar;
586	    depth.depth = pDepth->depth;
587	    depth.nVisuals = pDepth->numVids;
588	    memmove(pBuf, (char *)&depth, sizeof(xDepth));
589	    pBuf += sizeof(xDepth);
590	    sizesofar += sizeof(xDepth);
591	    for(k = 0; k < pDepth->numVids; k++)
592	    {
593		vid = pDepth->vids[k];
594		for (pVisual = pScreen->visuals;
595		     pVisual->vid != vid;
596		     pVisual++)
597		    ;
598		visual.visualID = vid;
599		visual.class = pVisual->class;
600		visual.bitsPerRGB = pVisual->bitsPerRGBValue;
601		visual.colormapEntries = pVisual->ColormapEntries;
602		visual.redMask = pVisual->redMask;
603		visual.greenMask = pVisual->greenMask;
604		visual.blueMask = pVisual->blueMask;
605		memmove(pBuf, (char *)&visual, sizeof(xVisualType));
606		pBuf += sizeof(xVisualType);
607		sizesofar += sizeof(xVisualType);
608	    }
609	}
610    }
611    connSetupPrefix.success = xTrue;
612    connSetupPrefix.length = lenofblock/4;
613    connSetupPrefix.majorVersion = X_PROTOCOL;
614    connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
615    return TRUE;
616}
617
618/*
619	grow the array of screenRecs if necessary.
620	call the device-supplied initialization procedure
621with its screen number, a pointer to its ScreenRec, argc, and argv.
622	return the number of successfully installed screens.
623
624*/
625
626int
627AddScreen(
628    Bool	(* pfnInit)(
629	int /*index*/,
630	ScreenPtr /*pScreen*/,
631	int /*argc*/,
632	char ** /*argv*/
633		),
634    int argc,
635    char **argv)
636{
637
638    int i;
639    int scanlinepad, format, depth, bitsPerPixel, j, k;
640    ScreenPtr pScreen;
641
642    i = screenInfo.numScreens;
643    if (i == MAXSCREENS)
644	return -1;
645
646    pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec));
647    if (!pScreen)
648	return -1;
649
650    pScreen->devPrivates = NULL;
651    pScreen->myNum = i;
652    pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
653    pScreen->ClipNotify = 0;	/* for R4 ddx compatibility */
654    pScreen->CreateScreenResources = 0;
655
656    /*
657     * This loop gets run once for every Screen that gets added,
658     * but thats ok.  If the ddx layer initializes the formats
659     * one at a time calling AddScreen() after each, then each
660     * iteration will make it a little more accurate.  Worst case
661     * we do this loop N * numPixmapFormats where N is # of screens.
662     * Anyway, this must be called after InitOutput and before the
663     * screen init routine is called.
664     */
665    for (format=0; format<screenInfo.numPixmapFormats; format++)
666    {
667 	depth = screenInfo.formats[format].depth;
668 	bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
669  	scanlinepad = screenInfo.formats[format].scanlinePad;
670 	j = indexForBitsPerPixel[ bitsPerPixel ];
671  	k = indexForScanlinePad[ scanlinepad ];
672 	PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
673 	PixmapWidthPaddingInfo[ depth ].padRoundUp =
674 	    (scanlinepad/bitsPerPixel) - 1;
675 	j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
676 	PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
677	PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
678	if (answerBytesPerPixel[bitsPerPixel])
679	{
680	    PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
681	    PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
682		answerBytesPerPixel[bitsPerPixel];
683	}
684	else
685	{
686	    PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
687	}
688    }
689
690    /* This is where screen specific stuff gets initialized.  Load the
691       screen structure, call the hardware, whatever.
692       This is also where the default colormap should be allocated and
693       also pixel values for blackPixel, whitePixel, and the cursor
694       Note that InitScreen is NOT allowed to modify argc, argv, or
695       any of the strings pointed to by argv.  They may be passed to
696       multiple screens.
697    */
698    pScreen->rgf = ~0L;  /* there are no scratch GCs yet*/
699    WindowTable[i] = NullWindow;
700    screenInfo.screens[i] = pScreen;
701    screenInfo.numScreens++;
702    if (!(*pfnInit)(i, pScreen, argc, argv))
703    {
704	dixFreePrivates(pScreen->devPrivates);
705	xfree(pScreen);
706	screenInfo.numScreens--;
707	return -1;
708    }
709    return i;
710}
711