Viewing file: xserver.py (14.06 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# # xserver.py - initial xserver startup for GUI mode. # # Michael Fulbright <msf@redhat.com> # Matt Wilson <msw@redhat.com> # Brent Fox <bfox@redhat.com> # # Copyright 1999-2002 Red Hat, Inc. # # This software may be freely redistributed under the terms of the GNU # library public license. # # You should have received a copy of the GNU Library Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
import os import string import sys import time
import rhpl.videocard as videocard import rhpl.monitor as monitor import rhpl.mouse as mouse import rhpl.keyboard as keyboard import rhpl.translate as translate import rhpl.arch from rhpl.translate import _ from rhpl.xhwstate import * from rhpl.log import log
translate.textdomain('rhpl')
# probes and starts X server in one call def probeHWandStartXServer(runres, display=':1', logfile = None, xStartedCB=None, xQuitCB=None):
(videohw, monitorhw, mousehw) = probeHW() kbd = keyboard.Keyboard()
xsetup_failed = startXServer(videohw, monitorhw, mousehw, kbd, runres, display=display, logfile=logfile, xStartedCB=xStartedCB, xQuitCB=xQuitCB)
return xsetup_failed
# # starts the X server up based on values passed # # will setup so rest of python app runs as a child and we wait on it # to exit, then we'll clean up X server process # # def startXServer(videohw, monitorhw, mousehw, kbd, runres, display=':1', logfile = None, xStartedCB=None, xQuitCB=None, useFB = False):
xsetup_failed = 0 try: startX(runres, videohw, monitorhw, mousehw, kbd, display=display, logfile=logfile, xStartedCB=xStartedCB, xQuitCB=xQuitCB, useFB = useFB) except RuntimeError: xsetup_failed = 1
return xsetup_failed
# probes current hardware, makes best effort at starting X server # # skipDDC controls whether we try to use VESA BIOS to determine data # Can cause some machines to hang. # # return a tuple with probed values: (videohw, monitorhw, mousehw) def probeHW(skipDDCProbe=0, skipMouseProbe=0, logFunc=None): videohw = videocard.VideoCardInfo(skipDDCProbe=skipDDCProbe)
if videohw and videohw.primaryCard(): cardstr = videohw.primaryCard().shortDescription() else: cardstr = _("Unable to probe")
cardstr = _("Probing for video card: %s") % (cardstr,) if logFunc is None: print cardstr else: logFunc(cardstr)
monitorhw = monitor.MonitorInfo(fbDevice=None, skipDDCProbe=skipDDCProbe) monstr = monitorhw.shortDescription() monstr = _("Probing for monitor type: %s") % (monstr,) if logFunc is None: print monstr else: logFunc(monstr)
mousehw = mouse.Mouse(skipProbe = skipMouseProbe) if not skipMouseProbe: mousename = mousehw.shortDescription() else: mousename = _("Skipped mouse probe.") mousestr = _("Probing for mouse type: %s") %(mousename,)
if logFunc is None: print mousestr else: logFunc(mousestr)
return (videohw, monitorhw, mousehw)
# start X server def startX(resolution, video, monitor, mouse, keyboard, display=':1', logfile = None, xStartedCB=None, xQuitCB=None, useFB = False): os.environ['DISPLAY'] = display serverPath = None
attempt = 'PROBED'
# use the framebuffer server by default on ppc if rhpl.arch.getCanonArch() == "ppc64pseries" or useFB: attempt = "FB"
orig_hsync = monitor.getMonitorHorizSync() orig_vsync = monitor.getMonitorVertSync() failed = 1 next_attempt = None while next_attempt != 'END': card = None test_resolution = resolution
if attempt == 'PROBED': card = None if video.primaryCard() is not None: print _("Attempting to start native X server") card = video.primaryCard().getDevID()
next_attempt = 'LCD' elif attempt == 'LCD': card = None if video.primaryCard() is not None and logfile is not None and os.access(logfile, os.R_OK): # see if they have an LCD we can guess import rhpl.guesslcd as guesslcd
(xres, yres) = guesslcd.scanXLogForLCD(logfile, video.primaryCard().getDriver()) if xres is not None: test_resolution = "%sx%s" % (xres, yres) (new_hsync, new_vsync) = guesslcd.getSyncForRes(test_resolution)
# set monitor to use new value monitor.setSpecs(new_hsync, new_vsync)
# messy hack for how rhpl.xhwstate works # current it wants to use probed values which we dont # have so we'll fake them hsync = monitor.getMonitorHorizSync() vsync = monitor.getMonitorVertSync() monitor.orig_monHoriz = hsync monitor.orig_monVert = vsync
print _("Attempting to start native X server using resolution %sx%s" % (xres, yres)) card = video.primaryCard().getDevID() next_attempt = 'VESA' elif attempt == 'VESA': card = None if video.primaryCard() is not None and video.primaryCard().getDescription() is not "VESA driver (generic)": print _("Attempting to start VESA driver X server") vram = video.primaryCard().getVideoRam() if vram: card = "VESA driver (generic)"
next_attempt = 'END' elif attempt == 'FB': print _("Attempting to start frame buffer X server") card = "Framebuffer driver (generic)"
next_attempt = 'END' else: print "Got off end somehow!" break
if card: # # XXX - assuming 'XFree86' is the binary for server # servername = 'Xorg' serverPath = '/usr/X11R6/bin/' + servername
if os.access (serverPath, os.X_OK): try: hwstate = XF86HardwareState(defcard=video, defmon=monitor, probeflags=XF86HW_PROBE_NONE) hwstate.set_resolution(test_resolution) hwstate.set_videocard_card(card)
testx(hwstate, mouse, keyboard, logfile=logfile, xStartedCB = xStartedCB, xQuitCB = xQuitCB)
failed = 0 break except (RuntimeError, IOError): pass
# restore monitor try again monitor.setSpecs(orig_hsync, orig_vsync)
# messy hack for how rhpl.xhwstate works # current it wants to use probed values which we dont # have so we'll fake them hsync = monitor.getMonitorHorizSync() vsync = monitor.getMonitorVertSync() monitor.orig_monHoriz = hsync monitor.orig_monVert = vsync attempt = next_attempt #--If original server isn't there...send them to text mode if failed: raise RuntimeError, "No X server binaries found to run" return hwstate
def testx(hwstate, mouse, keyboard, logfile = None, xStartedCB=None, xQuitCB=None):
try: server = writeXConfigAndRunX(hwstate, mouse, keyboard, serverflags = [':1', 'vt7', '-s', '1440', '-terminate', '-dpms', '-v', '-ac', '-nolisten', 'tcp'], standalone = 1, logfile=logfile) except: import traceback server = None (type, value, tb) = sys.exc_info() list = traceback.format_exception (type, value, tb) text = string.joinfields (list, "") print text
# give time for the server to fail (if it is going to fail...) # FIXME: Should find out if X server is already running # otherwise with NFS installs the X server may be still being # fetched from the network while we already continue to run if not server: sys.stderr.write("X SERVER FAILED"); raise RuntimeError, "X server failed to start"
count = 0
sys.stdout.write(_("Waiting for X server to start...log located in /tmp/X.log\n")) sys.stdout.flush()
for i in range(5): time.sleep(1) sys.stdout.write("%s..." % (i+1)) sys.stdout.flush() while count < 60: sys.stdout.write(".") sys.stdout.flush() pid = 0 try: pid, status = os.waitpid (server, os.WNOHANG) except OSError, (errno, msg): print __name__, "waitpid:", msg if pid: sys.stderr.write("X SERVER FAILED"); raise RuntimeError, "X server failed to start" try: os.stat ("/tmp/.X11-unix/X1") break except OSError: pass time.sleep(1) count = count + 1
print _(" X server started successfully.")
if xStartedCB is not None: xStartedCB()
child = os.fork() if (child): # here we fork and wait on our child, which will contine # on being anaconda, to finish. When the child finishes # we kill the X server and exit with the exit status set to # the same exit status of our child (which is now the main # anaconda process). try: pid, status = os.waitpid(child, 0) except OSError, (errno, msg): print __name__, "waitpid:", msg sys.exit (-1)
if xQuitCB is not None: xQuitCB()
# now the X server try: os.kill(server, 15) os.waitpid(server, 0) except: pass
if os.WIFEXITED(status) and not os.WEXITSTATUS(status): sys.exit(0)
sys.exit(-1)
# # should probably be in rhpl # def writeXConfig(filename, hwstate, mouse, keyboard, standalone = 0): if hwstate.videocard == None: return None
standalone_fontpaths = ["/usr/X11R6/lib/X11/fonts/misc:unscaled", "/usr/X11R6/lib/X11/fonts/Type1/", "/usr/X11R6/lib/X11/fonts/Speedo/", "/usr/X11R6/lib/X11/fonts/75dpi:unscaled", "/usr/X11R6/lib/X11/fonts/100dpi:unscaled", "/usr/X11R6/lib/X11/fonts/korean:unscaled", "/usr/X11R6/lib/X11/fonts/cyrillic:unscaled", "/usr/share/fonts/ISO8859-2/misc:unscaled", "/usr/share/fonts/ISO8859-2/75dpi:unscaled", "/usr/share/fonts/ISO8859-2/100dpi:unscaled", "/usr/share/fonts/ISO8859-9/misc:unscaled", "/usr/share/fonts/ISO8859-9/75dpi:unscaled", "/usr/share/fonts/ISO8859-9/100dpi:unscaled", "/usr/share/fonts/KOI8-R/misc:unscaled", "/usr/share/fonts/KOI8-R/75dpi:unscaled" ]
# # get an xg86config object that represents the config file we're going # to write out # xcfgdata = hwstate.generate_xconfig(mouse, keyboard)
# add the font paths we need if desired if standalone: files = xcfgdata.files tmpfp = files.fontpath newfp = "" for fp in standalone_fontpaths: newfp = newfp + fp + ","
newfp = newfp + tmpfp
files.fontpath = newfp xcfgdata.write(filename)
# BAD BAD BAD AWFUL HACK to work around #120950 f = open(filename, "r") lines = f.readlines() f.close() buf = "" for l in lines: if l.startswith("#") and l.find("HorizSync") != -1: l = l.replace("#", "") if l.startswith("#") and l.find("VertRefresh") != -1: l = l.replace("#", "") buf += l f = open(filename, "w") f.write(buf) f.close()
# # should probably be in rhpl # # # hwstate is a X hw state object from rhpl.xhwstate # mouse is mouse object from rhpl.mouse # keyboard is a keyboard object from rhpl.keyboard # serverflags are extra flags to throw at X server command line # root is top of hierarchy we look for X server in # standalone = 1 means we're running without xfs (anaconda mode essentially) # def writeXConfigAndRunX(hwstate, mouse, keyboard, serverflags=None, root='/', standalone = 0, logfile=None):
if hwstate.videocard == None: return None
# # XXX - Assuming X server binary is 'XFree86' # servername = 'Xorg' use_resolution = hwstate.get_resolution()
# FIXME: this is a hack to set the resolution on the framebuffer # to what we want to avoid having X understand this. # if (os.access("/usr/sbin/fbset", os.X_OK) and # hwstate.videocard.isFramebuffer()): # resFbModeMap = { "640x480": "640x480-90", # "800x600": "800x600-90", # "1024x768": "1024x768-75", # "1152x864": "1152x864-70", # "1280x1024": "1280x1024-70" } # depth = hwstate.get_colordepth() # if resFbModeMap.has_key(use_resolution): # args = [ "/usr/sbin/fbset", "-a", resFbModeMap[use_resolution], # "-depth", depth ] # executil.execWithRedirect(args[0], args, stdout = "/dev/tty5", # stderr = "/dev/tty5")
# # make text fit on screen # if use_resolution == "640x480": forced_dpi = 75 else: forced_dpi = 96
# write X Config writeXConfig('%s/tmp/XConfig.test' % (root,), hwstate, mouse, keyboard, standalone)
# setup to run X server serverPath = "/usr/X11R6/bin/" + servername
serverpid = os.fork()
if (not serverpid): if (root and root != '/'): os.chroot (root) os.chdir("/")
args = [serverPath, '-config', '/tmp/XConfig.test' ] tmplogFile = "/tmp/X.log" if servername == "Xorg": args = args + ["-logfile",] if logfile is not None: args = args + [logfile,] else: args = args + ["/dev/null",] if serverflags: args = args + serverflags else: args = args + [ ":9", "vt6" ] tmplogFile = "/tmp/X-Test.log"
try: err = os.open(tmplogFile, os.O_RDWR | os.O_CREAT) if err < 0: sys.stderr.write("error opening /tmp/X.log\n") else: os.dup2(err, 2) os.close(err) except: # oh well pass
os.execv(args[0], args) sys.exit (1)
return serverpid
# # Here is some example code to show how to get simple X display going # # run like (assuming you have rhpl installed in correct location): # # python2.2 xserver.py # if __name__ == '__main__': import os import sys import rhpl.xserver as xserver import rhpl.keyboard as keyboard
skipddcprobe = 0 skipmouseprobe = 0
# get best guesses on available hardware. We'll let it do probes that # can lockup systems. (videohw, monitorhw, mousehw) = xserver.probeHW(skipDDCProbe=skipddcprobe, skipMouseProbe = skipmouseprobe) # create a keyboard object kbd = keyboard.Keyboard()
# startup X based on this information runres = "1024x768" xsetup_failed = xserver.startXServer(videohw, monitorhw, mousehw, kbd, runres)
if xsetup_failed: print "Could not start X server, sorry!" sys.exit(0)
os.system("/usr/X11R6/bin/xterm -T 'It Worked!'")
|