Пример #1
0
static void
resume(pmEvent event, Bool undo)
{
    int i;
    InputInfoPtr pInfo;

    xf86AccessEnter();
    xf86EnterServerState(SETUP);
    for (i = 0; i < xf86NumScreens; i++) {
        xf86EnableAccess(xf86Screens[i]);
	if (xf86Screens[i]->PMEvent)
	    xf86Screens[i]->PMEvent(i,event,undo);
	else {
	    xf86Screens[i]->vtSema = TRUE;
	    xf86Screens[i]->EnterVT(i, 0);
	}
    }
    xf86EnterServerState(OPERATING);
    for (i = 0; i < xf86NumScreens; i++) {
        xf86EnableAccess(xf86Screens[i]);
	if (xf86Screens[i]->EnableDisableFBAccess)
	    (*xf86Screens[i]->EnableDisableFBAccess) (i, TRUE);
    }
    SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset);
#if !defined(__EMX__)
    pInfo = xf86InputDevs;
    while (pInfo) {
	EnableDevice(pInfo->dev);
	pInfo = pInfo->next;
    }
#endif
    xf86inSuspend = FALSE;
}
Пример #2
0
static void
DoApmEvent(pmEvent event, Bool undo)
{
    /* 
     * we leave that as a global function for now. I don't know if 
     * this might cause problems in the future. It is a global server 
     * variable therefore it needs to be in a server info structure
     */
    int i, setup = 0;
    
    switch(event) {
#if 0
    case XF86_APM_SYS_STANDBY:
    case XF86_APM_USER_STANDBY:
#endif
    case XF86_APM_SYS_SUSPEND:
    case XF86_APM_CRITICAL_SUSPEND: /*do we want to delay a critical suspend?*/
    case XF86_APM_USER_SUSPEND:
	/* should we do this ? */
	if (!undo && !suspended) {
	    suspend(event,undo);
	    suspended = TRUE;
	} else if (undo && suspended) {
	    resume(event,undo);
	    suspended = FALSE;
	}
	break;
#if 0
    case XF86_APM_STANDBY_RESUME:
#endif
    case XF86_APM_NORMAL_RESUME:
    case XF86_APM_CRITICAL_RESUME:
	if (suspended) {
	    resume(event,undo);
	    suspended = FALSE;
	}
	break;
    default:
	for (i = 0; i < xf86NumScreens; i++) {
	    if (xf86Screens[i]->PMEvent) {
		if (!setup) xf86EnterServerState(SETUP);
		setup = 1;
		xf86EnableAccess(xf86Screens[i]);
		xf86Screens[i]->PMEvent(i,event,undo);
	    }
	}
	if (setup) xf86EnterServerState(OPERATING);
	break;
    }
}
Пример #3
0
static void
suspend (pmEvent event, Bool undo)
{
    int i;
    InputInfoPtr pInfo;

   xf86inSuspend = TRUE;
    
    for (i = 0; i < xf86NumScreens; i++) {
        xf86EnableAccess(xf86Screens[i]);
	if (xf86Screens[i]->EnableDisableFBAccess)
	    (*xf86Screens[i]->EnableDisableFBAccess) (i, FALSE);
    }
#if !defined(__EMX__)
    pInfo = xf86InputDevs;
    while (pInfo) {
	DisableDevice(pInfo->dev);
	pInfo = pInfo->next;
    }
#endif
    xf86EnterServerState(SETUP);
    for (i = 0; i < xf86NumScreens; i++) {
        xf86EnableAccess(xf86Screens[i]);
	if (xf86Screens[i]->PMEvent)
	    xf86Screens[i]->PMEvent(i,event,undo);
	else {
	    xf86Screens[i]->LeaveVT(i, 0);
	    xf86Screens[i]->vtSema = FALSE;
	}
    }
    xf86AccessLeave();      
    xf86AccessLeaveState(); 
}
Пример #4
0
void
AbortDDX(void)
{
  int i;

  /*
   * try to restore the original video state
   */
#ifdef DPMSExtension /* Turn screens back on */
  if (DPMSPowerLevel != DPMSModeOn)
      DPMSSet(serverClient, DPMSModeOn);
#endif
  if (xf86Screens) {
      if (xf86Screens[0]->vtSema)
	  xf86EnterServerState(SETUP);
      for (i = 0; i < xf86NumScreens; i++)
	  if (xf86Screens[i]->vtSema) {
	      /*
	       * if we are aborting before ScreenInit() has finished
	       * we might not have been wrapped yet. Therefore enable
	       * screen explicitely.
	       */
	      xf86VGAarbiterLock(xf86Screens[i]);
	      (xf86Screens[i]->LeaveVT)(i, 0);
	      xf86VGAarbiterUnlock(xf86Screens[i]);
	  }
  }

  xf86AccessLeave();

  /*
   * This is needed for an abnormal server exit, since the normal exit stuff
   * MUST also be performed (i.e. the vt must be left in a defined state)
   */
  ddxGiveUp();
}
/*
 * xf86VTSwitch --
 *      Handle requests for switching the vt.
 */
