Viewing file: xhwstate.py (25.95 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
## xhwstate.py - an XFree86 configuration object ## Copyright (c) 2002-2007 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 monitor import videocard import xf86config import rhpl.translate as translate import ibmasm from rhpl.translate import _, N_ import rhpl import ilomouse
try: import _pyrandr except ImportError: _pyrandr = None
translate.textdomain('rhpxl')
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? # when guessing sync ranges, work backwards from randr mode list
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 else: 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
# Return a tuple of (xres, yres, bits_per_pixel) describing the framebuffer. def fbinfo(): from fcntl import ioctl import struct
FBIOGET_VSCREENINFO = 0x4600
# 160 is from sizeof(struct fb_var_screeninfo) in linux/fb.h fd = os.open("/dev/fb0", os.O_RDONLY) result = ioctl(fd, FBIOGET_VSCREENINFO, 160 * " ")
return struct.unpack('II16xI', result[:28])
# note: this is never called. def get_valid_resolution (xserver): res_supported = False
if not _pyrandr or not _pyrandr.randrAvailable(): return True
# See if the requested resolution is in the list of what xrandr supports. for num in range(0, _pyrandr.getNumRes()): res = _pyrandr.getRes(num) str = "%sx%s" % (res[0], res[1])
if xserver.resolution == str: res_supported = True break
# If not, let's first try 1024x768, and then try 800x600 as a last resort. if not res_supported: xserver.resolution = "1024x768" if not get_valid_resolution(xserver): xserver.resolution = "800x600" get_valid_resolution(xserver)
xserver.setHWState() xserver.hwstate.set_resolution(xserver.resolution)
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 = 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 = videocard.VideoCardInfo() else: self.videocard = defcard
# Init videocard self.colordepth = 24 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.all_resolutions = xf86config.XF86SupportedResolutions() self.config_resolutions = []
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: self.videocard_name = primary.getDescription() self.videocard_driver = None
if primary: mem = primary.getVideoRam() if mem: self.probed_video_ram = string.atoi(mem)
# Set up driver if primary: self.videocard_driver = primary.getDriver()
def init_from_xconfig(self, xconfig): try: screen = xf86config.getPrimaryScreen(xconfig) except xf86config.XF86SectionMissing: screen = None
try: if screen.device: device = xf86config.lookupDevice(xconfig, screen.device) else: device = None except xf86config.XF86SectionMissing: device = None
try: if screen.monitor: monitor = xf86config.lookupMonitor(xconfig, screen.monitor) else: monitor = None except xf86config.XF86SectionMissing: monitor = None 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: # If there is no 'board' comment, use the probed string, as long # as the driver is the same if device.board or device.driver != self.videocard_driver: self.videocard_name = device.board self.video_ram = device.videoram self.videocard_driver = device.driver
# Set up driver options 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)
# If probe fails, get hsync and vsync from MonitorsDB for user # specified monitor from xorg.xonf if self.monitor_name != "Unknown monitor" and \ (monitor.n_hsync == 0 or monitor.n_vrefresh == 0): db = self.monitor.readMonitorsDB() for maker in db.keys(): for mon in db[maker]: if mon[0] == self.monitor_name: self.hsync = mon[3] self.vsync = mon[2]
# Is DRI enabled? if xconfig.modules: for l in xconfig.modules.load: if l.name == "dri": self.dri_enabled = 1 break def merge_into(self, xconfig): screen = xf86config.getPrimaryScreen(xconfig)
screen.defaultdepth = self.colordepth
d = None if screen.display.size(): for i in screen.display: if i.depth == screen.defaultdepth: d = i if d == None: d = xf86config.XF86ConfDisplay() d.depth = screen.defaultdepth screen.display.insert(d)
for i in range(0, d.modes.size()): d.modes.remove(0) if self.config_resolutions != []: for r in self.config_resolutions: m = xf86config.XF86Mode(r) d.modes.insert(m)
device = xf86config.lookupDevice(xconfig, screen.device) 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])) try: if screen.monitor: monitor = xf86config.lookupMonitor(xconfig, screen.monitor) monitor.modelname = 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] else: monitor = None except xf86config.XF86SectionMissing: monitor = None
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 _pyrandr and _pyrandr.randrAvailable(): self.resolution = "%sx%s" % _pyrandr.getRes(_pyrandr.getCurRes())
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, res, change=False): resolution = resolution_from_string(res)
# Don't change the running resolution unless asked to, because we # may not be running X yet. if change: if not _pyrandr or not _pyrandr.randrAvailable(): return
for i in range(_pyrandr.getNumRes()): r = _pyrandr.getRes(i) if r[0] == resolution[0] and r[1] == resolution[1]: _pyrandr.setRes(i) break # Start with an empty list self.config_resolutions = [] # construct the config list here auto = 1 for r in self.available_resolutions(): if compare_resolution(r, res) < 1: self.config_resolutions.append(r) else: auto = 0 if auto == 0: self.config_resolutions.sort(compare_resolution) self.config_resolutions.reverse() else: self.config_resolutions = []
self.resolution = res self.recalc_mode()
def set_colordepth(self, depth): self.colordepth = depth self.recalc_mode()
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_videocard_name(self, name): self.videocard_name = name def set_videocard_driver(self, driver): self.videocard_driver = driver # this is a bit of a hack, but we need to set # UseFBDev on at cards on ppc if rhpl.getArch() == "ppc" and driver in ("radeon", "r128", "ati"): self.videocard_options.append(("UseFBDev", "true")) 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): if self.videocard_name is None: return "Unknown video card" else: 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_hsync(self): return self.hsync def get_vsync(self): return self.vsync
def get_monitor_name(self): if self.monitor_name is None: return "Unknown monitor" else: return self.monitor_name
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): l = [] modes = { 8 : [ "640x480", "800x600" ] }
# yeah, this was a bad idea. if False and _pyrandr and _pyrandr.randrAvailable(): for i in range(0, _pyrandr.getNumRes()): res = "%sx%s" % _pyrandr.getRes(i) found = 0 for item in l: if item == res: found = 1 if not found: l.append(res) l.sort(compare_resolution) modes[8] = l modes[16] = l modes[24] = l return modes
# no RANDR, guess wildly ram = self.get_videocard_ram_or_probed() # If we can't probe, assume at least 32 megs. if ram == 0: ram = 32*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 = monitor.Modes()
# This is a fixed mode monitor whose modes won't make it through our # calculations, so just return the list of what we know it supports. # See #115679, #174052. if self.get_monitor_name() == "SGI 1600SW FlatPanel": return ["800x512", "1600x1024"] availableModes = self.availableModes() l = [] if self.colordepth == 8 and availableModes.has_key(8): l = l + availableModes[8] if (self.colordepth == 15 or self.colordepth == 16) and availableModes.has_key(16): l = l + availableModes[16] if self.colordepth == 24 and availableModes.has_key(24): l = l + availableModes[24]
available = [] for res in unique(l): # This means non-vesa modes are always "supported". Hard to do otherwise. rc = modes.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
# # 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, "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, "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: #Synaptics support baseArch = rhpl.getArch() if baseArch in ("x86_64", "ppc64", "s390x", "sparc64"): libdir = 'lib64' else: libdir = 'lib' modpath = "/usr/%s/xorg/modules/input/synaptics_drv.so" %(libdir,) evdev_modpath = modpath.replace("synaptics", "evdev")
probedMice = mouse.getAllProbed() if probedMice is None: return xconfig
for mouse in probedMice: if mouse.driver == "synaptics" and os.path.exists(modpath): 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 for input_idx,i in enumerate(inputs): for o in i.options: if o.name == "CorePointer": inputs.remove(input_idx)
synaptics_ref = xf86config.XF86ConfInputref("Synaptics", "CorePointer") inputs.insert(synaptics_ref) # RH#492565, see mouse.py for an explanation elif mouse.driver == "evdev" and os.path.exists(evdev_modpath): evdev = xf86config.XF86ConfInput() xconfig.input.insert(evdev) evdev.identifier = mouse.desc evdev.driver = "evdev" get_option(evdev, "Device").val = mouse.device evdev_ref = xf86config.XF86ConfInputref(mouse.desc, "SendCoreEvents") inputs = xconfig.layout[0].inputs inputs.insert(evdev_ref)
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"
## Check for IBM RSA I device and if it exist add the stanza ibmasmhw = ibmasm.ibmasmCheck() if ibmasmhw.isDevicePresent(): ibmasm_conf = xf86config.XF86ConfInput() xconfig.input.insert(ibmasm_conf) ibmasm_conf.identifier = "ibmasm_remote" ibmasm_conf.driver = "ibmasm" get_option(ibmasm_conf, "Device").val = "" (w, h) = string.split (self.resolution, "x") get_option(ibmasm_conf, "XScale").val = w get_option(ibmasm_conf, "YScale").val = h get_option(ibmasm_conf, "SendCoreEvents").val = "True" inputs = xconfig.layout[0].inputs ibmasm_ref = xf86config.XF86ConfInputref("ibmasm_remote", "") inputs.insert(ibmasm_ref)
## Check for HP iLO 2 virtual mouse and if it exists configure evdev ilomousehw = ilomouse.ilomouseCheck() if ilomousehw.isDevicePresent(): print _("Found HP Virtual Mouse") ilomouse_conf = xf86config.XF86ConfInput() xconfig.input.insert(ilomouse_conf) ilomouse_conf.identifier = "ilomouse" ilomouse_conf.driver = "evdev" get_option(ilomouse_conf, "Device").val = "/dev/input/hp_ilo_mouse" get_option(ilomouse_conf, "MinX").val = "0" get_option(ilomouse_conf, "MinY").val = "0" get_option(ilomouse_conf, "MaxX").val = "3000" get_option(ilomouse_conf, "MaxY").val = "3000" get_option(ilomouse_conf, "SendCoreEvents").val = "True" inputs = xconfig.layout[0].inputs ilomouse_ref = xf86config.XF86ConfInputref("ilomouse", "") inputs.insert(ilomouse_ref)
return xconfig
|