1 /***********************************************************
3 Copyright (c) 1987 X Consortium
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:
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
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.
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.
27 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
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.
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
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 $ */
54 #include "scrnintstr.h"
57 #include "windowstr.h"
59 #include "dixstruct.h"
61 #include "extension.h"
62 #include "extnsionst.h"
64 #include "colormapst.h"
65 #include "cursorstr.h"
71 #include "dixevents.h" /* InitEvents() */
72 #include "dispatch.h" /* InitProcVectors() */
74 extern CARD32 defaultScreenSaverTime;
75 extern CARD32 defaultScreenSaverInterval;
76 extern int defaultScreenSaverBlanking;
77 extern int defaultScreenSaverAllowExposures;
85 extern int InitClientPrivates(
86 #if NeedFunctionPrototypes
92 #if NeedFunctionPrototypes
99 xConnSetupPrefix connSetupPrefix;
101 extern WindowPtr *WindowTable;
102 extern FontPtr defaultFont;
103 extern int screenPrivateCount;
105 static Bool CreateConnectionBlock(
106 #if NeedFunctionPrototypes
111 static void FreeScreen(
112 #if NeedFunctionPrototypes
113 ScreenPtr /*pScreen*/
117 PaddingInfo PixmapWidthPaddingInfo[33];
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).
124 PaddingInfo PixmapWidthPaddingInfoProto[33];
127 int connBlockScreenStart;
129 static int restart = 0;
132 * Dummy entry for EventSwapVector[]
137 #if NeedFunctionPrototypes && defined(EVENT_SWAP_PTR)
143 FatalError("Not implemented");
147 * Dummy entry for ReplySwapVector[]
152 #if NeedNestedPrototypes
159 FatalError("Not implemented");
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).
167 static int answer[6][4] = {
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 */
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).
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 */
189 3, ~0, ~0, ~0, /* 16 bits per pixel */
191 4, ~0, ~0, ~0, /* 24 bits per pixel */
193 5 /* 32 bits per pixel */
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.
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 */
205 0, ~0, ~0, ~0, /* 16 bits per pixel */
207 3, ~0, ~0, ~0, /* 24 bits per pixel */
209 0 /* 32 bits per pixel */
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).
217 static int indexForScanlinePad[ 65 ] = {
220 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
222 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
226 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
234 3 /* 64 bits per scanline pad unit */
244 HWEventQueueType alwaysCheckForInput[2];
246 /* Notice if we're restart. Probably this is because we jumped through
247 * uninitialized pointer */
249 FatalError("server restarted. Jumped through uninitialized pointer?\n");
254 ExpandCommandLine(&argc, &argv);
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 */
263 ProcessCommandLine(argc, argv);
265 alwaysCheckForInput[0] = 0;
266 alwaysCheckForInput[1] = 1;
270 ScreenSaverTime = defaultScreenSaverTime;
271 ScreenSaverInterval = defaultScreenSaverInterval;
272 ScreenSaverBlanking = defaultScreenSaverBlanking;
273 ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
275 DPMSStandbyTime = defaultDPMSStandbyTime;
276 DPMSSuspendTime = defaultDPMSSuspendTime;
277 DPMSOffTime = defaultDPMSOffTime;
278 DPMSEnabled = defaultDPMSEnabled;
281 InitBlockAndWakeupHandlers();
282 /* Perform any operating system dependent initializations you'd like */
284 if(serverGeneration == 1)
286 CreateWellKnownSockets();
288 clients = (ClientPtr *)xalloc(MAXCLIENTS * sizeof(ClientPtr));
290 FatalError("couldn't create client array");
291 for (i=1; i<MAXCLIENTS; i++)
292 clients[i] = NullClient;
293 serverClient = (ClientPtr)xalloc(sizeof(ClientRec));
295 FatalError("couldn't create server client");
296 InitClient(serverClient, 0, (pointer)NULL);
299 ResetWellKnownSockets ();
300 clients[0] = serverClient;
301 currentMaxClients = 1;
303 if (!InitClientResources(serverClient)) /* for root resources */
304 FatalError("couldn't init server resources");
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));
312 FatalError("couldn't create root window table");
315 * Just in case the ddx doesnt supply a format for depth 1 (like qvss).
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];
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.
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 */
339 ResetClientPrivates();
340 ResetScreenPrivates();
341 ResetWindowPrivates();
344 ResetPixmapPrivates();
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;
355 PrinterInitOutput(&screenInfo, argc, argv);
357 InitExtensions(argc, argv);
358 if (!InitClientPrivates(serverClient))
359 FatalError("failed to allocate serverClient devprivates");
360 for (i = 0; i < screenInfo.numScreens; i++)
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");
375 InitInput(argc, argv);
376 if (InitAndStartDevices() != Success)
377 FatalError("failed to initialize core devices");
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'",
388 /* check all screens, looking for DPMS Capabilities */
389 DPMSCapableFlag = DPMSSupported();
390 if (!DPMSCapableFlag)
393 for (i = 0; i < screenInfo.numScreens; i++)
394 InitRootWindow(WindowTable[i]);
395 DefineInitialRootWindow(WindowTable[0]);
397 if (!CreateConnectionBlock())
398 FatalError("could not create connection block info");
402 /* Now free up whatever must be freed */
403 if (screenIsSaved == SCREEN_SAVER_ON)
404 SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
405 CloseDownExtensions();
408 for (i = screenInfo.numScreens - 1; i >= 0; i--)
410 FreeScratchPixmapsForScreen(i);
412 FreeDefaultStipple(i);
413 (* screenInfo.screens[i]->CloseScreen)(i, screenInfo.screens[i]);
414 FreeScreen(screenInfo.screens[i]);
415 screenInfo.numScreens = i;
419 xfree(serverClient->devPrivates);
421 if (dispatchException & DE_TERMINATE)
428 xfree(ConnectionInfo);
433 static int padlength[4] = {0, 3, 2, 1};
436 CreateConnectionBlock()
442 xPixmapFormat format;
450 /* Leave off the ridBase and ridMask, these must be sent with
453 setup.release = VENDOR_RELEASE;
455 * per-server image and bitmap parameters are defined in Xmd.h
457 setup.imageByteOrder = screenInfo.imageByteOrder;
459 #ifdef INTERNAL_VS_EXTERNAL_PADDING
460 if ( screenInfo.bitmapScanlineUnit > 32 )
461 setup.bitmapScanlineUnit = 32;
464 setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
465 #ifdef INTERNAL_VS_EXTERNAL_PADDING
466 if ( screenInfo.bitmapScanlinePad > 32 )
467 setup.bitmapScanlinePad = 32;
470 setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
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);
480 lenofblock = sizeof(xConnSetup) +
481 ((setup.nbytesVendor + 3) & ~3) +
482 (setup.numFormats * sizeof(xPixmapFormat)) +
483 (setup.numRoots * sizeof(xWindowRoot));
484 ConnectionInfo = (char *) xalloc(lenofblock);
488 memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
489 sizesofar = sizeof(xConnSetup);
490 pBuf = ConnectionInfo + sizeof(xConnSetup);
492 memmove(pBuf, VENDOR_STRING, (int)setup.nbytesVendor);
493 sizesofar += setup.nbytesVendor;
494 pBuf += setup.nbytesVendor;
495 i = padlength[setup.nbytesVendor & 3];
500 for (i=0; i<screenInfo.numPixmapFormats; i++)
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;
509 format.scanLinePad = screenInfo.formats[i].scanlinePad;
510 memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
511 pBuf += sizeof(xPixmapFormat);
512 sizesofar += sizeof(xPixmapFormat);
515 connBlockScreenStart = sizesofar;
516 for (i=0; i<screenInfo.numScreens; i++)
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);
543 pDepth = pScreen->allowedDepths;
544 for(j = 0; j < pScreen->numDepths; j++, pDepth++)
546 lenofblock += sizeof(xDepth) +
547 (pDepth->numVids * sizeof(xVisualType));
548 pBuf = (char *)xrealloc(ConnectionInfo, lenofblock);
551 xfree(ConnectionInfo);
554 ConnectionInfo = pBuf;
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++)
563 vid = pDepth->vids[k];
564 for (pVisual = pScreen->visuals;
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);
581 connSetupPrefix.success = xTrue;
582 connSetupPrefix.length = lenofblock/4;
583 connSetupPrefix.majorVersion = X_PROTOCOL;
584 connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
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.
597 #if NeedFunctionPrototypes
600 #if NeedNestedPrototypes
602 ScreenPtr /*pScreen*/,
610 AddScreen(pfnInit, argc, argv)
618 int scanlinepad, format, depth, bitsPerPixel, j, k;
624 i = screenInfo.numScreens;
628 pScreen = (ScreenPtr) xalloc(sizeof(ScreenRec));
632 pScreen->devPrivates = (DevUnion *)xalloc(screenPrivateCount *
634 if (!pScreen->devPrivates && screenPrivateCount)
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);
647 pScreen->PixmapPrivateLen = 0;
648 pScreen->PixmapPrivateSizes = (unsigned *)NULL;
649 pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
651 pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
652 pScreen->CreateScreenResources = 0;
655 for (jNI = &pScreen->QueryBestSize;
656 jNI < (void (**) ()) &pScreen->SendGraphicsExpose;
658 *jNI = NotImplemented;
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.
670 for (format=0; format<screenInfo.numPixmapFormats; format++)
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])
684 PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
685 PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
686 answerBytesPerPixel[bitsPerPixel];
690 PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
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.
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])
706 PixmapWidthPaddingInfoProto[ depth ].notPower2 = 1;
707 PixmapWidthPaddingInfoProto[ depth ].bytesPerPixel =
708 answerBytesPerPixel[bitsPerPixel];
712 PixmapWidthPaddingInfoProto[ depth ].notPower2 = 0;
714 #endif /* INTERNAL_VS_EXTERNAL_PADDING */
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
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))
732 screenInfo.numScreens--;
742 xfree(pScreen->WindowPrivateSizes);
743 xfree(pScreen->GCPrivateSizes);
745 xfree(pScreen->PixmapPrivateSizes);
747 xfree(pScreen->devPrivates);