static void
xf86VTSwitch(void)
{
  int i, prevSIGIO;
  InputInfoPtr pInfo;
  IHPtr ih;

  DebugF("xf86VTSwitch()\n");

#ifdef XFreeXDGA
  if(!DGAVTSwitch())
	return;
#endif

  /*
   * Since all screens are currently all in the same state it is sufficient
   * check the first.  This might change in future.
   */
  if (xf86Screens[0]->vtSema) {

    DebugF("xf86VTSwitch: Leaving, xf86Exiting is %s\n",
	   BOOLTOSTRING((dispatchException & DE_TERMINATE) ? TRUE : FALSE));
#ifdef DPMSExtension
    if (DPMSPowerLevel != DPMSModeOn)
	DPMSSet(serverClient, DPMSModeOn);
#endif
    for (i = 0; i < xf86NumScreens; i++) {
      if (!(dispatchException & DE_TERMINATE))
	if (xf86Screens[i]->EnableDisableFBAccess)
	  (*xf86Screens[i]->EnableDisableFBAccess) (i, FALSE);
    }

    /*
     * Keep the order: Disable Device > LeaveVT
     *                        EnterVT > EnableDevice
     */
    for (ih = InputHandlers; ih; ih = ih->next)
      xf86DisableInputHandler(ih);
    for (pInfo = xf86InputDevs; pInfo; pInfo = pInfo->next) {
      if (pInfo->dev) {
          xf86ReleaseKeys(pInfo->dev);
          ProcessInputEvents();
          DisableDevice(pInfo->dev, TRUE);
      }
    }
    xf86EnterServerState(SETUP);
    for (i = 0; i < xf86NumScreens; i++)
	xf86Screens[i]->LeaveVT(i, 0);

    xf86AccessLeave();      /* We need this here, otherwise */

    if (!xf86VTSwitchAway()) {
      /*
       * switch failed
       */

      DebugF("xf86VTSwitch: Leave failed\n");
      prevSIGIO = xf86BlockSIGIO();
      xf86AccessEnter();
      xf86EnterServerState(SETUP);
      for (i = 0; i < xf86NumScreens; i++) {
	if (!xf86Screens[i]->EnterVT(i, 0))
	  FatalError("EnterVT failed for screen %d\n", i);
      }
      xf86EnterServerState(OPERATING);
      if (!(dispatchException & DE_TERMINATE)) {
	for (i = 0; i < xf86NumScreens; i++) {
	  if (xf86Screens[i]->EnableDisableFBAccess)
	    (*xf86Screens[i]->EnableDisableFBAccess) (i, TRUE);
	}
      }
      dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);

      pInfo = xf86InputDevs;
      while (pInfo) {
        if (pInfo->dev)
            EnableDevice(pInfo->dev, TRUE);
	pInfo = pInfo->next;
      }
      for (ih = InputHandlers; ih; ih = ih->next)
        xf86EnableInputHandler(ih);

      xf86UnblockSIGIO(prevSIGIO);

    } else {
#ifdef XF86PM
	  if (xf86OSPMClose)
	      xf86OSPMClose();
	  xf86OSPMClose = NULL;
#endif

	for (i = 0; i < xf86NumScreens; i++) {
 	    /*
 	     * zero all access functions to
 	     * trap calls when switched away.
 	     */
	    xf86Screens[i]->vtSema = FALSE;
	}
	if (xorgHWAccess)
	    xf86DisableIO();
    }
  } else {

    DebugF("xf86VTSwitch: Entering\n");
    if (!xf86VTSwitchTo()) return;

    prevSIGIO = xf86BlockSIGIO();
#ifdef XF86PM
    xf86OSPMClose = xf86OSPMOpen();
#endif

    if (xorgHWAccess)
	xf86EnableIO();
    xf86AccessEnter();
    xf86EnterServerState(SETUP);
    for (i = 0; i < xf86NumScreens; i++) {
      xf86Screens[i]->vtSema = TRUE;
      if (!xf86Screens[i]->EnterVT(i, 0))
	  FatalError("EnterVT failed for screen %d\n", i);
    }
    xf86EnterServerState(OPERATING);
    for (i = 0; i < xf86NumScreens; i++) {
      if (xf86Screens[i]->EnableDisableFBAccess)
	(*xf86Screens[i]->EnableDisableFBAccess)(i, TRUE);
    }

    /* Turn screen saver off when switching back */
    dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);

    pInfo = xf86InputDevs;
    while (pInfo) {
      if (pInfo->dev)
          EnableDevice(pInfo->dev, TRUE);
      pInfo = pInfo->next;
    }

    for (ih = InputHandlers; ih; ih = ih->next)
      xf86EnableInputHandler(ih);

    xf86UnblockSIGIO(prevSIGIO);
  }
}
Пример #6
0
/*
 * InitOutput --
 *	Initialize screenInfo for all actually accessible framebuffers.
 *      That includes vt-manager setup, querying all possible devices and
 *      collecting the pixmap formats.
 */
