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