Viewing file: xhwstate.py (24.51 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
## xhwstate.py - an XFree86 configuration object ## Copyright (c) 2002 Red Hat, Inc.
## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version.
## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details.
## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import os.path import string import rhpl.arch import rhpl.monitor import rhpl.videocard import xf86config import rhpl.translate as translate from rhpl.translate import _, N_ from rhpl.log import log import rhpl
translate.textdomain('rhpl')
TRUE = 1 FALSE = 0
XF86HW_PROBE_VIDEOCARD = 1 << 1 XF86HW_PROBE_MONITOR = 1 << 2
XF86HW_PROBE_ALL = 0xFFFF XF86HW_PROBE_NONE = 0
# TODO: # probe hsync/vsync seems to give different results than db, which one to trust? # Better way to detect when DRI is available.
def resolution_from_string(res): #Strip out refresh rates if they exist if string.find(res, "@") != -1: res, refresh = string.split(res, "@")
(w, h) = string.split (res, "x") return (string.atoi(w), string.atoi(h))
def resolution_area(res): (w, h) = resolution_from_string(res) return w * h
# X compares modes by width then height # Example 1680x1050 looks smaller than 1600x1200 # to X when parsing the xorg.conf file def compare_resolution(res1, res2): (w1, h1) = resolution_from_string(res1) (w2, h2) = resolution_from_string(res2)
if w1 < w2: return -1 elif w1 == w2: if h1 < h2: return -1 elif h1 == h2: return 0 elif h1 > h2: return -1 return 1
def ranges_to_string(array, len): str = "" for i in range(len): r = array[i] if str != "": str = str + "," if r[0] == r[1]: str = str + repr(r[0]) else: str = str + repr(r[0]) + "-" + repr(r[1]) return str
def string_to_ranges(str): l = [] pieces = string.split(str, ",") for piece in pieces: tmp = string.split(piece, "-") if len(tmp) == 1: l.append( (string.atof(tmp[0]), string.atof(tmp[0])) ) else: l.append( (string.atof(tmp[0]), string.atof(tmp[1])) ) return l
def dpi_string(resolution, physical_width, physical_height): if physical_width == 0 or physical_height == 0: return _("Unknown") (w,h) = resolution_from_string(resolution) dpix = int(round(w * 25.4/physical_width)) dpiy = int(round(h * 25.4/physical_height)) return _("%d by %d dots per inch")%(dpix, dpiy)
class XF86HardwareState: # # setup representation of X related hardware # # Probe flags determine what we are allowed to look for # # If hw object passed in as None it is probed, according to probe flags # # If xconfig is passed it is replaces probed data # def __init__(self, xconfig=None, defcard=None, defmon=None, probeflags=XF86HW_PROBE_ALL, verbose = 0): self.monitor = None self.xconfig = xconfig if defmon is None and probeflags & XF86HW_PROBE_MONITOR: if verbose: print _("Probing monitor") self.monitor = rhpl.monitor.MonitorInfo() else: self.monitor = defmon
self.videocard = None if defcard is None and probeflags & XF86HW_PROBE_VIDEOCARD: if verbose: print _("Probing videocard") self.videocard = rhpl.videocard.VideoCardInfo() else: self.videocard = defcard
# Init videocard self.colordepth = 16 self.resolution = "800x600" self.video_ram = 0 self.probed_video_ram = 0 self.videocard_options = [] self.dri_enabled = 0 self.videocard_name = None self.videocard_PCIBus = None self.videocard_PCIDev = None self.videocard_PCIFn = None self.monitor_name = None self.hsync = None self.vsync = None self.physical_width = 0 self.physical_height = 0 self.probed_hsync = None self.probed_vsync = None self.probed_physical_width = 0 self.probed_physical_height = 0
self.all_resolutions = xf86config.XF86SupportedResolutions()
self.init_from_probed()
if xconfig: self.init_from_xconfig(xconfig)
# Handle completely unset things: if self.videocard_name == None: self.videocard_name = "Unknown video card" if self.videocard_driver == None: self.videocard_driver = "vga"
# Default to: Generic Extended Super VGA H: 31.5-37.9 V: 50-70 if self.hsync == None: self.hsync = "31.5-37.9" if self.vsync == None: self.vsync = "50-70" if self.monitor_name == None: self.monitor_name = "Unknown monitor" def tokenize_line(self, line): list = [] current = ""
in_quote = 0 for c in line: if in_quote: if c == '"': in_quote = 0 list.append(current) current = "" else: current = current + c else: if c =='"': if len(current) > 0: list.append(current) current = "" in_quote = 1 elif c == "#": break elif c in string.whitespace: if len(current) > 0: list.append(current) current = "" else: current = current + c if len(current) > 0: list.append(current) return list
def parse_lines(self, lines): for line in string.split(lines, "\n"): items = self.tokenize_line(line) if len(items) > 1 and string.upper(items[0]) == "OPTION": name = items[1] if len(items) > 2: val = items[2] else: val = "" self.videocard_options.append( (name, val) ) def init_from_probed(self): primary = None if self.videocard: primary = self.videocard.primaryCard()
# Set up videocard name if primary != None: devid = primary.getDevID() if devid != None: self.videocard_name = devid self.videocard_driver = None
if primary: mem = primary.getVideoRam() if mem: self.probed_video_ram = string.atoi(mem)
# Set up driver if primary: carddata = primary.getCardData() if carddata: if carddata.has_key("DRIVER"): self.videocard_driver = carddata["DRIVER"]
# Add options if any, these are overridden # if there are other options in the x config if carddata.has_key("LINE"): lines = carddata["LINE"] self.parse_lines(lines)
if self.monitor: name = self.monitor.getMonitorName() if name != None and (self.monitor_name == None or self.monitor_name == "Monitor Model"): self.monitor_name = name
self.probed_hsync = self.monitor.getMonitorHorizSync(TRUE) self.probed_vsync = self.monitor.getMonitorVertSync(TRUE)
self.probed_physical_width = self.monitor.getMonitorPhysicalWidth() self.probed_physical_height = self.monitor.getMonitorPhysicalHeight() self.hsync = self.monitor.getMonitorHorizSync(FALSE) self.vsync = self.monitor.getMonitorVertSync(FALSE)
self.physical_width = self.probed_physical_width self.physical_height = self.probed_physical_height
#Load DRI extensions on all i386, x86_64, and ia64 systems if rhpl.getArch() in ("i386", "x86_64", "ia64"): self.dri_enabled = 1
def init_from_xconfig(self, xconfig): screen = xf86config.getPrimaryScreen(xconfig) device = xf86config.lookupDevice(xconfig, screen.device) monitor = xf86config.lookupMonitor(xconfig, screen.monitor) if screen: self.colordepth = screen.defaultdepth for d in screen.display: if d.depth == self.colordepth: try: self.resolution = d.modes[0].name except: #There's no specified modes. Let's create one and default to 800x600 d.modes.insert(xf86config.XF86Mode("800x600")) self.resolution = "800x600" break
if screen: for d in screen.display: for mode in d.modes: res = mode.name if res != None and res not in self.all_resolutions: self.all_resolutions.append(res) self.all_resolutions.sort (compare_resolution)
if device: self.videocard_name = device.board
if device: self.video_ram = device.videoram
if device != None: self.videocard_driver = device.driver
# Set up driver options if device != None: if len(device.options): # Override the probed values self.videocard_options = [] for option in device.options: self.videocard_options.append( (option.name, option.val) )
if monitor != None: self.monitor_name = monitor.modelname if monitor.n_hsync > 0: self.hsync = ranges_to_string(monitor.hsync, monitor.n_hsync) if monitor.n_vrefresh > 0: self.vsync = ranges_to_string(monitor.vrefresh, monitor.n_vrefresh) self.physical_width = monitor.width self.physical_height = monitor.height
# Is DRI enabled? for l in xconfig.modules.load: if l.name == "dri": self.dri_enabled = 1 break def merge_into(self, xconfig): screen = xf86config.getPrimaryScreen(xconfig)
#TODO: Handle no screen?
screen.defaultdepth = self.colordepth
display = None for d in screen.display: if d.depth == self.colordepth: display = d break
# Do we need to add a subsection for the current depth? if display == None: display = xf86config.XF86ConfDisplay() display.depth = self.colordepth screen.display.insert(display)
while len(display.modes) > 0: display.modes.remove(0) display.modes.insert(xf86config.XF86Mode(self.resolution)) # Add all other available resolutions too. available = self.available_resolutions() r = -1 for i in range(0, len(available)): if compare_resolution (available[i], self.resolution) >= 0: r = i - 1 break
for i in range (r, -1, -1): display.modes.insert(xf86config.XF86Mode(available[i]))
device = xf86config.lookupDevice(xconfig, screen.device) #TODO: Handle no device
device.board = self.videocard_name # # this causes problems so we don't override videoram # # device.videoram = self.video_ram
device.driver = self.videocard_driver
while len(device.options) > 0: device.options.remove(0) for option in self.videocard_options: device.options.insert(xf86config.XF86Option(option[0], option[1]))
monitor = xf86config.lookupMonitor(xconfig, screen.monitor) #TODO: Handle no monitor
# need to remove double quotes (bugzilla #103353) or else we # write out a bad line for ModelName in X config file monitor.modelname = string.replace(self.monitor_name, '"', '') hsync = string_to_ranges(self.hsync) monitor.n_hsync = len(hsync) for i in range(len(hsync)): monitor.hsync[i] = hsync[i]
vsync = string_to_ranges(self.vsync) monitor.n_vrefresh = len(vsync) for i in range(len(vsync)): monitor.vrefresh[i] = vsync[i]
monitor.width = int(round(self.physical_width)) monitor.height = int(round(self.physical_height))
if self.dri_enabled: self.add_module(xconfig,"dri") else: self.remove_module(xconfig,"dri")
def add_module(self, xconfig, moduleName): self.remove_module(xconfig, moduleName) xconfig.modules.load.insert(xf86config.XF86ConfLoad(moduleName))
def remove_module(self, xconfig, moduleName): for i in range(len(xconfig.modules.load)): if xconfig.modules.load[i].name == moduleName: xconfig.modules.load.remove(i) break def recalc_mode(self): availableRes = self.available_resolutions()
if self.resolution not in availableRes: self.resolution = availableRes[-1] availableDepth = self.available_color_depths() if self.colordepth not in availableDepth: self.colordepth = availableDepth[-1]
def set_resolution(self, resolution): self.resolution = resolution self.recalc_mode()
def set_colordepth(self, depth): self.colordepth = depth self.recalc_mode()
def set_dri_enabled(self, enabled): self.dri_enabled = enabled
def set_monitor_name(self, name): self.monitor_name = name
def set_hsync(self, hsync): self.hsync = hsync
def set_vsync(self, vsync): self.vsync = vsync
def set_physical_size(self, w, h): self.physical_width = w self.physical_height = h def set_videocard_name(self, name): self.videocard_name = name def set_videocard_driver(self, driver): self.videocard_driver = driver def set_videocard_card(self, card): try: foo = rhpl.videocard.Video_cardsDBLookup(card) if foo: if foo.has_key('DRIVER'): self.videocard_driver = foo['DRIVER']
# this is a bit of a hack, but we need to set # UseFBDev on ati cards on ppc if rhpl.getArch() == "ppc" and \ foo['DRIVER'] in ("radeon", "r128", "ati"): self.videocard_options.append(("UseFBDev", "true")) if foo.has_key("LINE"): lines = foo["LINE"] self.parse_lines(lines) except Exception, e: pass def set_videocard_ram(self, ram): self.video_ram = ram def set_videocard_options(self, options): self.videocard_options = options
def set_videocard_PCIBus(self, num): self.videocard_PCIBus = num
def set_videocard_PCIDev(self, num): self.videocard_PCIDev = num
def set_videocard_PCIFn(self, num): self.videocard_PCIFn = num def get_resolution(self): return self.resolution
def get_colordepth(self): return self.colordepth
def get_videocard_name(self): return self.videocard_name def get_videocard_driver(self): return self.videocard_driver def get_videocard_ram(self): return self.video_ram def get_videocard_ram_or_probed(self): if self.video_ram == 0: return self.probed_video_ram return self.video_ram
def get_videocard_PCIBus(self): return self.videocard_PCIBus
def get_videocard_PCIDev(self): return self.videocard_PCIDev
def get_videocard_PCIFn(self): return self.videocard_PCIFn
def get_all_resolutions(self): return self.all_resolutions def get_hsync(self): return self.hsync def get_hsync_or_probed(self): if self.hsync == None: return self.probed_hsync return self.hsync def get_vsync(self): return self.vsync def get_vsync_or_probed(self): if self.vsync == None: return self.probed_vsync return self.vsync def get_physical_size(self): return (self.physical_width, self.physical_height)
def get_physical_size_or_probed(self): if self.physical_width == 0 or self.physical_height == 0: return (self.probed_physical_width, self.probed_physical_height) return (self.physical_width, self.physical_height)
def get_monitor_name(self): return self.monitor_name
def get_dri_enabled(self): return self.dri_enabled
def get_videocard_options(self): return self.videocard_options
def get_xconfig(self): return self.xconfig
# based on available ram, guess which resolutions card can support # based on simple calculation of ram required to store all pixels at # the given depth. Does not actually know if videocard can do that # resolution (due to ramdac limitations, for exampel) def availableModes(self): modes = { 8 : [ "640x480", "800x600" ] }
ram = self.get_videocard_ram_or_probed() # If we can't probe, assume at least 8 megs. if ram == 0: ram = 8*1024
modes[8] = filter (lambda res: resolution_area(res)*1 <= ram*1024, self.all_resolutions) modes[16] = filter (lambda res: resolution_area(res)*2 <= ram*1024, self.all_resolutions) modes[24] = filter (lambda res: resolution_area(res)*4 <= ram*1024, self.all_resolutions)
return modes
# # returns list of modes filtered by what we think the monitor can # reasonably support # def available_resolutions(self): def unique(s): if len(s) == 0: return [] u = {} for x in s: u[x] = 1 return u.keys()
global monitor modes = self.availableModes() l = [] if self.colordepth == 8 and modes.has_key(8): l = l + modes[8] if (self.colordepth == 15 or self.colordepth == 16) and modes.has_key(16): l = l + modes[16] if self.colordepth == 24 and modes.has_key(24): l = l + modes[24]
available = [] for res in unique(l): # This means non-vesa modes are always "supported". Hard to do otherwise. rc = rhpl.monitor.monitor_supports_mode(self.hsync, self.vsync, res) if rc == 1: available.append(res)
available.sort(compare_resolution)
# Need a fallback if len(available) == 0: available = ["640x480"] return available
# # returns available color depths for currently selected resolution # def available_color_depths(self): modes = self.availableModes() l = [] if modes.has_key(8) and self.resolution in modes[8]: l.append(8) if modes.has_key(16) and self.resolution in modes[16]: l.append(16) if modes.has_key(24) and self.resolution in modes[24]: l.append(24) l.sort() return l
# # try to determine a sane default for given hwstate # def choose_sane_default(self): modes = self.availableModes()
# start at largest depth and work down to find desired resolution depths = modes.keys() depths.sort() depths.reverse()
# XXX this is lame, but some drivers fare poorly with # 24bpp (#105713) driver = self.get_videocard_driver() if driver in ("s3", "s3virge", "neomagic", "i128", "vmware"): if 24 in depths: depths.remove(24) desired_res = "1024x768" for d in depths: if modes.has_key(d) and desired_res in modes[d]: self.set_resolution(desired_res) self.set_colordepth(d) return
# XXX couldnt find what we wanted, punt for now return
def supports_dri(self): #TODO: This check is lame: driver = self.get_videocard_driver() if driver in ["i810", "glint", "tdfx", "r128", "mga", "radeon", "sis"]: return 1 return 0
# # given a hardware state and a mouse and kbd spec, return X config file # def generate_xconfig(self, mouse, keyboard): xconfig = xf86config.createTemplate()
self.merge_into(xconfig)
def get_option(device, optionname): res = filter (lambda o: o.name == optionname, device.options) if len (res) > 0: return res[0] else: option = xf86config.XF86Option(optionname) device.options.insert(option) return option
corekb = xf86config.getCoreKeyboard(xconfig)
try: #Let's assume we know what kind of keyboard this is # get_option(corekb, "XkbRules").val = keyboard["rules"] get_option(corekb, "XkbModel").val = keyboard["model"] get_option(corekb, "XkbLayout").val = keyboard["layout"] except: #Ok, the keyboard from /etc/sysconfig/keyboard isn't in rhpl's list, so let's assume US keyboard #Maybe this isn't the best thing to do, but it will work for most people keyboard.set("us") # get_option(corekb, "XkbRules").val = keyboard["rules"] get_option(corekb, "XkbModel").val = keyboard["model"] get_option(corekb, "XkbLayout").val = keyboard["layout"]
if keyboard["options"] != "": get_option(corekb, "XkbOptions").val = keyboard["options"] if keyboard["variant"] != "": get_option(corekb, "XkbVariant").val = keyboard["variant"]
# if no mouse defined then skip if mouse.getDevice() is not None: corepointer = xf86config.getCorePointer(xconfig)
#Let's default everything to /dev/input/mice and emulate 3 button get_option(corepointer, "Protocol").val = "IMPS/2" get_option(corepointer, "Device").val = "/dev/input/mice" get_option(corepointer, "Emulate3Buttons").val = "yes"
#Synaptics support modpath = "/usr/X11R6/lib/modules/input/synaptics_drv.o" basearch = rhpl.arch.getBaseArch() if basearch == "x86_64": modpath = "/usr/X11R6/lib64/modules/input/synaptics_drv.o" for mouse in mouse.getAllProbed(): if mouse.driver == "synaptics" and os.path.exists(modpath): self.add_module(xconfig,"synaptics") synaptics = xf86config.XF86ConfInput() xconfig.input.insert(synaptics) synaptics.identifier = "Synaptics" synaptics.driver = "synaptics" get_option(synaptics, "Device").val = "/dev/input/mice" get_option(synaptics, "Protocol").val = "auto-dev" get_option(synaptics, "Emulate3Buttons").val = "yes" if mouse.desc.find("ALPS") != -1 : get_option(synaptics, "LeftEdge").val = "120" get_option(synaptics, "RightEdge").val = "830" get_option(synaptics, "TopEdge").val = "120" get_option(synaptics, "BottomEdge").val = "650" get_option(synaptics, "FingerLow").val = "14" get_option(synaptics, "FingerHigh").val = "15" get_option(synaptics, "MaxTapMove").val = "110" get_option(synaptics, "VertScrollDelta").val = "20" get_option(synaptics, "HorizScrollDelta").val = "20" get_option(synaptics, "MinSpeed").val = "0.3" get_option(synaptics, "MaxSpeed").val = "0.75"
inputs = xconfig.layout[0].inputs synaptics_ref = xf86config.XF86ConfInputref("Synaptics", "AlwaysCore") inputs.insert(synaptics_ref) ##We're going to try supporting only PS/2 and USB mice for FC2 test 2. ##We can turn this back on later if necessary ## type = mouse.info["XMOUSETYPE"] ## type = "PS/2" # No idea, Guess PS/2 ## get_option(corepointer, "Protocol").val = type ## get_option(corepointer, "Device").val = "/dev/" + mouse.getDevice() ## (typename, emu3) = mouse.get() ## val = "no" ## if emu3: ## val = "yes" ## get_option(corepointer, "Emulate3Buttons").val = val
## if mouse.getDevice() == "input/mice": ## inputs = xconfig.layout[0].inputs ## for i in range(len(inputs)): ## if inputs[i].inputdev == "DevInputMice": ## inputs.remove(i) ## break else: # turn on flags to allow X server to run even if no mouse present if xconfig.flags is None: xconfig.flags = xf86config.XF86ConfFlags() get_option(xconfig.flags, "AllowMouseOpenFail").val = "yes" return xconfig
|