void
InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
{
  int                    i, j, k, scr_index;
  char                   **modulelist;
  pointer                *optionlist;
  Pix24Flags		 screenpix24, pix24;
  MessageType		 pix24From = X_DEFAULT;
  Bool			 pix24Fail = FALSE;
  Bool			 autoconfig = FALSE;
  GDevPtr		 configured_device;

  xf86Initialising = TRUE;

  if (serverGeneration == 1) {
    if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
      xf86ServerName++;
    else
      xf86ServerName = argv[0];

	xf86PrintBanner();
	xf86PrintMarkers();
	if (xf86LogFile)  {
	    time_t t;
	    const char *ct;
	    t = time(NULL);
	    ct = ctime(&t);
	    xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
			xf86LogFile, ct);
	}

    /* Read and parse the config file */
    if (!xf86DoConfigure && !xf86DoShowOptions) {
      switch (xf86HandleConfigFile(FALSE)) {
      case CONFIG_OK:
	break;
      case CONFIG_PARSE_ERROR:
	xf86Msg(X_ERROR, "Error parsing the config file\n");
	return;
      case CONFIG_NOFILE:
	autoconfig = TRUE;
	break;
      }
    }

    InstallSignalHandlers();

    /* Initialise the loader */
    LoaderInit();

    /* Tell the loader the default module search path */
    LoaderSetPath(xf86ModulePath);

    if (xf86Info.ignoreABI) {
        LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
    }

    if (xf86DoShowOptions)
        DoShowOptions();

    /* Do a general bus probe.  This will be a PCI probe for x86 platforms */
    xf86BusProbe();

    if (xf86DoConfigure)
	DoConfigure();

    if (autoconfig) {
	if (!xf86AutoConfig()) {
	    xf86Msg(X_ERROR, "Auto configuration failed\n");
	    return;
	}
    }

#ifdef XF86PM
    xf86OSPMClose = xf86OSPMOpen();
#endif

    /* Load all modules specified explicitly in the config file */
    if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
      xf86LoadModules(modulelist, optionlist);
      free(modulelist);
      free(optionlist);
    }

    /* Load all driver modules specified in the config file */
    /* If there aren't any specified in the config file, autoconfig them */
    /* FIXME: Does not handle multiple active screen sections, but I'm not
     * sure if we really want to handle that case*/
    configured_device = xf86ConfigLayout.screens->screen->device;
    if ((!configured_device) || (!configured_device->driver)) {
        if (!autoConfigDevice(configured_device)) {
            xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
            return ;
        }
    }
    if ((modulelist = xf86DriverlistFromConfig())) {
      xf86LoadModules(modulelist, NULL);
      free(modulelist);
    }

    /* Load all input driver modules specified in the config file. */
    if ((modulelist = xf86InputDriverlistFromConfig())) {
      xf86LoadModules(modulelist, NULL);
      free(modulelist);
    }

    /*
     * It is expected that xf86AddDriver()/xf86AddInputDriver will be
     * called for each driver as it is loaded.  Those functions save the
     * module pointers for drivers.
     * XXX Nothing keeps track of them for other modules.
     */
    /* XXX What do we do if not all of these could be loaded? */

    /*
     * At this point, xf86DriverList[] is all filled in with entries for
     * each of the drivers to try and xf86NumDrivers has the number of
     * drivers.  If there are none, return now.
     */

    if (xf86NumDrivers == 0) {
      xf86Msg(X_ERROR, "No drivers available.\n");
      return;
    }

    /*
     * Call each of the Identify functions and call the driverFunc to check
     * if HW access is required.  The Identify functions print out some
     * identifying information, and anything else that might be
     * needed at this early stage.
     */

    for (i = 0; i < xf86NumDrivers; i++) {
	if (xf86DriverList[i]->Identify != NULL)
	    xf86DriverList[i]->Identify(0);

	if (!xorgHWAccess || !xorgHWOpenConsole) {
	    xorgHWFlags flags;
	    if(!xf86DriverList[i]->driverFunc
		|| !xf86DriverList[i]->driverFunc(NULL,
						  GET_REQUIRED_HW_INTERFACES,
						  &flags))
		flags = HW_IO;

	    if(NEED_IO_ENABLED(flags))
		xorgHWAccess = TRUE;
	    if(!(flags & HW_SKIP_CONSOLE))
		xorgHWOpenConsole = TRUE;
	}
    }

    if (xorgHWOpenConsole)
	xf86OpenConsole();
    else
	xf86Info.dontVTSwitch = TRUE;

    if (xf86BusConfig() == FALSE)
        return;

    xf86PostProbe();

    /*
     * Sort the drivers to match the requested ording.  Using a slow
     * bubble sort.
     */
    for (j = 0; j < xf86NumScreens - 1; j++) {
	for (i = 0; i < xf86NumScreens - j - 1; i++) {
	    if (xf86Screens[i + 1]->confScreen->screennum <
		xf86Screens[i]->confScreen->screennum) {
		ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
		xf86Screens[i + 1] = xf86Screens[i];
		xf86Screens[i] = tmpScrn;
	    }
	}
    }
    /* Fix up the indexes */
    for (i = 0; i < xf86NumScreens; i++) {
	xf86Screens[i]->scrnIndex = i;
    }

    /*
     * Call the driver's PreInit()'s to complete initialisation for the first
     * generation.
     */

    for (i = 0; i < xf86NumScreens; i++) {
	xf86VGAarbiterScrnInit(xf86Screens[i]);
	xf86VGAarbiterLock(xf86Screens[i]);
	if (xf86Screens[i]->PreInit &&
	    xf86Screens[i]->PreInit(xf86Screens[i], 0))
	    xf86Screens[i]->configured = TRUE;
	xf86VGAarbiterUnlock(xf86Screens[i]);
    }
    for (i = 0; i < xf86NumScreens; i++)
	if (!xf86Screens[i]->configured)
	    xf86DeleteScreen(i--, 0);

    /*
     * If no screens left, return now.
     */

    if (xf86NumScreens == 0) {
      xf86Msg(X_ERROR,
	      "Screen(s) found, but none have a usable configuration.\n");
      return;
    }

    for (i = 0; i < xf86NumScreens; i++) {
      if (xf86Screens[i]->name == NULL) {
	xf86Screens[i]->name = xnfalloc(strlen("screen") + 10 + 1);
	sprintf(xf86Screens[i]->name, "screen%d", i);
	xf86MsgVerb(X_WARNING, 0,
		    "Screen driver %d has no name set, using `%s'.\n",
		    i, xf86Screens[i]->name);
      }
    }

    /* Remove (unload) drivers that are not required */
    for (i = 0; i < xf86NumDrivers; i++)
	if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
	    xf86DeleteDriver(i);

    /*
     * At this stage we know how many screens there are.
     */

    for (i = 0; i < xf86NumScreens; i++)
      xf86InitViewport(xf86Screens[i]);

    /*
     * Collect all pixmap formats and check for conflicts at the display
     * level.  Should we die here?  Or just delete the offending screens?
     */
    screenpix24 = Pix24DontCare;
    for (i = 0; i < xf86NumScreens; i++) {
	if (xf86Screens[i]->imageByteOrder !=
	    xf86Screens[0]->imageByteOrder)
	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");
	if (xf86Screens[i]->bitmapScanlinePad !=
	    xf86Screens[0]->bitmapScanlinePad)
	    FatalError("Inconsistent display bitmapScanlinePad.  Exiting\n");
	if (xf86Screens[i]->bitmapScanlineUnit !=
	    xf86Screens[0]->bitmapScanlineUnit)
	    FatalError("Inconsistent display bitmapScanlineUnit.  Exiting\n");
	if (xf86Screens[i]->bitmapBitOrder !=
	    xf86Screens[0]->bitmapBitOrder)
	    FatalError("Inconsistent display bitmapBitOrder.  Exiting\n");

	/* Determine the depth 24 pixmap format the screens would like */
	if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
	    if (screenpix24 == Pix24DontCare)
		screenpix24 = xf86Screens[i]->pixmap24;
	    else if (screenpix24 != xf86Screens[i]->pixmap24)
		FatalError("Inconsistent depth 24 pixmap format.  Exiting\n");
	}
    }
    /* check if screenpix24 is consistent with the config/cmdline */
    if (xf86Info.pixmap24 != Pix24DontCare) {
	pix24 = xf86Info.pixmap24;
	pix24From = xf86Info.pix24From;
	if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
	    pix24Fail = TRUE;
    } else if (screenpix24 != Pix24DontCare) {
	pix24 = screenpix24;
	pix24From = X_PROBED;
    } else
	pix24 = Pix24Use32;

    if (pix24Fail)
	FatalError("Screen(s) can't use the required depth 24 pixmap format"
		   " (%d).  Exiting\n", PIX24TOBPP(pix24));

    /* Initialise the depth 24 format */
    for (j = 0; j < numFormats && formats[j].depth != 24; j++)
	;
    formats[j].bitsPerPixel = PIX24TOBPP(pix24);

    /* Collect additional formats */
    for (i = 0; i < xf86NumScreens; i++) {
	for (j = 0; j < xf86Screens[i]->numFormats; j++) {
	    for (k = 0; ; k++) {
		if (k >= numFormats) {
		    if (k >= MAXFORMATS)
			FatalError("Too many pixmap formats!  Exiting\n");
		    formats[k] = xf86Screens[i]->formats[j];
		    numFormats++;
		    break;
		}
		if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
		    if ((formats[k].bitsPerPixel ==
			 xf86Screens[i]->formats[j].bitsPerPixel) &&
		        (formats[k].scanlinePad ==
			 xf86Screens[i]->formats[j].scanlinePad))
			break;
		    FatalError("Inconsistent pixmap format for depth %d."
			       "  Exiting\n", formats[k].depth);
		}
	    }
	}
    }
    formatsDone = TRUE;

    if (xf86Info.vtno >= 0 ) {
#define VT_ATOM_NAME         "XFree86_VT"
      Atom VTAtom=-1;
      CARD32  *VT = NULL;
      int  ret;

      /* This memory needs to stay available until the screen has been
	 initialized, and we can create the property for real.
      */
      if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
	FatalError("Unable to make VT property - out of memory. Exiting...\n");
      }
      *VT = xf86Info.vtno;

      VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);

      for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
	ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
					     VTAtom, XA_INTEGER, 32,
					     1, VT );
	if (ret != Success)
	  xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
		     "Failed to register VT property\n");
      }
    }

    /* If a screen uses depth 24, show what the pixmap format is */
    for (i = 0; i < xf86NumScreens; i++) {
	if (xf86Screens[i]->depth == 24) {
	    xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
		    PIX24TOBPP(pix24));
	    break;
	}
    }
  } else {
    /*
     * serverGeneration != 1; some OSs have to do things here, too.
     */
    if (xorgHWOpenConsole)
	xf86OpenConsole();

#ifdef XF86PM
    /*
      should we reopen it here? We need to deal with an already opened
      device. We could leave this to the OS layer. For now we simply
      close it here
    */
    if (xf86OSPMClose)
        xf86OSPMClose();
    if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
	xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
#endif

    /* Make sure full I/O access is enabled */
    if (xorgHWAccess)
	xf86EnableIO();
  }

  /*
   * Use the previously collected parts to setup pScreenInfo
   */

  pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
  pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
  pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
  pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
  pScreenInfo->numPixmapFormats = numFormats;
  for (i = 0; i < numFormats; i++)
    pScreenInfo->formats[i] = formats[i];

  /* Make sure the server's VT is active */

  if (serverGeneration != 1) {
    xf86Resetting = TRUE;
    /* All screens are in the same state, so just check the first */
    if (!xf86Screens[0]->vtSema) {
#ifdef HAS_USL_VTS
      ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
#endif
      xf86AccessEnter();
      xf86EnterServerState(SETUP);
    }
  }
