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