# # xf866config.py - XFree86 configuration file generator for 4.x # # Matt Wilson # Brent Fox # Michael Fulbright # # 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 sys if __name__ == "__main__": sys.path.append ('kudzu') sys.path.append ('isys') import string import iutil import kudzu import isys import time import os from rhpl.log import log from rhpl.keyboard import Keyboard from rhpl.mouse import Mouse from rhpl.translate import _ XF86Config_4_template = """ # File generated by anaconda. Section "ServerLayout" Identifier "Anaconda Configured" Screen 0 "Screen0" 0 0 InputDevice "Mouse0" "CorePointer" %(usbmouselayout)s InputDevice "Keyboard0" "CoreKeyboard" EndSection Section "Files" %(files)s EndSection Section "Module" Load "dbe" Load "extmod"%(nonSparcMods)s%(driMod)s Load "glx" Load "record" Load "freetype" Load "type1" EndSection Section "InputDevice" Identifier "Keyboard0" Driver "keyboard" %(autorepeat)s # when using XQUEUE, comment out the above line, and uncomment the # following line # Option "Protocol" "Xqueue" # Specify which keyboard LEDs can be user-controlled (eg, with xset(1)) # Option "Xleds" "1 2 3" # To disable the XKEYBOARD extension, uncomment XkbDisable. # Option "XkbDisable" # To customise the XKB settings to suit your keyboard, modify the # lines below (which are the defaults). For example, for a non-U.S. # keyboard, you will probably want to use: # Option "XkbModel" "pc102" # If you have a US Microsoft Natural keyboard, you can use: # Option "XkbModel" "microsoft" # # Then to change the language, change the Layout setting. # For example, a german layout can be obtained with: # Option "XkbLayout" "de" # or: # Option "XkbLayout" "de" # Option "XkbVariant" "nodeadkeys" # # If you'd like to switch the positions of your capslock and # control keys, use: # Option "XkbOptions" "ctrl:nocaps" Option "XkbRules" "%(XkbRules)s" Option "XkbModel" "%(XkbModel)s" Option "XkbLayout" "%(XkbLayout)s" %(enableVariant)sOption "XkbVariant" "%(XkbVariant)s" %(enableOptions)sOption "XkbOptions" "%(XkbOptions)s" EndSection Section "InputDevice" Identifier "Mouse0" Driver "mouse" Option "Protocol" "%(mouseProto)s" Option "Device" "/dev/%(mouseDevice)s" Option "ZAxisMapping" "4 5" Option "Emulate3Buttons" "%(emulate3)s" EndSection %(usbmousesection)s Section "Monitor" Identifier "Monitor0" VendorName "Monitor Vendor" ModelName "Monitor Model" HorizSync %(monitorHoriz)s VertRefresh %(monitorVert)s Option "dpms" %(displaySizeOptions)s EndSection Section "Device" %(cardsOptions)s Identifier "%(cardID)s" Driver "%(cardDriver)s" VendorName "%(cardVendor)s" BoardName "%(cardBoardName)s" %(videoRam)s #BusID EndSection Section "Screen" Identifier "Screen0" Device "%(cardID)s" Monitor "Monitor0"%(defaultDepth)s %(screenModes)s EndSection Section "DRI" Mode 0666 EndSection """ class XF86Config: def __init__ (self, videocard, monitor, mouse, keyboard, resolution = None): if videocard: self.setVideoCard(videocard) else: raise RuntimeError, "no videocard specified in XF86Config __init__" if monitor: self.setMonitor(monitor) else: raise RuntimeError, "no monitor specified in XF86Config __init__" if mouse: self.setMouse(mouse) else: raise RuntimeError, "no mouse specified in XF86Config __init__" if keyboard: self.setKeyboard(keyboard) else: raise RuntimeError, "no keyboard specified in XF86Config __init__" self.skip = 0 self.res = resolution self.manualModes = {} self.fallbackModes = {} monsyncknown = (self.monitor.getMonitorHorizSync() != None) and (self.monitor.getMonitorVertSync() != None) if self.res: if self.res == "640x480": self.modes = { "8" : ["640x480"] } if not monsyncknown: self.monitor.setSpecs("31.5-35.5", "50-61") else: # assume they are specifying resolution for laptop/lcd # these are values for generic laptop display from monitorsdb self.modes = { "16" : [self.res] } if not monsyncknown: if self.res == "800x600": self.monitor.setSpecs("31.5-48.5", "50-70") elif self.res == "1024x768": self.monitor.setSpecs("31.5-48.5", "40-70") elif self.res == "1280x1024": self.monitor.setSpecs("31.5-67", "50-75") elif self.res == "1400x1050": self.monitor.setSpecs("31.5-90", "59-75") elif self.res == "1600x1200": self.monitor.setSpecs("31.5-90", "60") else: # just pick something reasonable for most modes self.monitor.setSpecs("31.5-65.0", "50-90") else: # fallback if nothing avail self.modes = { "16" : ["800x600"] } if not monsyncknown: self.monitor.setSpecs("31.5-48.5", "50-70") self.fallbackModes = self.modes self.device = None self.monlist = {} self.monids = {} # HACK force dpi setting self.forcedDPI = None # if skipx is TRUE user has selected to not configure X self.skipx = 0 self.files = """ # The location of the RGB database. Note, this is the name of the # file minus the extension (like ".txt" or ".db"). There is normally # no need to change the default. RgbPath "/usr/X11R6/lib/X11/rgb" # Multiple FontPath entries are allowed (they are concatenated together) # By default, Red Hat 6.0 and later now use a font server independent of # the X server to render fonts. FontPath "unix/:7100" """ def setForcedDPI(self, dpi): self.forcedDPI = dpi def getForcedDPI(self): return self.forcedDPI def getKeyboard(self): return (self.keyboard["rules"], self.keyboard["model"], self.keyboard["layout"], self.keyboard["variant"], self.keyboard["options"]) def setMouse(self, mouse): self.mouse = mouse def setKeyboard(self, keyboard): self.keyboard = keyboard def setVideoCard(self, videocard): self.videocard = videocard def setMonitor(self, monitor): self.monitor = monitor def areaCompare (self, first, second): (sx1, sy1) = string.split (first, 'x') (sx2, sy2) = string.split (second, 'x') x1 = string.atoi (sx1) y1 = string.atoi (sy1) x2 = string.atoi (sx2) y2 = string.atoi (sy2) if ((x1 * y1) > (x2 * y2)): return -1 elif ((x1 * y1) < (x2 * y2)): return 1 return 0 def availableModes (self): modes = { "8" : [ "640x480" ] } if not self.videocard: return modes vidRam = self.videocard.getVideoRam() if not vidRam: return modes if string.atoi(vidRam) >= 10240: modes["8"] = ["640x480", "800x600", "1024x768","1152x864", "1280x960", "1280x1024", "1400x1050", "1600x1200", "1920x1440", "2048x1536"] modes["16"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x960", "1280x1024", "1400x1050", "1600x1200", "1920x1440", "2048x1536"] modes["32"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x960", "1280x1024", "1400x1050", "1600x1200", "1920x1440", "2048x1536"] elif string.atoi(vidRam) >= 8192: modes["8"] = ["640x480", "800x600", "1024x768","1152x864", "1280x960", "1280x1024", "1400x1050", "1600x1200", "1920x1440", "2048x1536"] modes["16"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x960", "1280x1024", "1400x1050", "1600x1200", "1920x1440", "2048x1536"] modes["32"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x960", "1280x1024", "1400x1050", "1600x1200"] elif string.atoi(vidRam) >= 6144: modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024", "1400x1050", "1600x1200"] modes["16"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x960", "1280x1024", "1400x1050", "1600x1200"] modes["32"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x1024"] elif string.atoi(vidRam) >= 4096: modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x960", "1280x1024"] modes["16"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x960", "1280x1024"] modes["32"] = ["640x480", "800x600", "1024x768", "1152x864"] elif string.atoi(vidRam) >= 2048: modes["8"] = ["640x480", "800x600", "1024x768", "1152x864", "1280x960", "1280x1024"] modes["16"] = ["640x480", "800x600", "1024x768", "1152x864"] modes["32"] = ["640x480", "800x600"] elif string.atoi(vidRam) >= 1024: modes["8"] = ["640x480", "800x600", "1024x768", "1152x864"] modes["16"] = ["640x480", "800x600"] modes["32"] = [] elif string.atoi(vidRam) >= 512: modes["8"] = ["640x480", "800x600"] modes["16"] = ["640x480"] modes["32"] = [] elif string.atoi(vidRam) >= 256: modes["8"] = ["640x480"] return modes def filterModesByMemory (self): self.modes = self.availableModes() def setModes(self, modes): self.modes = modes def getModes(self): return self.modes def setManualModes(self, modes): self.manualModes = modes def getManualModes(self): return self.manualModes def setFallBackModes(self, modes): self.fallbackModes = modes def getFallBackModes(self): return self.fallbackModes def write (self, path): try: config4 = self.Version4Config (self.videocard) except RuntimeError: return config = open (path + "/XF86Config", 'w') config.write (config4) config.close () def writeKS (self, f, desktop=None): if self.skipx: f.write("skipx\n") return xmodes = self.getManualModes() if len(xmodes) == 0: f.write("skipx\n") return f.write("xconfig") args = self.getArgList(xmodes) if desktop: rl = desktop.getDefaultRunLevel() if rl and str(rl) == '5': args = args + ['--startxonboot', ''] gui = desktop.getDefaultDesktop() if gui: args = args + ['--defaultdesktop', string.lower(gui)] for arg in args: f.write(" " + arg) f.write("\n") def getArgList(self, xmodes): args = [] vc = self.videocard args = args + [ "--card", '"' + vc.shortDescription() + '"' ] args = args + [ "--videoram", vc.getVideoRam() ] args = args + [ "--hsync", self.monitor.getMonitorHorizSync() ] args = args + [ "--vsync", self.monitor.getMonitorVertSync() ] # XXX this isn't really quite right, but it works for the way # things are now depths = xmodes.keys() args = args + [ "--resolution", xmodes[depths[0]][0] ] args = args + [ "--depth", depths[0] ] return args def test (self, serverflags=None, spawn=0, root='/'): if self.videocard == None: return None servername = self.videocard.getXServer() if not servername: return None files = self.files # needed for VGA16 to work? if self.videocard.hasFixedMode(): self.manualModes = self.videocard.FixedMode() # save current manually selected mode, override if non-existant manmodes = self.manualModes if not manmodes: if self.fallbackModes: self.manualModes = self.fallbackModes else: self.manualModes = self.modes self.files = """ RgbPath "/usr/X11R6/lib/X11/rgb" FontPath "/usr/X11R6/lib/X11/fonts/misc:unscaled" FontPath "/usr/X11R6/lib/X11/fonts/Type1/" FontPath "/usr/X11R6/lib/X11/fonts/Speedo/" FontPath "/usr/X11R6/lib/X11/fonts/75dpi:unscaled" FontPath "/usr/X11R6/lib/X11/fonts/100dpi:unscaled" FontPath "/usr/X11R6/lib/X11/fonts/korean:unscaled" FontPath "/usr/X11R6/lib/X11/fonts/cyrillic:unscaled" FontPath "/usr/share/fonts/ISO8859-2/misc:unscaled" FontPath "/usr/share/fonts/ISO8859-2/75dpi:unscaled" FontPath "/usr/share/fonts/ISO8859-2/100dpi:unscaled" FontPath "/usr/share/fonts/ISO8859-9/misc:unscaled" FontPath "/usr/share/fonts/ISO8859-9/75dpi:unscaled" FontPath "/usr/share/fonts/ISO8859-9/100dpi:unscaled" FontPath "/usr/share/fonts/KOI8-R/misc:unscaled" FontPath "/usr/share/fonts/KOI8-R/75dpi:unscaled" """ f = open ('%s/tmp/XF86Config.test' %(root), 'w') if servername == "XFree86": f.write(self.Version4Config(self.videocard, 1)) else: # ack! return f.close () self.files = files # restore manualmodes self.manualModes = manmodes serverPath = "/usr/X11R6/bin/" + servername serverpid = os.fork() if (not serverpid): if (root and root != '/'): os.chroot (root) os.chdir("/") args = [serverPath, '-xf86config', '/tmp/XF86Config.test' ] logFile = "/tmp/X.log" if servername == "XFree86": args = args + [ "-logfile", "/dev/null" ] if serverflags: args = args + serverflags else: args = args + [ ":9", "vt6" ] logFile = "/tmp/X-Test.log" try: err = os.open(logFile, 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) if spawn: return serverpid child = os.fork() if (not child): if (root and root != '/'): os.chroot (root) os.chdir("/") os.environ["DISPLAY"] = ":9" os.execv("/usr/X11R6/bin/Xtest", ["Xtest", "--nostart", "--norunlevel"]) else: failed = 0 status = -1 try: pid, status = os.waitpid(child, 0) os.kill (serverpid, 15) os.waitpid(serverpid, 0) if not os.WIFEXITED (status) or os.WEXITSTATUS (status): if os.WEXITSTATUS (status) not in [ 0, 1, 2 ]: failed = 1 except OSError: failed = 1 if failed: raise RuntimeError, "X startup failed %d" % (status,) return def Version4Config(self, card, test=0): if not card: raise RuntimeError, "No known video cards" screens = "" maxdepth = -1 xmodes = self.manualModes for depth in xmodes.keys (): if not xmodes[depth]: continue if depth == "32": depth = "24" xmodes["24"] = xmodes["32"] if maxdepth < string.atoi(depth): maxdepth = string.atoi(depth) screens = screens + """ Subsection "Display" Depth %s Modes """ % depth # put in all modes up to selected mode availmodes = self.availableModes() if depth in availmodes.keys(): tmpmodes = availmodes[depth] tmpmodes.reverse() else: tmpmodes = [] for d in xmodes.keys(): for r in xmodes[d]: tmpmodes.append(r) modes = xmodes[depth] modes.sort (self.areaCompare) for res in tmpmodes: if self.areaCompare(res, modes[0]) > -1: screens = screens + '"' + res + '" ' screens = screens + """ EndSubsection """ if depth == "24": del xmodes["24"] # XXX if we're going to be using IMPS/2 on # reboot, but we're using PS/2 now, we'll need # to temporarily use PS/2 so we don't frob the # intellimouse into IMPS/2 mode (if we did, we'll # loose the mouse cursor in the install) if test and self.mouse.info["XMOUSETYPE"] == "IMPS/2": mouseProto = "PS/2" else: mouseProto = self.mouse.info['XMOUSETYPE'] if mouseProto == 'sun': mouseProto = 'BusMouse' if self.mouse.get()[1]: emulate3 = "yes" else: emulate3 = "no" carddata = card.getCardData() monitor = self.monitor # set cardsoptions if unambiguous what version of XFree86 they # apply to cardoptions = " # no known options" if carddata.has_key("DRIVER") and not carddata.has_key("SERVER"): if carddata.has_key("LINE"): cardoptions = carddata["LINE"] # calculate display size so we force dpi in install mode # only works when starting X server in real install environment displaySizeOpts = "" fdpi = self.getForcedDPI() if fdpi and self.res and carddata.has_key("DRIVER"): try: idx = string.find(self.res, 'x') if idx >= 0: reswidth = string.atoi(self.res[:idx]) resheight = string.atoi(self.res[idx+1:]) widthmm = 25.4*reswidth/fdpi heightmm = 25.4*resheight/fdpi log("forcing dpi = %s for mode %sx%s, heightxwidth = %smm by %smm" % (fdpi, reswidth, resheight, widthmm, heightmm)) displaySizeOpts = "DisplaySize %s %s" % (widthmm, heightmm) except: log("failed to force dpi to requested %s" % (fdpi,)) data = { "mouseProto" : mouseProto, "mouseDevice" : self.mouse.device, "cardsOptions" : cardoptions, "cardID" : carddata["NAME"], "cardVendor" : carddata["NAME"], "cardBoardName": carddata["NAME"], "monitorHoriz" : monitor.getMonitorHorizSync(), "monitorVert" : monitor.getMonitorVertSync(), "files" : self.files, "screenModes" : screens, "nonSparcMods" : '\n\tLoad "fbdevhw"', "driMod" : '\n\tLoad "dri"', "XkbRules" : self.keyboard["rules"], "XkbModel" : self.keyboard["model"], "XkbLayout" : self.keyboard["layout"], "XkbVariant" : self.keyboard["variant"], "enableVariant": "#", "XkbOptions" : self.keyboard["options"], "enableOptions": "#", "defaultDepth" : "", "emulate3" : emulate3, "videoRam" : "", "displaySizeOptions" : displaySizeOpts } # self.vidCards[self.primary]["DRIVER"] = "vga" # see if 16 bpp is available, and if it should be the # default depth if self.keyboard["variant"]: data["enableVariant"] = "" if self.keyboard["options"]: data["enableOptions"] = "" if maxdepth > 0: if maxdepth > 16 and '16' in xmodes.keys() and xmodes['16']: data["defaultDepth"] = "\n\tDefaultDepth\t16" else: data["defaultDepth"] = "\n\tDefaultDepth\t%d" % maxdepth if iutil.getArch() == "sparc": data["nonSparcMods"] = "" data["autorepeat"] = '# Option "AutoRepeat" "200 20"' else: data["autorepeat"] = '# Option "AutoRepeat" "500 5"' if carddata.has_key ("DRIVER"): data["cardDriver"] = carddata["DRIVER"] if data["cardDriver"] == "i810": data["videoRam"] = "\tVideoRam %s\n" % card.getVideoRam() # DRI HACK! #if data["cardDriver"] == "r128" or data["cardDriver"] == "mga": # data["driMod"] = '\n\t#Load "dri"' else: raise RuntimeError, "Don't know which XFree86-4.0 video driver to use!" # see if we need to add a section for USB mice which aren't # attached yet. This makes hotplug work if self.mouse and not self.mouse.anyUSBMice(): data["usbmouselayout"] = "InputDevice \"Mouse1\" \"SendCoreEvents\"" data["usbmousesection"] = """ Section "InputDevice" Identifier "Mouse1" Driver "mouse" Option "Device" "/dev/input/mice" Option "Protocol" "IMPS/2" Option "Emulate3Buttons" "no" Option "ZAxisMapping" "4 5" EndSection """ else: data["usbmouselayout"] = "#\n" data["usbmousesection"] = "#\n" return XF86Config_4_template % data if __name__ == "__main__": sys.path.append ("kudzu") x = XF86Config () print x.cards ("ATI Mach64 3D RAGE II") x.probe () print x.Version4Config() sys.exit (0) x.filterModesByMemory () # print self.modes # time.sleep (5) print x.preludeSection () print x.keyboardSection () print x.mouseSection () print x.monitorSection () print x.deviceSection () # x.modes["8"] = [ "640x480" ] # x.modes["16"] = [ "640x480" ] # x.modes["32"] = [ "640x480" ] print x.screenSection ()