#ifdef SCO325
  else {
    /*
     * Under SCO we must ack that we got the console at startup,
     * I think this is the safest way to assure it.
     */
    static int once = 1;
    if (once) {
      once = 0;
      if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
        xf86Msg(X_WARNING, "VT_ACKACQ failed");
    }
  }
#endif /* SCO325 */

  for (i = 0; i < xf86NumScreens; i++)
      if (!xf86ColormapAllocatePrivates(xf86Screens[i]))
	  FatalError("Cannot register DDX private keys");

  if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) ||
      !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0) ||
      !dixRegisterPrivateKey(&xf86PixmapKeyRec, PRIVATE_PIXMAP, 0))
      FatalError("Cannot register DDX private keys");

  for (i = 0; i < xf86NumScreens; i++) {
	xf86VGAarbiterLock(xf86Screens[i]);
	/*
	 * Almost everything uses these defaults, and many of those that
	 * don't, will wrap them.
	 */
	xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
#ifdef XFreeXDGA
	xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
#endif
	xf86Screens[i]->DPMSSet = NULL;
	xf86Screens[i]->LoadPalette = NULL;
	xf86Screens[i]->SetOverscan = NULL;
	xf86Screens[i]->DriverFunc = NULL;
	xf86Screens[i]->pScreen = NULL;
	scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
	xf86VGAarbiterUnlock(xf86Screens[i]);
      if (scr_index == i) {
	/*
	 * Hook in our ScrnInfoRec, and initialise some other pScreen
	 * fields.
	 */
	dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
		      xf86ScreenKey, xf86Screens[i]);
	xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
	/* The driver should set this, but make sure it is set anyway */
	xf86Screens[i]->vtSema = TRUE;
      } else {
	/* This shouldn't normally happen */
	FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
      }

      DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
	     i, xf86Screens[i]->pScreen );
      DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
	     i, xf86Screens[i]->pScreen->CreateWindow );

      dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
		    xf86CreateRootWindowKey,
		    xf86Screens[i]->pScreen->CreateWindow);
      xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;

    if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
    {
	xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
	PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
				 DDC ?
				 (DDC->features.input_type ?
				  SubPixelHorizontalRGB : SubPixelNone) :
				 SubPixelUnknown);
    }
#ifdef RANDR
    if (!xf86Info.disableRandR)
	xf86RandRInit (screenInfo.screens[scr_index]);
    xf86Msg(xf86Info.randRFrom, "RandR %s\n",
	    xf86Info.disableRandR ? "disabled" : "enabled");
#endif
  }

  xf86PostScreenInit();

  xf86InitOrigins();

  xf86Resetting = FALSE;
  xf86Initialising = FALSE;

  RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
				 NULL);
}