diff --git a/ChangeLog b/ChangeLog index bdcec67..39477f9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,5 @@ +- Remove thoroughly obsolete displayconfig tool + - Handle "ain't got no cpufreq" more gracefully (Malone bug # 99198) - Fix typo in mountconfig that lead to a crash (Malone bug # 87861) - BUG: Fix detection of the nvidia proprietary driver (Malone bug #104860) diff --git a/MANIFEST.in b/MANIFEST.in index b1b40ad..d8afa81 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -8,14 +8,3 @@ prune package/mandrake/.svn include README COPYING ChangeLog MANIFEST.in TODO global-include *.desktop *.py *.pot *.po *.ui global-exclude *~ .svn -include displayconfig/40guidance-displayconfig_restore -include displayconfig/vesamodes -include displayconfig/extramodes -include displayconfig/widescreenmodes -include displayconfig/ldetect-lst/Cards+ -include displayconfig/ldetect-lst/MonitorsDB -include displayconfig/ldetect-lst/pcitable -exclude displayconfig/test.py -exclude displayconfig/xconfig-test.py -exclude displayconfig/popentest.py -exclude displayconfig/guidance_bug_reporter.py diff --git a/README b/README index 73a6748..e16d435 100644 --- a/README +++ b/README @@ -47,9 +47,6 @@ have only been tested on Mandrake. * mountconfig - Mount point configuration utility. Feature complete and stable. -* displayconfig - Display and graphics card configuration utility. Feature - complete but it only tested on Kubuntu right now. - * wineconfig - Wine configuration utility. * grubconfig - Grub boot loader configuration utility. beta quality now. @@ -115,46 +112,15 @@ This will test for a working installation of PyQt/PyKDE and automatically install the files using the same installation prefix as TDE. You will need to have a working Python install before you can even run the setup.py script. -displayconfig-hwprobe installation ----------------------------------- -displayconfig-hwprobe.py is a small program that should be run at boottime -before Xorg is started. It scans the PCI bus looking for graphics cards and -compares the list it finds to the previous time it was run. If the two lists -of hardware are different then "dpkg-reconfigure xserver-xorg" is automatically -run in non-interactive mode to generate a new xorg.conf based on the new -hardware. - -The philosophy is that it is better to have a system with a raw but working -xorg.conf and X server, than to keep the old configuration and a Xorg that -won't startup. Swapping a graphics card should not "break" the OS. - -The setup.py script currently does not install displayconfig-hwprobe.py by -itself. For now this must be done by the packager. displayconfig-hwprobe.py -should be put in /etc/init.d and installed to run at boot time with a command -like this: - - update-rc.d displayconfig-hwprobe.py start 18 3 . - -displayconfig-hwprobe.py only supports Kubuntu right now. Perhaps in the -future displayconfig-hwprobe will be expanded to detect hardware and generate -an xorg.conf by itself. - -More information about displayconfig-hwprobe.py and the files it uses is -inside displayconfig-hwprobe.py. Currently the hardware data is written to -/var/lib/guidance/guidance-gfxhardware-snapshot. IMPORTANT: The directory -/var/lib/guidance/ should be created before using displayconfig-hwprobe.py. - - Running ------- Installation should add a couple of entries to the Trinity Control Center in the -System section (displayconfig will show up in Peripherals). It is also possible +System section. It is also possible to run the commands outside of the Trinity Control Center from the shell as root: * serviceconfig * userconfig * mountconfig - * displayconfig * wineconfig * grubconfig diff --git a/TODO b/TODO index 4124684..05901e1 100644 --- a/TODO +++ b/TODO @@ -61,11 +61,6 @@ mountconfig This is stand on Mandriva 2005. * Implement "real" HAL backend. -displayconfig -~~~~~~~~~~~~~ -* Use HAL for fetching PCI and card info? alongside existing systems (ldetect)? - - Extra? ~~~~~~ @@ -260,33 +255,6 @@ calling a drakxtools) ---------------------------------------------------------------------------- -List of hardware probing tools to use for displayconfig: --------------------------------------------------------- - - -[1] xvinfo - Print out X-Video extension adaptor information - - xvinfo prints out the capabilities of any video adaptors - associated with the display - that are accesible through the X-Video extension. - -[2] xresprobe - Prints out resolutions, frequency and displaytype. - Doesn't work in all cases. Works via ddc, I guess. - -[3] ddcprobe - Uses VESA BIOS Extension - Detects VGA + OEM, modes (only set up modes?), vid mem (kudzu) - -[3] read-edid - get-edid|parse-edid prints out a "good-looking" Monitor Section for - xorg.conf, not reliable (failed on notebook) - -[4] ddcxinfo - prints out modelines, hsync and vsync (kudzu) - -[5] svgamodes - prints out supported video modes (kudzu) - - - - -- Pixel programming languages addict http://merd.net/pixel/language-study/ diff --git a/displayconfig/40guidance-displayconfig_restore b/displayconfig/40guidance-displayconfig_restore deleted file mode 100644 index 0f8ae9c..0000000 --- a/displayconfig/40guidance-displayconfig_restore +++ /dev/null @@ -1,11 +0,0 @@ -# Set the X server resolution to that selected by the user. -# -# This needs to be done before windows managers or X clients start, -# otherwise the DPI and fonts sizes get all screwed up. -# -# http://www.simonzone.com/software/guidance -# -# This file is sourced by Xsession(5), not executed. -# The "|| true" is to ensure that the Xsession script does not terminate -# and stop the login if something fails in the Python program. -/opt/trinity/bin/displayconfig-restore || true diff --git a/displayconfig/ScanPCI.py b/displayconfig/ScanPCI.py deleted file mode 100644 index 031a4e9..0000000 --- a/displayconfig/ScanPCI.py +++ /dev/null @@ -1,340 +0,0 @@ -########################################################################### -# ScanPCI.py - # -# ------------------------------ # -# copyright : (C) 2005 by Simon Edwards # -# email : simon@simonzone.com # -# # -########################################################################### -# # -# 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. # -# # -########################################################################### -"""Provides information about the devices attached to the PCI bus. -""" -import struct -import csv -import os.path -import sys - -########################################################################### -class PCIDevice(object): - def __init__(self,line=None): - self.vendor = None # PCI vendor id - self.device = None - - self.subvendor = None # 0xffff if not probe_type'd or no subid - self.subdevice = None # 0xffff if not probe_type'd or no subid - self.pci_class = None # 'None' if not probe_type'd - - self.pci_bus = None # pci bus id 8 bits wide - self.pci_device = None # pci device id 5 bits wide - self.pci_function = None# pci function id 3 bits wide - - self.module = None - self.text = None - self.already_found = False - - if line is not None: - self.loadFromString(line) - - def isGfxCard(self): - if self.module is not None and \ - (self.module.startswith("Card:") or self.module.startswith("Server:XFree86(")): - return True - - return (self.pci_class & PCIBus.PCI_BASE_CLASS_MASK)==PCIBus.PCI_BASE_CLASS_DISPLAY - - def getModule(self): - if self.module is not None: - if self.module.startswith("Server:XFree86("): - return self.module[15:-1] - elif self.module.startswith("Card:"): - return self.module[5:] - return self.module - - def isModuleXorgDriver(self): - return self.module is not None and \ - (self.module.startswith("Server:XFree86(") or self.module.startswith("Card:")) - - def __str__(self): - s = "PCI:%i:%i:%i, " % (self.pci_bus,self.pci_device,self.pci_function) - s += "Vendor:%x, Device:%x," % (self.vendor,self.device) - if self.subvendor is not None: - s += " Subvendor:%x," % self.subvendor - if self.subdevice is not None: - s += " Subdevice:%x," % self.subdevice - if self.pci_class is not None: - s += " Class:%x," % self.pci_class - if self.module is not None: - s += " Module:%s," % self.module - if self.text is not None: - s += " Text:%s" % self.text - return s - - def loadFromString(self,line): - parts = line.split(",") - for i in range(len(parts)): - bit = parts[i].strip() - if bit.startswith("PCI:"): - pci_code = bit[4:].split(":") - self.pci_bus = int(pci_code[0]) - self.pci_device = int(pci_code[1]) - self.pci_function = int(pci_code[2]) - elif bit.startswith("Vendor:"): - self.vendor = int(bit[7:],16) - elif bit.startswith("Device:"): - self.device = int(bit[7:],16) - elif bit.startswith("Subvendor:"): - self.subvendor = int(bit[10:],16) - elif bit.startswith("Subdevice:"): - self.subdevice = int(bit[10:],16) - elif bit.startswith("Class:"): - self.pci_class = int(bit[6:],16) - elif bit.startswith("Module:"): - self.module = bit[7:] - elif bit.startswith("Text:"): - self.text = " ".join(parts[i:]).strip()[5:] - break - -############################################################################ -class PCIBus(object): - PCI_CLASS_SERIAL_USB = 0x0c03 - PCI_CLASS_SERIAL_FIREWIRE = 0x0c00 - PCI_BASE_CLASS_MASK = 0xff00 - PCI_BASE_CLASS_DISPLAY = 0x0300 - - def __init__(self, data_file_dir="."): - self.devices = [] - self.data_file_dir = data_file_dir - - def detect(self,device_data="/proc/bus/pci/devices"): - # Shamelessly translated from ldetect's pci.c. - fhandle = open(device_data) - for line in fhandle.readlines(): - #print "L:",line - entry = PCIDevice() - self.devices.append(entry) - parts = line.split() - - devbusfn = int(parts[0],16) - idbits = int(parts[1],16) - entry.vendor = idbits >> 16 - entry.device = idbits & 0xffff - entry.pci_bus = devbusfn >> 8 - entry.pci_device = (devbusfn & 0xff) >> 3 - entry.pci_function = (devbusfn & 0xff) & 0x07 - - try: - infohandle = open("/proc/bus/pci/%02x/%02x.%d" % ( - entry.pci_bus, entry.pci_device, entry.pci_function),"r") - # these files are 256 bytes but we only need first 48 bytes - buf = infohandle.read(48) - (class_prog, entry.pci_class, entry.subvendor, entry.subdevice) = \ - struct.unpack("= 1 and row[0] != '': - # Skip manufacturer info lines. - continue - - vendor = int(row[1][:4],16) - device = int(row[1][4:],16) - module = row[3] - text = ' '.join(row[4:]).strip() - - i = 0 - while i1: - if sys.argv[1]=="--help" or sys.argv[1]=="-h": - print "Usage:\n ScanPCI.py " - sys.exit(0) - bus.detect(sys.argv[1]) - else: - bus.detect() - print bus - -if __name__=='__main__': - main() diff --git a/displayconfig/displayconfig-hwprobe.py b/displayconfig/displayconfig-hwprobe.py deleted file mode 100755 index 7ba5c69..0000000 --- a/displayconfig/displayconfig-hwprobe.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/python -########################################################################### -# displayconfig-hwprobe.py - description # -# ------------------------------ # -# begin : Sun Jan 22 2006 # -# copyright : (C) 2006 by Simon Edwards # -# email : simon@simonzone.com # -# # -########################################################################### -# # -# 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 should be run during boot time. It quickly examines the -# graphics cards (read: PCI devices) in the computer and compares they to -# the list in the file $hardware_info_filename. If the two lists differ -# then the Debian package manager is automatically called to regenerate -# /etc/X11/xorg.conf. This hopefully should mean that people can swap gfx -# cards in and out and always have a system that will run Xorg. (even -# though the config will be most likely be suboptimal. Suboptimal is better -# than no X server). - -import ScanPCI -import os -import syslog -import select - -hardware_info_filename = "/var/lib/guidance/guidance-gfxhardware-snapshot" -data_file_dir = "/usr/share/apps/guidance/" - -def main(): - # Scan the PCI bus. - pci_bus = ScanPCI.PCIBus(data_file_dir) - pci_bus.detect() - - # Stuff our device info in to a string. - hardware_config = "" - for pci_device in pci_bus.devices: - if pci_device.isGfxCard(): - hardware_config += "PCI:%i:%i:%i Vendor:%x Device:%x Subvendor:%x Subdevice:%x\n" % \ - (pci_device.pci_bus, pci_device.pci_device, pci_device.pci_function, - pci_device.vendor, pci_device.device, - pci_device.subvendor, pci_device.subdevice) - - # Read in the old gfx hardware info in. - previous_hardware = None - try: - fhandle = open(hardware_info_filename) - previous_hardware = fhandle.read() - fhandle.close() - except IOError: - previous_hardware = None - - if previous_hardware is not None and previous_hardware!=hardware_config: - # Run dpkg and configure the new hardware. - syslog.syslog(syslog.LOG_INFO, "Graphics card hardware has changed. Reconfiguring xorg.conf using 'dpkg-reconfigure xserver-xorg'.") - cmd = ['dpkg-reconfigure','xserver-xorg'] - environ = os.environ.copy() - environ['DEBIAN_FRONTEND'] = 'noninteractive' - #os.spawnvpe(os.P_WAIT, 'dpkg-reconfigure', cmd, environ) - result = ExecWithCapture('/usr/sbin/dpkg-reconfigure', cmd, 0, '/', 0,1, -1, environ) - for line in result.split('\n'): - syslog.syslog(syslog.LOG_INFO,"dpkg-reconfigure:"+line) - - # [21:18] you are brave indeed - # [21:21] I figured some kind of non-interactive "dpkg-reconfigure xorg" might be enough. - # [21:22] yep - - if previous_hardware is None or previous_hardware!=hardware_config: - syslog.syslog(syslog.LOG_INFO, "Writing graphics card hardware list to "+hardware_info_filename) - # Write out the gfx hardware info - tmp_filename = hardware_info_filename + ".tmp" - fhandle = open(tmp_filename,'w') - fhandle.write(hardware_config) - fhandle.close() - os.rename(tmp_filename, hardware_info_filename) - - -############################################################################ -def ExecWithCapture(command, argv, searchPath = 0, root = '/', stdin = 0, - catchfd = 1, closefd = -1, environ = None): - - if not os.access(root + command, os.X_OK) and not searchPath: - raise RuntimeError, command + " can not be run" - - (read, write) = os.pipe() - childpid = os.fork() - if (not childpid): - if (root and root != '/'): os.chroot(root) - os.dup2(write, catchfd) - os.close(write) - os.close(read) - - if closefd != -1: - os.close(closefd) - if stdin: - os.dup2(stdin, 0) - os.close(stdin) - - # Replace the environment - if environ is not None: - os.environ.clear() - os.environ.update(environ) - - if searchPath: - os.execvp(command, argv) - else: - os.execv(command, argv) - sys.exit(1) - os.close(write) - - rc = "" - s = "1" - while s: - select.select([read], [], []) - s = os.read(read, 1000) - rc = rc + s - - os.close(read) - - try: - os.waitpid(childpid, 0) - except OSError, (errno, msg): - print __name__, "waitpid:", msg - - return rc - -main() diff --git a/displayconfig/displayconfig-restore.py b/displayconfig/displayconfig-restore.py deleted file mode 100755 index e4665bc..0000000 --- a/displayconfig/displayconfig-restore.py +++ /dev/null @@ -1,324 +0,0 @@ -#!/usr/bin/python -########################################################################### -# displayconfig-restore.py - description # -# ------------------------------ # -# begin : Wed Dec 15 2004 # -# copyright : (C) 2004-2006 by Simon Edwards # -# email : simon@simonzone.com # -# # -########################################################################### -# # -# 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. # -# # -########################################################################### -import os -import os.path -import subprocess -import ixf86misc -import xf86misc - -from execwithcapture import * - -############################################################################ -def FindXorgConfig(self): - # Lookup location of X configfile - for line in ExecWithCapture("xset", ["xset","q"],True).split('\n'): - if line.strip().startswith("Config file"): - return line.split(":")[1].strip() - # Sometimes, xset doesn't know about the configfile location, hence ... - if os.path.isfile("/etc/X11/xorg.conf"): - return "/etc/X11/xorg.conf" - return None - -############################################################################ -# FixXorgDPI -# ========== -# The idea here is to ensure that applications use a sensible DPI setting -# for fonts. When Xorg starts up it tries to detect the size of the attached -# monitor and calculate the real DPI from there and use that. Problems are: -# -# * if the monitor size can not be detect then Xorg uses 75dpi. This is -# usually far too low. -# -# * if the monitor size is not accurately detected then you get bad a DPI. -# -# * most fonts are optimised to work at a handful of standard DPIs. 96dpi, -# 120dpi and printer resolution 300dpi and 600dpi. Fonts rendered in -# non-standard DPIs often look bad and jagged. This is a real problem -# when rendering fonts on low resolution devices. (i.e. a computer -# monitor). -# -# Although it is desirable in theory to use the real DPI of the monitor, in -# practice it is more important to ensure that fonts are well rendered even -# if the DPI in use is not correct. -# -# What this function does is read the display size from the X server and -# if it is lower than 140dpi then 'round' it to either 96dpi or 120dpi. -# (A dpi greater or equal to 140 is assumed to be high enough to render fonts -# well.) The new dpi is then loaded with the xrdb command into the X server -# resource database. Most X applications (Qt and GTK apps at least) will then -# use this DPI for font rendering. -# -def FixXorgDPI(desiredDPI): - # dpi is: - # None - round the DPI. - # xserver - Use the X server's DPI. - # - DPI to use. - if desiredDPI=="xserver": - return - - dpi = 96 - try: - if desiredDPI is not None: - dpi = int(desiredDPI) - except ValueError: - desiredDPI = None - - if desiredDPI is None: - xserver = xf86misc.XF86Server() - if len(xserver.getScreens())!=0: - (width,height,width_mm,height_mm) = xserver.getScreens()[0].getDimensions() - if not float(width_mm) == 0: - w_dpi = float(width)/(float(width_mm)/25.4) - else: - w_dpi = 96 - if not float(height_mm) == 0: - h_dpi = float(height)/(float(height_mm)/25.4) - else: - h_dpi = 96 - dpi = (w_dpi+h_dpi)/2.0 # Average the two possible DPIs. - - if dpi >= 140: # Anything above 140 is ok. - dpi = int(dpi) - else: - if abs(96-dpi) < abs(120-dpi): # Rounding to 96 is best. - dpi = 96 - else: - dpi = 120 - - # work around for LP beastie 151311 - if ((w_dpi < 200) and (h_dpi > 900)): - dpi = 96 - - try: - xrdb = subprocess.Popen(["xrdb","-nocpp","-merge"],stdin=subprocess.PIPE) - xrdb.communicate("Xft.dpi: %i\n" % dpi) - xrdb.wait() - except OSError: - pass - - # Other common, but now used settingsfor xrdb: - # Xft.antialias: - # Xft.hinting: - # Xft.hintstyle: - # Xft.rgba: - -############################################################################ -def ReadDisplayConfigRC(): - screens = None - dpi = None - dpms_seconds = None - dpms_enabled = None - - configpath = ExecWithCapture("tde-config",['tde-config','--path','config'],True) - - # Hunt down the user's displayconfigrc file and adjust the resolution - # on the fly to match. (Non-root Users can independantly specify their own settings.) - dirs = configpath.strip().split(":") - for dir in dirs: - if dir!="": - configpath = os.path.join(dir,"displayconfigrc") - if os.path.exists(configpath): - # Parse the config file. - fhandle = open(configpath) - screens = [] - currentscreen = None - for line in fhandle.readlines(): - line = line.strip() - if line.startswith("[Screen"): - # Screen, width, height, refresh, reflectx, reflecty, rotate, redgamma, greengamma,bluegamma - currentscreen = [int(line[7:-1]), None, None, None, False, False, "0", None, None, None] - screens.append(currentscreen) - elif line.startswith("["): - currentscreen = None - elif line.startswith("dpi="): - dpi = line[4:] - elif currentscreen is not None: - if line.startswith("width="): - currentscreen[1] = int(line[6:]) - elif line.startswith("height="): - currentscreen[2] = int(line[7:]) - elif line.startswith("refresh="): - currentscreen[3] = int(line[8:]) - elif line.startswith("reflectX="): - currentscreen[4] = line[9:]=="1" - elif line.startswith("reflectY="): - currentscreen[5] = line[9:]=="1" - elif line.startswith("rotate="): - currentscreen[6] = line[7:] - elif line.startswith("redgamma="): - currentscreen[7] = line[9:] - elif line.startswith("greengamma="): - currentscreen[8] = line[11:] - elif line.startswith("bluegamma="): - currentscreen[9] = line[10:] - elif line.startswith("dpmsEnabled"): - dpms_enabled = line.split("=")[1] - elif line.startswith("dpmsSeconds"): - dpms_seconds = int(line.split("=")[1]) - fhandle.close() - break - - return (screens,dpi,dpms_enabled,dpms_seconds) - -############################################################################ -def main(): - (screens,dpi,dpms_enabled,dpms_seconds) = ReadDisplayConfigRC() - - if dpms_enabled: - if dpms_enabled == "on": - if not dpms_seconds: - dpms_seconds = 900 - cmd = "xset dpms %i %i %i" % (dpms_seconds,dpms_seconds,dpms_seconds) - os.system(cmd) - else: - cmd = "xset -dpms" - os.system(cmd) - - if screens is not None: - # Set the X server. - try: - xserver = xf86misc.XF86Server() - if len(screens)!=0: - - for screen in screens: - (id,width,height,refresh,reflectx,reflecty,rotate,redgamma,greengamma,bluegamma) = screen - - # Convert the stuff into RandR's rotation bitfield thingy. - if rotate=="0": - rotation = xf86misc.XF86Screen.RR_Rotate_0 - elif rotate=="90": - rotation = xf86misc.XF86Screen.RR_Rotate_90 - elif rotate=="180": - rotation = xf86misc.XF86Screen.RR_Rotate_180 - elif rotate=="270": - rotation = xf86misc.XF86Screen.RR_Rotate_270 - if reflectx: - rotation |= xf86misc.XF86Screen.RR_Reflect_X - if reflecty: - rotation |= xf86misc.XF86Screen.RR_Reflect_Y - - if id

Gamma controls how your monitor displays colors.

For accurate color reproduction, adjust the gamma correction sliders until the squares blend into the background as much as possible.

"),hbox) - label.setTextFormat(Qt.RichText) - hboxlayout.addWidget(label,1,Qt.AlignTop) - - sliderspace = QWidget(vbox) - - grid = QGridLayout(sliderspace, 9, 4, 0, KDialog.spacingHint()) - grid.setSpacing(KDialog.spacingHint()) - grid.setColStretch(0,0) - grid.setColStretch(1,0) - grid.setColStretch(2,0) - grid.setColStretch(3,1) - - label = QLabel(i18n("Gamma correction:"),sliderspace) - grid.addWidget(label, 0, 0) - - self.gammaradiogroup = QButtonGroup() - self.gammaradiogroup.setRadioButtonExclusive(True) - self.connect(self.gammaradiogroup,SIGNAL("clicked(int)"),self.slotGammaRadioClicked) - - self.allradio = QRadioButton(sliderspace) - grid.addWidget(self.allradio, 0, 1, Qt.AlignTop) - - label = QLabel(i18n("All:"),sliderspace) - grid.addWidget(label, 0, 2) - - self.gammaslider = KDoubleNumInput(0.4, 3.5, 2.0, 0.05, 2, sliderspace, 'gammaslider') - grid.addMultiCellWidget(self.gammaslider,0,1,3,3) - self.gammaslider.setRange(0.5, 2.5, 0.05, True) - self.connect(self.gammaslider, SIGNAL("valueChanged(double)"), self.slotGammaChanged) - - self.componentradio = QRadioButton(sliderspace) - grid.addWidget(self.componentradio, 2, 1, Qt.AlignTop) - - label = QLabel(i18n("Red:"),sliderspace) - grid.addWidget(label, 2, 2) - - self.redslider = KDoubleNumInput(self.gammaslider,0.4, 3.5, 2.0, 0.05, 2, sliderspace, 'redslider') - grid.addMultiCellWidget(self.redslider,2,3,3,3) - self.redslider.setRange(0.5, 2.5, 0.05, True) - self.connect(self.redslider, SIGNAL("valueChanged(double)"), self.slotRedChanged) - - label = QLabel(i18n("Green:"),sliderspace) - grid.addWidget(label, 4, 2) - - self.greenslider = KDoubleNumInput(self.redslider,0.4, 3.5, 2.0, 0.05, 2, sliderspace, 'greenslider') - grid.addMultiCellWidget(self.greenslider,4,5,3,3) - self.greenslider.setRange(0.5, 2.5, 0.05, True) - self.connect(self.greenslider, SIGNAL("valueChanged(double)"), self.slotGreenChanged) - - label = QLabel(i18n("Blue:"),sliderspace) - grid.addWidget(label, 6, 2) - - self.blueslider = KDoubleNumInput(self.greenslider,0.4, 3.5, 2.0, 0.05, 2, sliderspace, 'blueslider') - grid.addMultiCellWidget(self.blueslider,6,7,3,3) - self.blueslider.setRange(0.5, 2.5, 0.05, True) - self.connect(self.blueslider, SIGNAL("valueChanged(double)"), self.slotBlueChanged) - - self.gammaradiogroup.insert(self.allradio,0) - self.gammaradiogroup.insert(self.componentradio,1) - - if not self.compact_mode: - label = QLabel(i18n("Target gamma:"),sliderspace) - grid.addWidget(label, 8, 0) - - hbox = QHBox(sliderspace) - self.targetgammacombo = KComboBox(False,hbox) - self.targetgammacombo.insertItem(i18n('1.4')) - self.targetgammacombo.insertItem(i18n('1.6')) - self.targetgammacombo.insertItem(i18n('1.8 Apple Macintosh standard')) - self.targetgammacombo.insertItem(i18n('2.0 Recommend')) - self.targetgammacombo.insertItem(i18n('2.2 PC standard, sRGB')) - self.targetgammacombo.insertItem(i18n('2.4')) - hbox.setStretchFactor(self.targetgammacombo,0) - spacer = QWidget(hbox) - hbox.setStretchFactor(spacer,1) - grid.addMultiCellWidget(hbox, 8, 8, 1, 3) - - self.connect(self.targetgammacombo,SIGNAL("activated(int)"),self.slotTargetGammaChanged) - - spacer = QWidget(vbox) - vbox.setStretchFactor(spacer,1) - - if not standalone: - tabcontrol.addTab(vbox,tabname) - - #--- Hardware tab --- - if standalone: - hardwarepage = self.addVBoxPage(i18n("Hardware")) - vbox = QVBox(hardwarepage) - else: - vbox = QVBox(tabcontrol) - vbox.setMargin(KDialog.marginHint()) - self.gfxcarddialog = GfxCardDialog(None) - self.monitordialog = MonitorDialog(None) - - self.xscreenwidgets = [] - - for gfxcard in self.xsetup.getGfxCards(): - w = GfxCardWidget(vbox,self.xsetup, gfxcard, self.gfxcarddialog, self.monitordialog) - self.xscreenwidgets.append(w) - self.connect(w,PYSIGNAL("configChanged"),self.slotConfigChanged) - - spacer = QWidget(vbox) - vbox.setStretchFactor(spacer,1) - - if not self.xsetup.mayModifyXorgConfig(): - QLabel(i18n("Changes on this tab require 'root' access."),vbox) - if not standalone: - QLabel(i18n("Click the \"Administrator Mode\" button to allow modifications on this tab."),vbox) - - hbox = QHBox(vbox) - hbox.setSpacing(KDialog.spacingHint()) - self.testbutton = KPushButton(i18n("Test"),hbox) - self.connect(self.testbutton,SIGNAL("clicked()"),self.slotTestClicked) - hbox.setStretchFactor(self.testbutton,0) - - self.testunavailablelabel = QHBox(hbox) - self.testunavailablelabel.setSpacing(KDialog.spacingHint()) - tmplabel = QLabel(self.testunavailablelabel) - self.testunavailablelabel.setStretchFactor(tmplabel,0) - tmplabel.setPixmap(SmallIcon('info')) - label = QLabel(i18n("This configuration cannot be safely tested."),self.testunavailablelabel) - self.testunavailablelabel.setStretchFactor(label,1) - self.testunavailablelabel.hide() - - spacer = QWidget(hbox) - hbox.setStretchFactor(spacer,1) - vbox.setStretchFactor(hbox,0) - - if not standalone: - tabcontrol.addTab(vbox,i18n("Hardware")) - - #--- Display Power Saving --- - tabname = i18n("Power saving") - if standalone: - powerpage = self.addGridPage(1,QGrid.Horizontal,tabname) - self.dpmspage = DpmsPage(powerpage) - else: - self.dpmspage = DpmsPage(tabcontrol) - self.dpmspage.setMargin(KDialog.marginHint()) - - #self.SizePage.setScreens(self.xsetup.getScreens()) - - # Connect all PYSIGNALs from SizeOrientationPage Widget to appropriate actions. - #self.connect(self.SizePage,PYSIGNAL("dualheadEnabled(bool)"),self.slotDualheadEnabled) - self.connect(self.dpmspage,PYSIGNAL("changedSignal()"),self._sendChangedSignal) - - if not standalone: - tabcontrol.addTab(self.dpmspage,tabname) - - def save(self): # TDECModule - xorg_config_changed = self.xsetup.isXorgConfigChanged() - restart_recommended = self.xsetup.getRestartHint() - - # Check the Size & Orientation tab. - if self.applytimerdialog is None: - self.applytimerdialog = KTimerDialog(15000, KTimerDialog.CountDown, self, "mainKTimerDialog", - True, i18n("Confirm Display Setting Change"), KTimerDialog.Ok | KTimerDialog.Cancel, \ - KTimerDialog.Cancel) - self.applytimerdialog.setButtonOK(KGuiItem(i18n("&Keep"), "button_ok")) - self.applytimerdialog.setButtonCancel(KGuiItem(i18n("&Cancel"), "button_cancel")) - label = KActiveLabel(i18n("Trying new screen settings. Keep these new settings? (Automatically cancelling in 15 seconds.)"), - self.applytimerdialog, "userSpecifiedLabel") - self.applytimerdialog.setMainWidget(label) - - if self.xsetup.isLiveResolutionConfigChanged(): - if self.xsetup.applyLiveResolutionChanges(): - # running X server config has changed. Ask the user. - KDialog.centerOnScreen(self.applytimerdialog, 0) - if self.applytimerdialog.exec_loop(): - self.xsetup.acceptLiveResolutionChanges() - else: - try: - self.xsetup.rejectLiveResolutionChanges() - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - return - else: - # Nothing really changed, just accept the changes. - self.xsetup.acceptLiveResolutionChanges() - - - self.xsetup.acceptLiveGammaChanges() - self.dpmspage.apply() - - # Save the X server config. - if isroot and xorg_config_changed: - - if not self.xconfigtested: - if self.badfbrestore or self._badFbRestore(): - if KMessageBox.warningContinueCancel(self, \ - i18n("The selected driver and monitor configuration can not be safely tested on this computer.\nContinue with this configuration?"), - i18n("Configuration not tested"))!=KMessageBox.Continue: - return - else: - if KMessageBox.warningContinueCancel(self, - i18n("The selected driver and monitor configuration has not been successfully tested on this computer.\nContinue with this configuration?"), - i18n("Configuration not tested"))!=KMessageBox.Continue: - return - - try: - # Backup up the current config file. - i = 1 - while os.path.exists("%s.%i" % (self.xconfigpath,i)): - i += 1 - try: - shutil.copyfile(self.xconfigpath,"%s.%i" % (self.xconfigpath,i)) - except IOError, errmsg: - print "IOError", errmsg, " - while trying to save new xorg.conf - trying to fix" - self.xconfigpath = "/etc/X11/xorg.conf" - xorgfile = open(self.xconfigpath, 'a') - xorgfile.close() - shutil.copyfile(self.xconfigpath,"%s.%i" % (self.xconfigpath,i)) - - # Write out the new config - tmpfilename = self.xconfigpath + ".tmp" - self.xsetup.writeXorgConfig(tmpfilename) - - os.rename(tmpfilename,self.xconfigpath) - except (IOError,TypeError): - print "******* Bang" - raise - return - # FIXME error - - # FIXME the instructions in these messages are probably not quite right. - if restart_recommended==XSetup.RESTART_X: - KMessageBox.information(self, - i18n("Some changes require that the X server be restarted before they take effect. Log out and select \"Restart X server\" from the menu button."), - i18n("X Server restart recommend")) - - if restart_recommended==XSetup.RESTART_SYSTEM: - KMessageBox.information(self, - i18n("Some changes require that the entire system be restarted before they take effect. Log out and select \"Restart computer\" from the log in screen."), - i18n("System restart recommend")) - - self._saveConfig() - self._sendChangedSignal() - - # Called when the desktop is resized. Just center the confirm dialog. - def slotDesktopResized(self): - if self.applytimerdialog is not None: - KDialog.centerOnScreen(self.applytimerdialog, self.applydialogscreenindex) - - def slotApply(self): # KDialogBase - self.save() - - def slotClose(self): # KDialogBase - try: - self.xsetup.rejectLiveGammaChanges() - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - KDialogBase.slotClose(self) - - def load(self): # TDECModule - self.__reset() - self._sendChangedSignal() - - def slotUser1(self): # Reset button, KDialogBase - self.load() - - def slotUser2(self): # About button, KDialogBase - self.aboutus.show() - - def slotResolutionChange(self,i): - self.currentsizescreen.setResolutionIndex(i) - self._sendChangedSignal() - - def slotTargetGammaChanged(self,i): - self.targetgamma = i - self._selectGamma(self.targetgamma) - self._sendChangedSignal() - - def slotGammaRadioClicked(self,i): - self.settingall = i==0 - self.gammaslider.setDisabled(not self.settingall) - self.redslider.setDisabled(self.settingall) - self.greenslider.setDisabled(self.settingall) - self.blueslider.setDisabled(self.settingall) - try: - if self.settingall: - self.currentgammascreen.setAllGamma(self.currentgammascreen.getAllGamma()) - else: - self.currentgammascreen.setRedGamma(self.currentgammascreen.getRedGamma()) - self.currentgammascreen.setGreenGamma(self.currentgammascreen.getGreenGamma()) - self.currentgammascreen.setBlueGamma(self.currentgammascreen.getBlueGamma()) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotGammaChanged(self,value): - if self.updatingGUI: - return - try: - self.currentgammascreen.setAllGamma(value) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotRedChanged(self,value): - if self.updatingGUI: - return - try: - self.currentgammascreen.setRedGamma(value) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotGreenChanged(self,value): - if self.updatingGUI: - return - try: - self.currentgammascreen.setGreenGamma(value) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotBlueChanged(self,value): - if self.updatingGUI: - return - try: - self.currentgammascreen.setBlueGamma(value) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotGammaScreenCombobox(self,i): - self.currentgammascreen = self.xsetup.getUsedScreens()[i] - self._syncGUI() - self._sendChangedSignal() - - def slotConfigChanged(self): - self.xconfigchanged = True - self.xconfigtested = False - - # Check if the current X config can be tested. - self.SizePage._syncGUI() - for widget in self.xscreenwidgets: - widget.syncConfig() - self._syncTestButton() - self._sendChangedSignal() - - def slotTestClicked(self): - self.xconfigtested = self.testX() - - def testX(self): - - self.xserverbin = "/usr/X11R6/bin/XFree86" - if not os.path.isfile(self.xserverbin): - self.xserverbin = "/usr/X11R6/bin/Xorg" - rc = False - - # Remove an stale X server lock - try: os.remove("/tmp/.X9-lock") - except OSError: pass - - # Try to find a safe tmp dir. - tmp_dir = None - if os.environ.get("TMPDIR") is not None: - tmp_dir = os.environ.get("TMPDIR") - if tmp_dir is None or not os.path.isdir(tmp_dir): - tmp_dir = os.path.join(os.environ.get("HOME"),"tmp") - if not os.path.isdir(tmp_dir): - tmp_dir = "/tmp" - working_tmp_dir = os.path.join(tmp_dir,"guidance."+str(os.getpid())) - error_filename = os.path.join(working_tmp_dir,"testserver.xoutput") - config_filename = os.path.join(working_tmp_dir,"testserver.config") - auth_filename = os.path.join(working_tmp_dir,"xauthority") - - # Start the Xserver up with the new config file. - try: - # Create our private dir. - os.mkdir(working_tmp_dir,0700) - - # Backup the XAUTHORITY environment variable. - old_xauthority = os.environ.get("XAUTHORITY",None) - - # Write out the new config file. - self.xsetup.writeXorgConfig(config_filename) - - os.system("xauth -f %s add :9 . `mcookie`" % (auth_filename,) ) - # FIXME:: -xf86config is nowhere in man X ?? - pid = os.spawnv(os.P_NOWAIT,"/bin/bash",\ - ["bash","-c","exec %s :9 -xf86config %s -auth %s &> %s" % \ - (self.xserverbin, config_filename, auth_filename, error_filename)]) - print "Got pid",pid - - # Wait for the server to show up. - print str(os.waitpid(pid,os.WNOHANG)) - - # Use our private xauthority file. - os.environ["XAUTHORITY"] = auth_filename - - time.sleep(1) # Wait a sec. - testserver = None - while True: - # Try connecting to the server. - try: - testserver = xf86misc.XF86Server(":9") - break - except xf86misc.XF86Error: - testserver = None - # Check if the server process is still alive. - if os.waitpid(pid,os.WNOHANG) != (0,0): - break - time.sleep(1) # Give the server some more time. - - print "checkpoint 1" - print str(testserver) - - if testserver is not None: - # Start the timed popup on the :9 display. - #servertestpy = str(TDEGlobal.dirs().findResource("data","guidance/servertestdialog.py")) - servertestpy = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])),"servertestdialog.py") - pythonexe = unicode(TDEStandardDirs.findExe("python")) - - testrc = os.system(pythonexe + " " + servertestpy + " '" + auth_filename+"' ") - rc = (rc >> 8) == 0 # Test is good if the return code was 0. - testserver = None - os.kill(pid,signal.SIGINT) - else: - # Server failed, read the error info. - msg = "" - try: - fhandle = open(error_filename,'r') - for line in fhandle.readlines(): - if (line.startswith("(EE)") and ("Disabling" not in line)) or line.startswith("Fatal"): - msg += line - msg = unicode(i18n("Messages from the X server:\n")) + msg - except IOError: - msg += unicode(i18n("Sorry, unable to capture the error messages from the X server.")) - KMessageBox.detailedSorry(self,i18n("Sorry, this configuration video card driver\nand monitor doesn't appear to work."),msg) - - finally: - # Attempt some cleanup before we go. - try: os.remove(error_filename) - except OSError: pass - try: os.remove(config_filename) - except OSError: pass - try: os.remove(auth_filename) - except OSError: pass - try: os.rmdir(working_tmp_dir) - except OSError: pass - - if old_xauthority is None: - del os.environ["XAUTHORITY"] - else: - os.environ["XAUTHORITY"] = old_xauthority - - return rc - - def _syncGUI(self): - self.SizePage._syncGUI() - - for gfxcard_widget in self.xscreenwidgets: - gfxcard_widget.syncConfig() - - # Sync the gamma tab. - if not self.compact_mode: - self.targetgammacombo.setCurrentItem(self.targetgamma) - self._selectGamma(self.targetgamma) - - if self.currentgammascreen.isGammaEqual(): - self.gammaradiogroup.setButton(0) - else: - self.gammaradiogroup.setButton(1) - - self.gammaslider.setValue(self.currentgammascreen.getAllGamma()) - self.redslider.setValue(self.currentgammascreen.getRedGamma()) - self.greenslider.setValue(self.currentgammascreen.getGreenGamma()) - self.blueslider.setValue(self.currentgammascreen.getBlueGamma()) - - self.settingall = self.currentgammascreen.isGammaEqual() - self.gammaslider.setDisabled(not self.settingall) - self.redslider.setDisabled(self.settingall) - self.greenslider.setDisabled(self.settingall) - self.blueslider.setDisabled(self.settingall) - self._syncTestButton() - - def _syncTestButton(self): - currentbadfbrestore = self._badFbRestore() - self.testbutton.setEnabled(self.xsetup.mayModifyXorgConfig() and not (self.badfbrestore or currentbadfbrestore)) - if not isroot or (self.xsetup.mayModifyXorgConfig() and not (self.badfbrestore or currentbadfbrestore)): - self.testunavailablelabel.hide() - else: - self.testunavailablelabel.show() - - def _loadConfig(self): - self.config.setGroup("General") - t = self.config.readEntry("targetgamma",unicode(i18n("2.0"))) - if t in self.availabletargetgammas: - t = unicode(i18n('2.0')) - self.targetgamma = self.availabletargetgammas.index(t) - - def _saveConfig(self): - global isroot - if isroot: - return - self.config.setGroup("General") - self.config.writeEntry("targetgamma",self.availabletargetgammas[self.targetgamma]) - for s in self.xsetup.getUsedScreens(): - self.config.setGroup("Screen"+str(s.getScreenIndex())) - self._saveRandRConfig(s) - - # Write out the gamma values. - if self.settingall: - self.config.writeEntry("redgamma", str(s.getAllGamma())) - self.config.writeEntry("greengamma", str(s.getAllGamma())) - self.config.writeEntry("bluegamma", str(s.getAllGamma())) - else: - self.config.writeEntry("redgamma", str(s.getRedGamma())) - self.config.writeEntry("greengamma", str(s.getGreenGamma())) - self.config.writeEntry("bluegamma", str(s.getBlueGamma())) - - self.config.writeEntry("dpmsSeconds", self.dpmspage.seconds) - self.config.writeEntry("dpmsEnabled", ("off","on")[self.dpmspage.enabled]) - self.config.sync() - - def _saveRandRConfig(self,screen): - w,h = screen.getAvailableResolutions()[screen.getResolutionIndex()] - self.config.writeEntry("width",w) - self.config.writeEntry("height",h) - self.config.writeEntry("reflectX", int( (screen.getReflection() & screen.RR_Reflect_X)!=0) ) - self.config.writeEntry("reflectY", int((screen.getReflection() & screen.RR_Reflect_Y)!=0) ) - self.config.writeEntry("refresh", screen.getAvailableRefreshRates()[screen.getRefreshRateIndex()]) - rotationmap = {screen.RR_Rotate_0: "0", screen.RR_Rotate_90: "90", - screen.RR_Rotate_180:"180", screen.RR_Rotate_270: "270"} - self.config.writeEntry("rotate", rotationmap[screen.getRotation()]) - - def _selectGamma(self,i): - self.mediumpic.setPixmap(self.mediumimages[i]) - - def __loadImages(self): - if not self.compact_mode: - for g in ['14','16','18','20','22','24']: - self.mediumimages.append( QPixmap(self.imagedir+'gammapics/MGam'+g+'.png') ) - - self.previewscreen = QPixmap(self.imagedir+'monitor_screen_1280x1024.png') - self.previewscreenportrait = QPixmap(self.imagedir+'monitor_screen_1024x1280.png') - - def __reset(self): - # Reset the screen settings. - self.xsetup.reset() - self.dpmspage.reset() - self._syncGUI() - - # Kcontrol expects updates about whether the contents have changed. - # Also we fake the Apply and Reset buttons here when running outside kcontrol. - def _sendChangedSignal(self): - global standalone - - changed = False - for s in self.xsetup.getUsedScreens(): - changed = changed or s.isResolutionSettingsChanged() - - changed = changed or self.xsetup.isXorgConfigChanged() - changed = changed or self.dpmspage.isChanged() - - if standalone: - self.enableButton(KDialogBase.User1,changed) # Reset button - self.enableButtonApply(changed) # Apply button - else: - self.emit(SIGNAL("changed(bool)"), (changed,) ) - - def _badFbRestore(self): - bad_fb_restore = False - for card in self.xsetup.getGfxCards(): - bad_fb_restore = bad_fb_restore or \ - ((card.getGfxCardModel() is not None) and card.getGfxCardModel().getBadFbRestore(card.isProprietaryDriver())) - return bad_fb_restore - -############################################################################ -class SizeOrientationPage(QWidget): - """ - A TabPage with all the settings for Size and Orientation of the screens, - also features Refreshrates and Dualheadsettings. - - Emits the following signals: - - changeSignal() - - ... - - TODO: - * Update __doc__ with emitted signals, connect these. - * Choose screen (more than one preview) - * Relative positioning. - * Call setRefreshCombo after switching screens. - """ - def __init__(self,parent,xsetup,compact): - QWidget.__init__(self,parent) - - global imagedir - self.xsetup = xsetup - self.imagedir = imagedir - self.parent = parent - self.current_screen = self.xsetup.getPrimaryScreen() - self.current_is_primary = True - self.compact_mode = compact - - self._buildGUI() - self._syncGUI() - - def _syncGUI(self): - if self.current_is_primary: - self.current_screen = self.xsetup.getPrimaryScreen() - else: - self.current_screen = self.xsetup.getSecondaryScreen() - - self._syncGUILayout() - self._syncGUIScreen() - - def _syncGUILayout(self): - # Secondary monitor radios. - available_layouts = self.xsetup.getAvailableLayouts() - - may = self.xsetup.mayModifyLayout() - - self.secondary_clone_radio.setEnabled(may and available_layouts & self.xsetup.LAYOUT_CLONE) - self.secondary_clone_radio.setShown(available_layouts & self.xsetup.LAYOUT_CLONE) - - self.secondary_dual_radio.setEnabled(may and available_layouts & self.xsetup.LAYOUT_DUAL) - self.secondary_dual_radio.setShown(available_layouts & self.xsetup.LAYOUT_DUAL) - - self.secondary_position_combo.setEnabled(may and self.xsetup.getLayout()==self.xsetup.LAYOUT_DUAL) - self.secondary_position_combo.setShown(available_layouts & self.xsetup.LAYOUT_DUAL) - - self.secondary_groupbox.setEnabled(may and available_layouts != self.xsetup.LAYOUT_SINGLE) - # If only the single layout is available, then we just hide the whole radio group - self.secondary_groupbox.setShown(available_layouts!=self.xsetup.LAYOUT_SINGLE) - - if self.xsetup.getLayout()!=self.xsetup.LAYOUT_SINGLE: - self.secondary_radios.setButton(self.secondary_option_ids[self.xsetup.getLayout()]) - else: - if available_layouts & XSetup.LAYOUT_CLONE: - self.secondary_radios.setButton(self.secondary_option_ids[XSetup.LAYOUT_CLONE]) - else: - self.secondary_radios.setButton(self.secondary_option_ids[XSetup.LAYOUT_DUAL]) - - self.secondary_groupbox.setChecked(self.xsetup.getLayout() != self.xsetup.LAYOUT_SINGLE) - - def _syncGUIScreen(self): - # Sync the size tab. - self.resize_slider.setScreen(self.current_screen) - - if self.xsetup.getLayout()!=self.xsetup.LAYOUT_DUAL: - self.resize_slider.setTitle(i18n("Screen size")) - else: - self.resize_slider.setTitle(i18n("Screen size #%1").arg(self.xsetup.getUsedScreens().index(self.current_screen)+1)) - - if self.xsetup.getLayout()==self.xsetup.LAYOUT_DUAL: - if not self.compact_mode: - self.monitor_preview_stack.raiseWidget(self.dual_monitor_preview) - else: - if not self.compact_mode: - self.monitor_preview_stack.raiseWidget(self.monitor_preview) - - # Sync the screen orientation. - width,height = self.current_screen.getAvailableResolutions()[self.current_screen.getResolutionIndex()] - - if not self.compact_mode: - self.monitor_preview.setResolution(width,height) - - if self.current_screen.getRotation()==Screen.RR_Rotate_0: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_0) - elif self.current_screen.getRotation()==Screen.RR_Rotate_90: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_90) - elif self.current_screen.getRotation()==Screen.RR_Rotate_270: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_270) - else: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_180) - - self.monitor_preview.setReflectX(self.current_screen.getReflection() & Screen.RR_Reflect_X) - self.monitor_preview.setReflectY(self.current_screen.getReflection() & Screen.RR_Reflect_Y) - - # Set the resolutions for the dual screen preview. - if self.xsetup.getAvailableLayouts() & XSetup.LAYOUT_DUAL: - for i in [0,1]: - screen = [self.xsetup.getPrimaryScreen(), self.xsetup.getSecondaryScreen()][i] - width,height = screen.getAvailableResolutions()[screen.getResolutionIndex()] - self.dual_monitor_preview.setScreenResolution(i,width,height) - self.dual_monitor_preview.setPosition(self.xsetup.getDualheadOrientation()) - - self._fillRefreshCombo() - - self.orientation_radio_group.setButton( \ - [Screen.RR_Rotate_0, Screen.RR_Rotate_90, Screen.RR_Rotate_270, - Screen.RR_Rotate_180].index(self.current_screen.getRotation())) - # This construct above just maps an rotation to a radiobutton index. - self.mirror_horizontal_checkbox.setChecked(self.current_screen.getReflection() & Screen.RR_Reflect_X) - self.mirror_vertical_checkbox.setChecked(self.current_screen.getReflection() & Screen.RR_Reflect_Y) - - width,height = self.current_screen.getAvailableResolutions()[self.current_screen.getResolutionIndex()] - if not self.compact_mode: - self.monitor_preview.setResolution(width,height) - - # Enable/disable the resolution/rotation/reflection widgets. - may_edit = self.xsetup.mayModifyResolution() - self.normal_orientation_radio.setEnabled(may_edit) - available_rotations = self.current_screen.getAvailableRotations() - - # Hide the whole group box if there is only one boring option. - self.orientation_group_box.setShown(available_rotations!=Screen.RR_Rotate_0) - - self.left_orientation_radio.setEnabled(available_rotations & Screen.RR_Rotate_90 and may_edit) - self.left_orientation_radio.setShown(available_rotations & Screen.RR_Rotate_90) - - self.right_orientation_radio.setEnabled(available_rotations & Screen.RR_Rotate_270 and may_edit) - self.right_orientation_radio.setShown(available_rotations & Screen.RR_Rotate_270) - - self.upside_orientation_radio.setEnabled(available_rotations & Screen.RR_Rotate_180 and may_edit) - self.upside_orientation_radio.setShown(available_rotations & Screen.RR_Rotate_180) - - self.mirror_horizontal_checkbox.setEnabled(available_rotations & Screen.RR_Reflect_X and may_edit) - self.mirror_horizontal_checkbox.setShown(available_rotations & Screen.RR_Reflect_X) - - self.mirror_vertical_checkbox.setEnabled(available_rotations & Screen.RR_Reflect_Y and may_edit) - self.mirror_vertical_checkbox.setShown(available_rotations & Screen.RR_Reflect_Y) - - self.resize_slider.setEnabled(may_edit) - self.size_refresh_combo.setEnabled(may_edit) - - # Set the dual orientation combo. - self.secondary_position_combo.setCurrentItem( - [XSetup.POSITION_LEFTOF, - XSetup.POSITION_RIGHTOF, - XSetup.POSITION_ABOVE, - XSetup.POSITION_BELOW].index(self.xsetup.getDualheadOrientation())) - - def _fillRefreshCombo(self): - # Update refresh combobox - self.size_refresh_combo.clear() - for rate in self.current_screen.getAvailableRefreshRates(): - self.size_refresh_combo.insertItem(i18n("%1 Hz").arg(rate)) - self.size_refresh_combo.setCurrentItem(self.current_screen.getRefreshRateIndex()) - self.current_screen.setRefreshRateIndex(self.size_refresh_combo.currentItem()) - - def slotMonitorFocussed(self,currentMonitor): - if currentMonitor==0: - self.current_screen = self.xsetup.getPrimaryScreen() - self.current_is_primary = True - else: - self.current_screen = self.xsetup.getSecondaryScreen() - self.current_is_primary = False - - self._syncGUIScreen() - - def _sendChangedSignal(self): - self.emit(PYSIGNAL("changedSignal()"),()) - - def _buildGUI(self): - """ Assemble all GUI elements """ - # Layout stuff. - top_layout = QHBoxLayout(self,0,KDialog.spacingHint()) - self.top_layout = top_layout - - # -- Left column with orientation and dualhead box. - vbox = QVBox(self) - top_layout.addWidget(vbox,0) - - # -- Orientation group - self.orientation_group_box = QVGroupBox(vbox) - self.orientation_group_box.setTitle(i18n("Monitor Orientation")) - self.orientation_group_box.setInsideSpacing(KDialog.spacingHint()) - self.orientation_group_box.setInsideMargin(KDialog.marginHint()) - self.orientation_radio_group = QButtonGroup() - self.orientation_radio_group.setRadioButtonExclusive(True) - - self.normal_orientation_radio = QRadioButton(self.orientation_group_box) - self.normal_orientation_radio.setText(i18n("Normal")) - self.left_orientation_radio = QRadioButton(self.orientation_group_box) - self.left_orientation_radio .setText(i18n("Left edge on top")) - self.right_orientation_radio = QRadioButton(self.orientation_group_box) - self.right_orientation_radio.setText(i18n("Right edge on top")) - self.upside_orientation_radio = QRadioButton(self.orientation_group_box) - self.upside_orientation_radio.setText(i18n("Upsidedown")) - - self.mirror_horizontal_checkbox = QCheckBox(self.orientation_group_box) - self.mirror_horizontal_checkbox.setText(i18n("Mirror horizontally")) - self.connect(self.mirror_horizontal_checkbox,SIGNAL("toggled(bool)"),self.slotMirrorHorizontallyToggled) - - self.mirror_vertical_checkbox = QCheckBox(self.orientation_group_box) - self.mirror_vertical_checkbox.setText(i18n("Mirror vertically")) - self.connect(self.mirror_vertical_checkbox,SIGNAL("toggled(bool)"),self.slotMirrorVerticallyToggled) - - self.orientation_radio_group.insert(self.normal_orientation_radio,0) - self.orientation_radio_group.insert(self.left_orientation_radio,1) - self.orientation_radio_group.insert(self.right_orientation_radio,2) - self.orientation_radio_group.insert(self.upside_orientation_radio,3) - self.connect(self.orientation_radio_group,SIGNAL("clicked(int)"),self.slotOrientationRadioClicked) - - # -- Dualhead Box. - self.secondary_groupbox = QVGroupBox(vbox) - self.secondary_groupbox.setCheckable(True) - self.secondary_groupbox.setTitle(i18n("Second screen")) - self.connect(self.secondary_groupbox,SIGNAL("toggled(bool)"),self.slotSecondMonitorToggled) - - self.secondary_radios = QVButtonGroup(None) # Invisible - self.connect(self.secondary_radios,SIGNAL("pressed(int)"),self.slotSecondMonitorRadioPressed) - - self.secondary_options = {} - self.secondary_option_ids = {} - - # Clone radio - self.secondary_clone_radio = QRadioButton(i18n("Clone primary screen"),self.secondary_groupbox) - radio_id = self.secondary_radios.insert(self.secondary_clone_radio) - self.secondary_options[radio_id] = self.xsetup.LAYOUT_CLONE - self.secondary_option_ids[self.xsetup.LAYOUT_CLONE] = radio_id - - # Dual radio - self.secondary_dual_radio = QRadioButton(i18n("Dual screen"),self.secondary_groupbox) - radio_id = self.secondary_radios.insert(self.secondary_dual_radio) - self.secondary_options[radio_id] = self.xsetup.LAYOUT_DUAL - self.secondary_option_ids[self.xsetup.LAYOUT_DUAL] = radio_id - - self.secondary_radios.setButton(radio_id) - - hbox = QHBox(self.secondary_groupbox) - spacer = QWidget(hbox) - spacer.setFixedSize(20,1) - hbox.setStretchFactor(spacer,0) - - self.secondary_position_combo = QComboBox(0,hbox,"") - self.secondary_position_combo.insertItem(i18n("1 left of 2")) - self.secondary_position_combo.insertItem(i18n("1 right of 2")) - self.secondary_position_combo.insertItem(i18n("1 above 2")) - self.secondary_position_combo.insertItem(i18n("1 below 2")) - self.connect(self.secondary_position_combo,SIGNAL("activated(int)"),self.slotSecondaryPositionChange) - - spacer = QWidget(vbox) - vbox.setStretchFactor(spacer,1) - - vbox = QVBox(self) - top_layout.addWidget(vbox,1) - - if not self.compact_mode: - # -- Right columns with preview, size and refresh widgets. - - # -- Preview Box. - self.monitor_preview_stack = QWidgetStack(vbox) - - self.monitor_preview = MonitorPreview(self.monitor_preview_stack,self.imagedir) - self.monitor_preview_stack.addWidget(self.monitor_preview) - self.connect(self.monitor_preview,PYSIGNAL("focussed()"),self.slotMonitorFocussed) - - self.dual_monitor_preview = DualMonitorPreview(self.monitor_preview_stack, DUAL_PREVIEW_SIZE, self.imagedir) - - self.monitor_preview_stack.addWidget(self.dual_monitor_preview) - self.connect(self.dual_monitor_preview,PYSIGNAL("pressed()"),self.slotMonitorFocussed) - self.connect(self.dual_monitor_preview,PYSIGNAL("positionChanged()"),self.slotDualheadPreviewPositionChanged) - - # -- Size & Refresh Box. - if not self.compact_mode: - hbox = QHBox(vbox) - else: - hbox = QVBox(vbox) - hbox.setSpacing(KDialog.spacingHint()) - - self.resize_slider = ResizeSlider(hbox) - self.connect(self.resize_slider,PYSIGNAL("resolutionChange(int)"),self.slotResolutionChange) - - hbox2 = QHBox(hbox) - self.refresh_label = QLabel(hbox2,"RefreshLabel") - self.refresh_label.setText(i18n("Refresh:")) - - self.size_refresh_combo = QComboBox(0,hbox2,"comboBox1") # gets filled in setRefreshRates() - self.connect(self.size_refresh_combo,SIGNAL("activated(int)"),self.slotRefreshRateChange) - if self.compact_mode: - spacer = QWidget(hbox2) - hbox2.setStretchFactor(spacer,1) - - spacer = QWidget(vbox) - vbox.setStretchFactor(spacer,1) - - self.clearWState(Qt.WState_Polished) - - def setNotification(self,text): - self.notify.setText(text) - - def slotOrientationRadioClicked(self,i): - self.current_screen.setRotation( - [Screen.RR_Rotate_0, Screen.RR_Rotate_90,Screen.RR_Rotate_270, Screen.RR_Rotate_180][i]) - - if self.current_screen.getRotation()==Screen.RR_Rotate_0: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_0) - elif self.current_screen.getRotation()==Screen.RR_Rotate_90: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_90) - elif self.current_screen.getRotation()==Screen.RR_Rotate_270: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_270) - else: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_180) - - self._sendChangedSignal() - - def slotMirrorHorizontallyToggled(self,flag): - # Bit flippin' - if flag: - self.current_screen.setReflection(self.current_screen.getReflection() | Screen.RR_Reflect_X) - else: - self.current_screen.setReflection(self.current_screen.getReflection() & ~Screen.RR_Reflect_X) - self.monitor_preview.setReflectX(flag) - self._sendChangedSignal() - - def slotMirrorVerticallyToggled(self,flag): - # Bit flippin' - if flag: - self.current_screen.setReflection(self.current_screen.getReflection() | Screen.RR_Reflect_Y) - else: - self.current_screen.setReflection(self.current_screen.getReflection() & ~Screen.RR_Reflect_Y) - self.monitor_preview.setReflectY(flag) - self._sendChangedSignal() - - def slotResolutionChange(self,i): - self.current_screen.setResolutionIndex(i) - width,height = self.current_screen.getAvailableResolutions()[i] - - if not self.compact_mode: - self.monitor_preview.setResolution(width,height) - self.dual_monitor_preview.setScreenResolution( - self.xsetup.getUsedScreens().index(self.current_screen), - width,height) - - self._fillRefreshCombo() - self._sendChangedSignal() - - def slotRefreshRateChange(self,index): - self.current_screen.setRefreshRateIndex(index) - self._sendChangedSignal() - - def setScreen(self,screen): - self.current_screen = screen - self._syncGUI() - - def slotSecondMonitorToggled(self,enabled): - if enabled: - pressed_id = self.secondary_radios.selectedId() - self.xsetup.setLayout(self.secondary_options[pressed_id]) - else: - self.xsetup.setLayout(self.xsetup.LAYOUT_SINGLE) - - if self.xsetup.getLayout()!=self.xsetup.LAYOUT_DUAL: - self.current_screen = self.xsetup.getUsedScreens()[0] - - self.secondary_position_combo.setEnabled(self.xsetup.getLayout()==XSetup.LAYOUT_DUAL) - - self._syncGUIScreen() - self._sendChangedSignal() - - def slotSecondMonitorRadioPressed(self,pressedId): - self.xsetup.setLayout(self.secondary_options[pressedId]) - - if self.xsetup.getLayout()!=XSetup.LAYOUT_DUAL: - self.current_screen = self.xsetup.getUsedScreens()[0] - - self.secondary_position_combo.setEnabled(self.xsetup.getLayout()==XSetup.LAYOUT_DUAL) - - if self.xsetup.getLayout()==XSetup.LAYOUT_DUAL: - if not self.compact_mode: - self.monitor_preview_stack.raiseWidget(self.dual_monitor_preview) - else: - if not self.compact_mode: - self.monitor_preview_stack.raiseWidget(self.monitor_preview) - - self._syncGUIScreen() - self._sendChangedSignal() - - def slotSecondaryPositionChange(self,index): - position = [XSetup.POSITION_LEFTOF,XSetup.POSITION_RIGHTOF,XSetup.POSITION_ABOVE,XSetup.POSITION_BELOW][index] - self.xsetup.setDualheadOrientation(position) - self.dual_monitor_preview.setPosition(position) - self._sendChangedSignal() - - def slotDualheadPreviewPositionChanged(self,position): - self.xsetup.setDualheadOrientation(position) - index = { - XSetup.POSITION_LEFTOF:0, - XSetup.POSITION_RIGHTOF:1, - XSetup.POSITION_ABOVE:2, - XSetup.POSITION_BELOW:3 - }[position] - self.secondary_position_combo.setCurrentItem(index) - self._sendChangedSignal() - - def setMargin(self,margin): - self.top_layout.setMargin(margin) - - def setSpacing(self,spacing): - self.top_layout.setSpacing(spacing) - -############################################################################ -class DpmsPage(QWidget): - - # Mapping values in seconds to human-readable labels. - intervals = ( - (60,i18n("1 minute")), - (120,i18n("2 minutes")), - (180,i18n("3 minutes")), - (300,i18n("5 minutes")), - (600,i18n("10 minutes")), - (900,i18n("15 minutes")), - (1200,i18n("20 minutes")), - (1500,i18n("25 minutes")), - (1800,i18n("30 minutes")), - (2700,i18n("45 minutes")), - (3600,i18n("1 hour")), - (7200,i18n("2 hours")), - (10800,i18n("3 hours")), - (14400,i18n("4 hours")), - (18000,i18n("5 hours"))) - - def __init__(self,parent = None,name = None,modal = 0,fl = 0): - global imagedir - QWidget.__init__(self,parent) - - # Where to find xset. - self.xset_bin = os.popen('which xset').read()[:-1] - - if not name: - self.setName("DPMSTab") - - dpms_tab_layout = QVBoxLayout(self,0,0,"DPMSTabLayout") - self.top_layout = dpms_tab_layout - - hbox = QHBox(self) - hbox.setSpacing(KDialog.spacingHint()) - - dpms_tab_layout.addWidget(hbox) - - self.dpmsgroup = QHGroupBox(hbox,"dpmsgroup") - self.dpmsgroup.setInsideSpacing(KDialog.spacingHint()) - self.dpmsgroup.setInsideMargin(KDialog.marginHint()) - self.dpmsgroup.setTitle(i18n("Enable power saving")) - self.dpmsgroup.setCheckable(1) - - self.connect(self.dpmsgroup,SIGNAL("toggled(bool)"),self.slotDpmsToggled) - - hbox2 = QHBox(self.dpmsgroup) - hbox2.setSpacing(KDialog.spacingHint()) - - dpmstext = QLabel(hbox2,"dpmstext") - dpmstext.setText(i18n("Switch off monitor after:")) - - self.dpmscombo = QComboBox(0,hbox2,"dpmscombo") - self.fillCombo(self.dpmscombo) - self.connect(self.dpmscombo,SIGNAL("activated(int)"),self.slotDpmsActivated) - - spacer = QWidget(hbox2) - hbox2.setStretchFactor(spacer,1) - - self.energystarpix = QLabel(hbox,"energystarpix") - self.energystarpix.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.energystarpix.sizePolicy().hasHeightForWidth())) - self.energystarpix.setMinimumSize(QSize(150,77)) - self.energystarpix.setPixmap(QPixmap(imagedir+"../energystar.png")) - self.energystarpix.setScaledContents(1) - - bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding) - dpms_tab_layout.addItem(bottomspacer) - - self.clearWState(Qt.WState_Polished) - - self.readDpms() - - def fillCombo(self,combo): - """ Fill the combobox with the values from our list """ - for interval in self.intervals: - combo.insertItem(interval[1]) - - def slotDpmsActivated(self,index): - """ Another dpms value has been chosen, update buttons at bottom. """ - self.emit(PYSIGNAL("changedSignal()"), ()) - - def slotDpmsToggled(self,bool): - """ Dpms checkbox has been toggled, update buttons at bottom. """ - self.emit(PYSIGNAL("changedSignal()"), ()) - - def readDpms(self): - # FIXME it is not the widget's job to read or change the values, just to present the GUI. - """ Read output from xset -q and parse DPMS settings from it. """ - # FIXME: localisation problem running this command. - lines = ExecWithCapture(self.xset_bin,[self.xset_bin,'-q']).split('\n') - - self.dpms_min = 1800 - self.dpms_enabled = False - - for line in lines: - if line.strip().startswith("Standby"): - self.dpms_min = int(line.strip().split()[5]) # TODO: More subtle exception handling. ;) - if line.strip().startswith("DPMS is"): - self.dpms_enabled = line.strip().split()[2]=="Enabled" - - if self.dpms_min==0: # 0 also means don't use Standby mode. - self.dpms_enabled = False - self.dpms_min = 1800 - - self.dpmsgroup.setChecked(self.dpms_enabled) - - for i in range(len(self.intervals)): - diff = abs(self.intervals[i][0] - self.dpms_min) - if i==0: - last_diff = diff - if (last_diff <= diff and i!=0) or (last_diff < diff): - i = i-1 - break - last_diff = diff - self.dpmscombo.setCurrentItem(i) - - def isChanged(self): - """ Check if something has changed since startup or last apply(). """ - if self.dpmsgroup.isChecked(): - if self.intervals[self.dpmscombo.currentItem()][0] != self.dpms_min: - return True - if self.dpmsgroup.isChecked() != self.dpms_enabled: - return True - return False - - else: - # self.dpmsgroup.isChecked() is False - return self.dpms_enabled # self.dpms_enabled != False - - def applyDpms(self): - """ Use xset to apply new dpms settings. """ - self.enabled = self.dpmsgroup.isChecked() - self.seconds = self.intervals[self.dpmscombo.currentItem()][0] - if self.enabled: - # Switch dpms on and set timeout interval. - cmd_on = "%s +dpms" % self.xset_bin - cmd_set = "%s dpms %i %i %i" % (self.xset_bin, self.seconds,self.seconds,self.seconds) - print cmd_set - if os.system(cmd_set) != 0: - print "DPMS command failed: ", cmd_set - else: - # Switch dpms off. - cmd_on = "%s -dpms" % self.xset_bin - if os.system(cmd_on) != 0: - print "DPMS command failed: ", cmd_on - self.readDpms() - self.emit(PYSIGNAL("changedSignal()"), ()) - - def apply(self): - self.applyDpms() - - def reset(self): - for i in range(len(self.intervals)): - if self.intervals[i][0] == self.dpms_min: - self.dpmscombo.setCurrentItem(i) - break - - self.dpmsgroup.setChecked(self.dpms_enabled) - - def setMargin(self,margin): - self.top_layout.setMargin(margin) - - def setSpacing(self,spacing): - self.top_layout.setSpacing(spacing) - -############################################################################ -def create_displayconfig(parent,name): - """ Factory function for KControl """ - global kapp - kapp = TDEApplication.kApplication() - return DisplayApp(parent, name) - -############################################################################ -def MakeAboutData(): - aboutdata = TDEAboutData("guidance",programname,version, \ - "Display and Graphics Configuration Tool", TDEAboutData.License_GPL, \ - "Copyright (C) 2003-2007 Simon Edwards", \ - "Thanks go to Phil Thompson, Jim Bublitz and David Boddie.") - aboutdata.addAuthor("Simon Edwards","Developer","simon@simonzone.com", \ - "http://www.simonzone.com/software/") - aboutdata.addAuthor("Sebastian Kügler","Developer","sebas@kde.org", \ - "http://vizZzion.org"); - aboutdata.addCredit("Pete Andrews","Gamma calibration pictures/system",None, \ - "http://www.photoscientia.co.uk/Gamma.htm") - return aboutdata - -if standalone: - aboutdata = MakeAboutData() - TDECmdLineArgs.init(sys.argv,aboutdata) - - kapp = TDEApplication() - - displayapp = DisplayApp() - displayapp.exec_loop() diff --git a/displayconfig/displayconfigabstraction.py b/displayconfig/displayconfigabstraction.py deleted file mode 100644 index f59b2ff..0000000 --- a/displayconfig/displayconfigabstraction.py +++ /dev/null @@ -1,3230 +0,0 @@ -#!/usr/bin/env python - -import os -import sys -import string -import math -import subprocess -import xf86misc -import xorgconfig -import ScanPCI -import csv -import re -from execwithcapture import * - -"""Classes for dealing with X.org configuration in a sane way. - -The object model used here is fairly simple. An XSetup object represents -the complete configuration of the server. The XSetup object contains one or -more GfxCard objects. One for each graphics card present in the machine. -Each GfxCard has one or more Screen objects with each Screen representing -one 'output' on the graphics card. - -Each GfxCard object is also associated with a GfxCardModel object which -describes the model of graphics card. - -Each Screen object is associated with a MonitorModel object which -describes the model of monitor attached. - -""" - -FALLBACK_RESOLUTION = (800,600) - -# FIXME updating /etc/modules for fglrx. -data_file_dir = "." -def SetDataFileDir(dir_name): - global data_file_dir - data_file_dir = dir_name - -var_data_dir = "/var/lib/guidance-backends" -def SetVarDataDir(dir_name): - global var_data_dir - var_data_dir = dir_name - -############################################################################ -class XSetup(object): - """Represents the current configuration of the X.org X11 server. - - - """ - # Map positions - ABOVE = 0 - UNDER = 1 - LEFTOF = 2 - RIGHTOF = 3 - - RESTART_NONE = 0 - RESTART_X = 1 - RESTART_SYSTEM = 2 - - LAYOUT_SINGLE = 1 # These are bit flags. - LAYOUT_CLONE = 2 - LAYOUT_DUAL = 4 - LAYOUT_SINGLE_XINERAMA = 256 # For internal use. - LAYOUT_CLONE_XINERAMA = 512 # For internal use. - - POSITION_LEFTOF = 0 - POSITION_RIGHTOF = 1 - POSITION_ABOVE = 2 - POSITION_BELOW = 3 - - ROLE_UNUSED = 0 - ROLE_PRIMARY = 1 - ROLE_SECONDARY = 2 - - def __init__(self,xorg_config_filename='/etc/X11/xorg.conf',debug_scan_pci_filename=None,secondtry=False): - self.screens = [] - self.gfxcards = [] - self.xorg_config, self.hasxorg = xorgconfig.readConfig(xorg_config_filename, check_exists=True) - if not secondtry: - self.xorg_config_filename = xorg_config_filename - if self.xorg_config_filename == None: - self.xorg_config_filename = '/etc/X11/xorg.conf'; - self.x_live_info = xf86misc.XF86Server() - - self.primary_screen = None - self.secondary_screen = None - - pci_bus = ScanPCI.PCIBus(data_file_dir) - if debug_scan_pci_filename is None: - pci_bus.detect() - else: - pci_bus.loadFromFile(debug_scan_pci_filename) - - # First thing. Scan the PCI bus and find out how many Gfx cards we have. - found_list = self._detectGfxCards(pci_bus) - # list of (PCI_ID, PCIDevice, GfxCard) tuples - - found_list.sort() - - # Prepare some useful data structures. - self.layout = self.LAYOUT_SINGLE - self.xinerama = False - self.orientation = self.POSITION_LEFTOF - - # Maps screen section names to xorg screens section objects. - xorg_screen_name_dict = {} - xorg_unused_screen_sections = self.xorg_config.getSections("Screen") - for screen in xorg_unused_screen_sections: - xorg_screen_name_dict[screen.identifier] = screen - - # Maps device sections names to xorg device sections - xorg_device_name_dict = {} - xorg_unused_device_sections = self.xorg_config.getSections("Device") - for device in xorg_unused_device_sections: - xorg_device_name_dict[device.identifier] = device - - # Maps device sections names to xorg device sections - xorg_monitor_name_dict = {} - xorg_monitor_sections = self.xorg_config.getSections("Monitor") - for monitor in xorg_monitor_sections: - xorg_monitor_name_dict[monitor.identifier] = monitor - - # Maps GfxCard objects to ScanPCI.PCIDevice objects. - gfx_card_pcidevice_dict = {} - - #------------------------------------------------------------------- - # Decode the server layout. - server_layouts = self.xorg_config.getSections("ServerLayout") - if len(server_layouts)==0: - print "*** Error: couldn't find any ServerLayout sections" - return - layout = server_layouts[0] # Grab the first ServerLayout - - if len(layout.screen)==0: - print "*** Error: no screens were specified in the ServerLayout section" - - # Handle leftof rightof below and above. - (primary_name, secondary_name, layout, self.orientation) = self._decodeServerLayoutScreens(layout.screen) - - screen_list = [primary_name] - if secondary_name is not None: - screen_list.append(secondary_name) - - for screen_name in screen_list: - if screen_name in xorg_screen_name_dict: - screen_section = xorg_screen_name_dict[screen_name] - if screen_section.device in xorg_device_name_dict: - - device_section = xorg_device_name_dict[screen_section.device] - - # Ok, we've now got a screen section and its device. - gfx_card = None - - if device_section.busid is not None: - # Try to match this device to a gfxcard by using the PCI bus ID. - bus_id = self._canonicalPCIBusID(device_section.busid) - - # See if there is already a known gfxcard at this PCI ID. - gfx_card = self.getGfxCardByPCIBusID(bus_id) - if gfx_card is not None: - # Let the gfxcard know that we have another device section for it to manage. - gfx_card._addXDevice(device_section) - try: - xorg_unused_device_sections.remove(device_section) - except ValueError: - pass - else: - # Not known, look for a matching pci device instead. - for pci_device_tuple in found_list: - if pci_device_tuple[0]==bus_id: - # Got a hit, create a gfxcard object. - gfx_card = GfxCard( self, pci_id=bus_id, \ - x_device=device_section, \ - detected_model=pci_device_tuple[2]) - - self.gfxcards.append(gfx_card) - gfx_card_pcidevice_dict[gfx_card] = pci_device_tuple[1] - xorg_unused_device_sections.remove(device_section) - found_list.remove(pci_device_tuple) - break - - else: - - # OK, no PCI ID, try matching to a PCI device by X driver name, - # or if there is one only gfx card then just grab it. - driver_name = device_section.driver - for pci_device_tuple in found_list: - if pci_device_tuple[2].getDriver()==driver_name \ - or pci_device_tuple[2].getProprietaryDriver()==driver_name \ - or len(found_list)==1: - # Got a hit, create a gfxcard object. - gfx_card = GfxCard( self, pci_id=pci_device_tuple[0], \ - x_device=device_section, \ - detected_model=pci_device_tuple[2]) - - self.gfxcards.append(gfx_card) - gfx_card_pcidevice_dict[gfx_card] = pci_device_tuple[1] - xorg_unused_device_sections.remove(device_section) - found_list.remove(pci_device_tuple) - break - - if gfx_card is not None: - # Look up the monitor section from the monitor name. - monitor_section = None - monitor_model = None - if screen_section.monitor in xorg_monitor_name_dict: - monitor_section = xorg_monitor_name_dict[screen_section.monitor] - monitor_model = self._matchMonitor(monitor_section) - - screen = Screen(x_config_screen=screen_section, gfx_card=gfx_card, \ - x_config_monitor=monitor_section, monitor_model=monitor_model, \ - x_config=self.xorg_config) - gfx_card._addScreen(screen) - - if self.primary_screen is None: - self.primary_screen = screen - elif self.secondary_screen is None: - self.secondary_screen = screen - - xorg_unused_screen_sections.remove(screen_section) - - if self.primary_screen is not None and self.secondary_screen is not None: - self.layout = layout - - #------------------------------------------------------------------- - # Dualhead hardware detection. - gfx_cards_needing_second_heads = [] - - # Detect dualhead ATI cards - for pci_device in pci_bus.devices: - if pci_device.text is not None and pci_device.text.find("Secondary")!=-1: - - pci_device_id = "PCI:%i:%i:%i" % (pci_device.pci_bus, pci_device.pci_device, pci_device.pci_function) - - for gfx_card in self.gfxcards: - if gfx_card.getPCIBusID() != pci_device_id: - # Compare the first two numbers that make up a PCI bus id (e.g. middle part of PCI:1:0:0) - if gfx_card.getPCIBusID().split(":")[1:-1] == [str(pci_device.pci_bus),str(pci_device.pci_device)]: - if len(gfx_card.getScreens())<2: - gfx_cards_needing_second_heads.append(gfx_card) - found_list = [x for x in found_list if x[0]!=pci_device_id] - break - - # Detect dualhead Intel cards - for gfx_card in self.gfxcards: - if gfx_card._getDetectedGfxCardModel().getDriver() in ['i740','i810', 'intel']: - gfx_card_pci_id = gfx_card.getPCIBusID().split(":")[1:] - base_pci_id = gfx_card_pci_id[:-1] - - for pci_device in pci_bus.devices: - if gfx_card_pci_id != [str(pci_device.pci_bus),str(pci_device.pci_device),str(pci_device.pci_function)]: - if base_pci_id == [str(pci_device.pci_bus),str(pci_device.pci_device)]: - pci_device_id = "PCI:%i:%i:%i" % (pci_device.pci_bus, pci_device.pci_device, pci_device.pci_function) - found_list = [x for x in found_list if x[0]!=pci_device_id] - # Try to configure a second head later if not yet available - if len(gfx_card.getScreens()) < 2: - gfx_cards_needing_second_heads.append(gfx_card) - break - - # Detect dualhead nVidia cards - for gfx_card in self.gfxcards: - if gfx_card._getDetectedGfxCardModel().getDriver() in ['nv','nvidia']: - if self._isNVidiaCardDualhead(gfx_card_pcidevice_dict[gfx_card]): - if len(gfx_card.getScreens())<2: - if gfx_card not in gfx_cards_needing_second_heads: - gfx_cards_needing_second_heads.append(gfx_card) - continue - - # Detect dualhead Matrox cards. This info is from the Cards+ db. - for gfx_card in self.gfxcards: - if (gfx_card._getDetectedGfxCardModel().getMultiHead()>1) and (len(gfx_card.getScreens())<2): - if gfx_card not in gfx_cards_needing_second_heads: - gfx_cards_needing_second_heads.append(gfx_card) - - # Detect laptops. Dualhead/clone mode is standard functionality on laptops. - # (but can be hard to detect). - if os.path.isfile('/usr/sbin/laptop-detect'): - if subprocess.call(['/usr/sbin/laptop-detect'])==0: - if len(self.gfxcards)!=0: - gfx_card = self.gfxcards[0] - if gfx_card not in gfx_cards_needing_second_heads and \ - len(gfx_card.getScreens())<2: - gfx_cards_needing_second_heads.append(gfx_card) - - # Match up the second heads with any loose sections in xorg.conf. - for gfx_card in gfx_cards_needing_second_heads: - screens = gfx_card.getScreens() - # Try to find a loose xorg.conf Screen section that also - # references this gfx card. That is probably the config - # for the second screen. - for screen_section in xorg_unused_screen_sections: - if screen_section.device in xorg_device_name_dict: - device_section = xorg_device_name_dict[screen_section.device] - - # Is this the second screen for the same PCI device aka gfxcard? - - # Note: even though the second head shows up as a separate PCI ID, the screen - # section in xorg.conf still uses the primary PCI ID. - if str(device_section.screen)=="1" and \ - self._canonicalPCIBusID(device_section.busid)==gfx_card.getPCIBusID(): - - # Look up the monitor section from the monitor name. - monitor_section = None - monitor_model = None - if screen_section.monitor in xorg_monitor_name_dict: - monitor_section = xorg_monitor_name_dict[screen_section.monitor] - monitor_model = self._matchMonitor(monitor_section) - - gfx_card._addXDevice(device_section) - xorg_unused_device_sections.remove(device_section) - - screen = Screen(x_config_screen=screen_section, gfx_card=gfx_card, \ - x_config_monitor=monitor_section, monitor_model=monitor_model, \ - x_config=self.xorg_config) - gfx_card._addScreen(screen) - self.secondary_screen = screen - xorg_unused_screen_sections.remove(screen_section) - break - else: - # Couldn't anything in xorg.conf, just make an empty screen - screen = Screen(gfx_card=gfx_card, x_config=self.xorg_config) - gfx_card._addScreen(screen) - - #------------------------------------------------------------------- - # Handle loose gfx card devices. Check that all PCI gfxcards are accounted for. - for pci_device_tuple in found_list: - - bus_id = pci_device_tuple[0] - for device_section in xorg_unused_device_sections: - if bus_id == self._canonicalPCIBusID(device_section.busid): - xorg_unused_device_sections.remove(device_section) - break - else: - device_section = None - - # Got a hit, create a gfxcard object. - gfx_card = GfxCard( self, pci_id=pci_device_tuple[0], \ - x_device=device_section, \ - detected_model=pci_device_tuple[2]) - - gfx_card_pcidevice_dict[gfx_card] = pci_device_tuple[1] - self.gfxcards.append(gfx_card) - - screen = None - # See if this device section is referenced by a screen section. - # if so, then we grab the screen section. - if device_section is not None: - for screen_section in xorg_unused_screen_sections: - if screen_section.device==device_section.identifier: - - # Ok, we have found the screen section, monitor? - monitor_section = None - monitor_model = None - if screen_section.monitor in xorg_monitor_name_dict: - monitor_section = xorg_monitor_name_dict[screen_section.monitor] - monitor_model = self._matchMonitor(monitor_section) - - screen = Screen(x_config_screen=screen_section, gfx_card=gfx_card, \ - x_config_monitor=monitor_section, monitor_model=monitor_model, \ - x_config=self.xorg_config) - gfx_card._addScreen(screen) - xorg_unused_screen_sections.remove(screen_section) - break - - if screen is None: - # Manually add a screen. - screen = Screen(gfx_card=gfx_card, x_config=self.xorg_config) - gfx_card._addScreen(screen) - - #------------------------------------------------------------------- - # Sort the gfx cards by PCI id. - def gfxcard_pci_sort(a,b): return cmp(a.getPCIBusID(),b.getPCIBusID()) - self.gfxcards.sort(gfxcard_pci_sort) - - # Hand out some randr live screens - x_live_screens = self.x_live_info.getScreens() - i = 0 - for gfx_card in self.gfxcards: - for screen in gfx_card.getScreens(): - if itwoHeads = " - # - NV_ARCH_04 = 0x4 - NV_ARCH_10 = 0x10 - NV_ARCH_20 = 0x20 - NV_ARCH_30 = 0x30 - NV_ARCH_40 = 0x40 - - pci_device = PCIDeviceObject.device - - if pci_device & 0xfff0 == 0x00f0: - return True # FIXME PCIXpress chipsets - - # These IDs come from the Xorg source. - # xc/programs/Xserver/hw/xfree86/drivers/nv/nv_driver.c - # And should be periodically updated. - chipset = pci_device & 0x0ff0 - if chipset in [ - 0x0100, # GeForce 256 - 0x0110, # GeForce2 MX - 0x0150, # GeForce2 - 0x0170, # GeForce4 MX - 0x0180, # GeForce4 MX (8x AGP) - 0x01A0, # nForce - 0x01F0]:# nForce2 - architecture = NV_ARCH_10 - elif chipset in [ - 0x0200, # GeForce3 - 0x0250, # GeForce4 Ti - 0x0280]:# GeForce4 Ti (8x AGP) - architecture = NV_ARCH_20 - elif chipset in [ - 0x0300, # GeForceFX 5800 - 0x0310, # GeForceFX 5600 - 0x0320, # GeForceFX 5200 - 0x0330, # GeForceFX 5900 - 0x0340]:# GeForceFX 5700 - architecture = NV_ARCH_30 - elif chipset in [ - 0x0040, - 0x00C0, - 0x0120, - 0x0130, - 0x0140, - 0x0160, - 0x01D0, - 0x0090, - 0x0210, - 0x0220, - 0x0230, - 0x0290, - 0x0390]: - architecture = NV_ARCH_40 - else: - architecture = NV_ARCH_04 - - return (architecture >= NV_ARCH_10) and \ - (chipset != 0x0100) and \ - (chipset != 0x0150) and \ - (chipset != 0x01A0) and \ - (chipset != 0x0200) - - def _syncXorgConfig(self): - - xinerama_clone = (self.layout==XSetup.LAYOUT_CLONE) and \ - not ((self.secondary_screen._getGfxCard() is self.primary_screen._getGfxCard()) \ - and (self.primary_screen._getGfxCard()._getAvailableLayouts() & XSetup.LAYOUT_CLONE)) - - if xinerama_clone: - # For clone mode with xinerama we copy the screen settings from the primary screen - # to the secondary screen. - primary_screen = self.getPrimaryScreen() - secondary_screen = self.getSecondaryScreen() - - resolution = primary_screen.getAvailableResolutions()[primary_screen.getResolutionIndex()] - secondary_resolution_index = secondary_screen.getAvailableResolutions().index(resolution) - secondary_screen.setResolutionIndex(secondary_resolution_index) - secondary_rates = secondary_screen.getAvailableRefreshRatesForResolution(secondary_resolution_index) - primary_rate = primary_screen.getAvailableRefreshRates()[primary_screen.getRefreshRateIndex()] - - best_rate_index = 0 - best_score = 1000000 - for i in range(len(secondary_rates)): - rate = secondary_rates[i] - score = abs(rate-primary_rate) - if score < best_score: - best_score = score - best_rate_index = i - - secondary_screen.setRefreshRateIndex(best_rate_index) - - # Sync up the graphics cards. - for gfxcard in self.gfxcards: - gfxcard._syncXorgConfig() - - server_flags_sections = self.xorg_config.getSections("ServerFlags") - if len(server_flags_sections)!=0: - server_flags = server_flags_sections[0] - server_flags.option.removeOptionByName("Xinerama") - else: - server_flags = self.xorg_config.makeSection(None,["Section","ServerFlags"]) - self.xorg_config.append(server_flags) - - # Delete any old screen entries in the serverlayout section. - server_layout = self.xorg_config.getSections("ServerLayout")[0] - for screen in server_layout.screen[:]: - server_layout.screen.remove(screen) - - # Add the first Screen row - screen_id_1 = self.primary_screen._getXorgScreenSection().identifier - server_layout.screen.append(server_layout.screen.makeLine(None, - ["0",screen_id_1,"0","0"])) - - # FIXME server_flags -> Option "DefaultServerLayout" "???" - if self.layout==XSetup.LAYOUT_DUAL or xinerama_clone: - server_flags.option.append( server_flags.option.makeLine(None,["Xinerama","true"]) ) - - # Add the second screen row. This one also has the dual screen - # orientation info. - screen_id_2 = self.secondary_screen._getXorgScreenSection().identifier - - if not xinerama_clone: - - position = {XSetup.POSITION_LEFTOF:"RightOf", - XSetup.POSITION_RIGHTOF:"LeftOf", - XSetup.POSITION_ABOVE:"Below", - XSetup.POSITION_BELOW:"Above"}[self.orientation] - - server_layout.screen.append(server_layout.screen.makeLine(None, - ["1",screen_id_2,position,screen_id_1])) - else: - # Xinerama clone mode. Place the second screen directly on top of the - # primary screen. - server_layout.screen.append(server_layout.screen.makeLine(None, - ["1",screen_id_2,"0","0"])) - - self.original_layout = self.layout - self.original_orientation = self.orientation - self.original_primary_screen = self.primary_screen - self.original_secondary_screen = self.secondary_screen - - def writeXorgConfig(self,filename): - self._syncXorgConfig() - self.xorg_config.writeConfig(filename) - - def xorgConfigToString(self): - return self.xorg_config.toString() - - def getUsedScreens(self): - """Returns the list of Screen objects that the current setup is using.""" - if self.layout==XSetup.LAYOUT_SINGLE: - return [self.primary_screen] - else: - return [self.primary_screen, self.secondary_screen] - - def getAllScreens(self): - """Returns a list of all Screen object.""" - screens = [] - for card in self.gfxcards: - for screen in card.getScreens(): - screens.append(screen) - return screens - - def getScreen(self,screenindex): - return self.getUsedScreens()[screenindex] - - def getGfxCards(self): - return self.gfxcards[:] # No messin' with the gfx card list. - - def getGfxCardByPCIBusID(self,bus_id): - for gfxcard in self.gfxcards: - if gfxcard.getPCIBusID()==bus_id: - return gfxcard - return None - - def getPrimaryScreen(self): - return self.primary_screen - - def getSecondaryScreen(self): - return self.secondary_screen - - def getScreenRole(self,screen): - if screen is self.primary_screen: - return XSetup.ROLE_PRIMARY - if screen is self.secondary_screen: - return XSetup.ROLE_SECONDARY - return XSetup.ROLE_UNUSED - - def setScreenRole(self,screen,role): - if role==XSetup.ROLE_PRIMARY: - if screen is self.secondary_screen: - # Swap the roles around. - self.secondary_screen = self.primary_screen - self.primary_screen = screen - else: - self.primary_screen = screen - - elif role==XSetup.ROLE_SECONDARY: - if screen is self.primary_screen: - # Swap the roles around. - self.primary_screen = self.secondary_screen - self.secondary_screen = screen - else: - self.secondary_screen = screen - else: - # ROLE_UNUSED - if screen is not self.primary_screen and screen is not self.secondary_screen: - return - - # Find the first screen unused. - for unused_screen in self.getAllScreens(): - if screen is not self.primary_screen and screen is not self.secondary_screen: - if screen is self.primary_screen: - self.primary_screen = unused_screen - else: - self.secondary_screen = unused_screen - return - - def mayModifyXorgConfig(self): - """Check if the current user may modify the xorg.conf file - - Returns True or False - """ - return os.access(self.xorg_config_filename, os.W_OK|os.R_OK) - - def mayModifyGamma(self): - """Check if the current user may modify the gamma settings. - - Returns True or False. - """ - return self.isGammaLive() or self.mayModifyXorgConfig() - - def mayModifyResolution(self): - """Check if the current user may modify the screen resolution. - - Returns True or False. - """ - for screen in self.x_live_info.getScreens(): - if screen.resolutionSupportAvailable(): - return True - - return self.mayModifyXorgConfig() - - def isGammaLive(self): - """Check if gamma changes are done immediately. - - Returns True or False. - """ - return True # FIXME depends on the xvid extension and if86misc. - - def isLiveResolutionConfigChanged(self): - """Check if the live server configuration is changed - - Checks if the configuration has been modified with changes that can be - pushed to the running X server. - - Returns True or False. - """ - # XRandR tends to break Xinerama - if self.primary_screen._getGfxCard().getLayout() in \ - (XSetup.LAYOUT_SINGLE_XINERAMA, XSetup.LAYOUT_DUAL): - return False - for screen in self.getAllScreens(): - if screen.isLive() and screen.isResolutionSettingsChanged(): - return True - - return False - - def applyLiveResolutionChanges(self): - """Apply any changes that can be done live - - Returns True if running server resolution has been changed. - """ - rc = False - for s in self.getUsedScreens(): - if s.isResolutionSettingsChanged(): - s.applyResolutionSettings() - rc = rc or s.isResolutionLive() - return rc - - def acceptLiveResolutionChanges(self): - """ - - - """ - for s in self.getUsedScreens(): - s.acceptResolutionSettings() - - def rejectLiveResolutionChanges(self): - """Rejects and reverts the last live server resolution changes - - Rejects the last resolution changes that were made to the live server - and reverts it back to the previous configuration. - """ - for s in self.getUsedScreens(): - s.revertResolutionSettings() - - def isLiveGammaConfigChanged(self): - """Check if the live server gamma configuration is changed - - Checks if the configuration has been modified with changes that can be - pushed to the running X server. - - Returns True or False. - """ - for screen in self.getAllScreens(): - if screen.isLive() and screen.isGammaSettingsChanged(): - return True - - return False - - def applyLiveGammaChanges(self): - """Apply any changes that can be done live - - Returns True if running server gamma has been changed. - """ - rc = False - for s in self.getUsedScreens(): - if s.isGammaSettingsChanged(): - s.applyGammaSettings() - rc = rc or s.isGammaLive() - return rc - - def acceptLiveGammaChanges(self): - """ - - - """ - for s in self.getUsedScreens(): - s.acceptGammaSettings() - - def rejectLiveGammaChanges(self): - """Rejects and reverts the last live server gamma changes - - Rejects the last gamma changes that were made to the live server - and reverts it back to the previous configuration. - """ - for s in self.getUsedScreens(): - s.revertGammaSettings() - - def isXorgConfigChanged(self): - """Check if the xorg.config needs to updated - - Returns True if the xorg.config file needs to updated to reflect new changes. - """ - changed = self.original_layout!=self.layout or \ - self.original_orientation!=self.orientation or \ - self.original_primary_screen!=self.primary_screen or \ - self.original_secondary_screen!=self.secondary_screen - - for gfxcard in self.gfxcards: - changed = changed or gfxcard.isXorgConfigChanged() - for screen in self.getAllScreens(): - changed = changed or screen.isXorgConfigChanged() - return changed - - def getRestartHint(self): - hint = XSetup.RESTART_NONE - if self.original_layout!= self.layout or self.original_orientation != self.orientation: - hint = XSetup.RESTART_X - return max(hint,max( [gfxcard.getRestartHint() for gfxcard in self.gfxcards] )) - - def reset(self): - for card in self.gfxcards: - card.reset() - - self.layout = self.original_layout - self.orientation = self.original_orientation - self.primary_screen = self.original_primary_screen - self.secondary_screen = self.original_secondary_screen - - # Dualhead and secondary monitor support ---------- - def getLayout(self): - return self.layout - - def setLayout(self,layout): - """ - - Keyword arguments: - layout - XSetup.LAYOUT_SINGLE, XSetup.LAYOUT_CLONE or XSetup.LAYOUT_DUAL. - """ - self.layout = layout - - if self.layout==XSetup.LAYOUT_SINGLE: - for gfxcard in self.gfxcards: - gfxcard.setLayout(XSetup.LAYOUT_SINGLE) - self.xinerama = False - elif self.layout==XSetup.LAYOUT_DUAL: - # 'xinerama' screens can be combined by the ServerLayout xorg.conf - # sections into a multihead configurations. Gfxcard objects just - # have to output xinerama friendly xorg.conf device and screen - # sections. - self.xinerama = True - for gfxcard in self.gfxcards: - gfxcard.setLayout(XSetup.LAYOUT_SINGLE_XINERAMA) - - # Check if the primary and secondary screen are on the same gfx card. - # If so then see if the gfxcard can directly (read: accelarated) support - # the layout we want. - if self.primary_screen._getGfxCard() is self.secondary_screen._getGfxCard(): - if self.primary_screen._getGfxCard().getAvailableLayouts() & self.layout: - self.primary_screen._getGfxCard().setLayout(self.layout) - self.xinerama = False - - elif self.layout==XSetup.LAYOUT_CLONE: - - # If the graphics card itself has both heads and it can offer a better clone - # mode, then we use that instead of faking it with xinerama. - if (self.secondary_screen._getGfxCard() is self.primary_screen._getGfxCard()) \ - and (self.primary_screen._getGfxCard()._getAvailableLayouts() & XSetup.LAYOUT_CLONE): - self.xinerama = False - for gfxcard in self.gfxcards: - gfxcard.setLayout(XSetup.LAYOUT_CLONE) - else: - self.xinerama = True - for gfxcard in self.gfxcards: - gfxcard.setLayout(XSetup.LAYOUT_SINGLE_XINERAMA) - - def mayModifyLayout(self): - return self.mayModifyXorgConfig() - - def getAvailableLayouts(self): - if self.secondary_screen is not None: - return XSetup.LAYOUT_SINGLE | XSetup.LAYOUT_DUAL | XSetup.LAYOUT_CLONE - else: - return XSetup.LAYOUT_SINGLE - - def setDualheadOrientation(self,orientation): - """ Sets orientation of monitor to one of - XSetup.ABOVE, XSetup.UNDER, XSetup.LEFTOF, XSetup.RIGHTOF - """ - self.orientation = orientation - - def getDualheadOrientation(self): - """ Returns the current orientation, one of - XSetup.ABOVE, XSetup.UNDER, XSetup.LEFTOF, XSetup.RIGHTOF - """ - return self.orientation - - def isHWAccelerated(self): - # FIXME: - # if twinview-alike and screen[0].res = screen[1].res - # else: if primary screen - return True - - # Internal ---------- - def _addScreen(self,screen): - self.screens.append(screen) - - def _addGfxCard(self,gfxcard): - self.gfxcards.append(gfxcard) - - def _getColorDepth(self): - return min([s._getColorDepth() for s in self.getUsedScreens()]) - - def __str__(self): - string = "XSetup:\n" - string += " Layout: %s\n" % ({self.LAYOUT_SINGLE: "Single", - self.LAYOUT_CLONE: "Clone", - self.LAYOUT_DUAL: "Dual" - }[self.getLayout()]) - - i = 1 - for gfxcard in self.gfxcards: - string += " Gfxcard %i: %s\n" % (i,str(gfxcard)) - i += 1 - return string - -############################################################################ -class GfxCard(object): - """Represents a graphics card that is present in this computer.""" - - def __init__(self, setup, pci_id=None, x_device=None, detected_model=None, proprietary_driver=False): - self.setup = setup - self.x_config = self.setup.xorg_config - self.layout = XSetup.LAYOUT_SINGLE - self.pci_id = pci_id - self.screens = [] - - self.detected_model = detected_model - self.proprietary_driver = proprietary_driver - - self.video_ram = 1024 - - # The (optimised) layout that was detected in xorg.conf on device level. - self.detected_layout = XSetup.LAYOUT_SINGLE - self.detected_orientation = XSetup.POSITION_LEFTOF - - self.x_device = [] # This can be a list of xorg device sections - if x_device is not None: - self.x_device.append(x_device) - - def _addScreen(self,screen): - self.screens.append(screen) - - def _addXDevice(self,x_device): - self.x_device.append(x_device) - - def _finalizeInit(self): - # Finish initalisation. - - if len(self.x_device)!=0: - - # Try to find a gfx card model. - self.gfxcard_model = None - if self.x_device[0].boardname is not None: - # Look up the model by boardname. - try: - self.gfxcard_model = GetGfxCardModelDB().getGfxCardModelByName(self.x_device[0].boardname) - except KeyError: - pass - - if self.gfxcard_model is None: - # OK, try looking it up by driver. - try: - self.gfxcard_model = GetGfxCardModelDB().getGfxCardModelByDriverName(self.x_device[0].driver) - except KeyError: - self.gfxcard_model = self.detected_model - - # Write the current driver in the model - if self.x_device[0].driver: - self.gfxcard_model.setDriver(self.x_device[0].driver) - - self.proprietary_driver = self.gfxcard_model.getProprietaryDriver()==self.x_device[0].driver - - if self.x_device[0].videoram is not None: - self.video_ram = int(self.x_device[0].videoram) - - # Detect layout - if len(self.screens)>=2: - # Xorg ATI driver. - if self._getCurrentDriver() in ['ati','r128','radeon']: - merged = self.x_device[0].option.getOptionByName('mergedfb') - if merged is not None and xorgconfig.toBoolean(merged._row[2]): - self.detected_layout = XSetup.LAYOUT_CLONE - # ATI proprietary driver - elif self._getCurrentDriver()=='fglrx': - desktopsetup = self.x_device[0].option.getOptionByName('desktopsetup') - if desktopsetup is not None and desktopsetup._row[2]=='c': - self.detected_layout = XSetup.LAYOUT_CLONE - # nVidia proprietary driver - elif self._getCurrentDriver()=='nvidia': - twinview = self.x_device[0].option.getOptionByName('twinview') - if twinview is not None: - desktopsetup = self.x_device[0].option.getOptionByName('twinvieworientation') - if desktopsetup is not None and desktopsetup._row[2].lower()=='clone': - self.detected_layout = XSetup.LAYOUT_CLONE - # i810 driver - elif self._getCurrentDriver() in ['i810', 'intel']: - clone = self.x_device[0].option.getOptionByName('clone') - if clone is not None: - if xorgconfig.toBoolean(clone._row[2]): - self.detected_layout = XSetup.LAYOUT_CLONE - - else: - self.gfxcard_model = self.detected_model - - self.original_gfxcard_model = self.gfxcard_model - self.original_proprietary_driver = self.proprietary_driver - self.original_layout = self.layout - - # Give the screens a chance to finish initialisation. - for screen in self.screens: - screen._finalizeInit() - for screen in self.screens: - screen._resyncResolution() - - def _getDetectedLayout(self): - return self.detected_layout - - def _getDetectedDualheadOrientation(self): - return self.detected_orientation - - def _getDetectedGfxCardModel(self): - return self.detected_model - - def getScreens(self): - return self.screens[:] - - def getGfxCardModel(self): - return self.gfxcard_model - - def setGfxCardModel(self,gfx_card_model): - self.gfxcard_model = gfx_card_model - - for screen in self.screens: - screen._resyncResolution() - - def getXorgDeviceSection(self,index): - return self.x_device[index] - - def isProprietaryDriver(self): - return self.proprietary_driver - - def setProprietaryDriver(self,proprietary_driver): - self.proprietary_driver = proprietary_driver - - def getDetectedGfxCardModel(self): - return self.detected_model - - def getPCIBusID(self): - return self.pci_id - - def isXorgConfigChanged(self): - return self.original_gfxcard_model is not self.gfxcard_model or \ - self.original_proprietary_driver != self.proprietary_driver or \ - self.original_layout != self.layout - - def reset(self): - for screen in self.screens: - screen.reset() - - self.gfxcard_model = self.original_gfxcard_model - self.proprietary_driver = self.original_proprietary_driver - - def isAGP(self): - return self.pci_id=='PCI:1:0:0' # FIXME this might not be accurate. - - def getLayout(self): - return self.layout - - def setLayout(self,layout): - self.layout = layout - for screen in self.screens: - screen._resyncResolution() - - def getAvailableLayouts(self): - layouts = XSetup.LAYOUT_SINGLE - if len(self.screens)==2: - if self._getCurrentDriver() in ['fglrx', 'nvidia', 'i810']: - layouts |= XSetup.LAYOUT_CLONE | XSetup.LAYOUT_DUAL - return layouts - - def getVideoRam(self): - """ - Get the amount of video ram that this card has. - - The values returned have the following meanings: - 256 => 256 kB - 512 => 512 kB - 1024 => 1 MB - 2048 => 2 MB - 4096 => 4 MB - 8192 => 8 MB - 16384 => 16 MB - 32768 => 32 MB - 65536 => 64 MB or more - - The video ram setting is only used if the selected graphics card model requires - that the amount of video ram be explicitly specified. That is to say that - gfxcard.getGfxCardModel().getNeedVideoRam() returns true. - - Returns an integer from the list above. - """ - return self.video_ram - - def setVideoRam(self,ram): - self.video_ram = ram - - for screen in self.screens: - screen._resyncResolution() - - def _getCurrentDriver(self): - if self.proprietary_driver: - return self.gfxcard_model.getProprietaryDriver() - else: - return self.gfxcard_model.getDriver() - - def getRestartHint(self): - # The ATI propreitary drivers need a special AGP kernel module to be loaded. - # The best, and often only way to get this module loaded is to reboot. - # The same applies for removing the module. - hint = XSetup.RESTART_NONE - - if self.original_proprietary_driver: - original_gfx_driver = self.original_gfxcard_model.getProprietaryDriver() - else: - original_gfx_driver = self.original_gfxcard_model.getDriver() - - current_gfx_driver = self._getCurrentDriver() - - if current_gfx_driver!=original_gfx_driver: - # Restart X if the driver is different. - hint = XSetup.RESTART_X - - # Layout changes also require an X server restart. - if self.original_layout!=self.layout: - hint = XSetup.RESTART_X - - if original_gfx_driver=='fglrx' and current_gfx_driver in ['ati','r128','radeon']: - hint = XSetup.RESTART_SYSTEM - - # If a different kernel module is needed, then restart the system. - kernel_module_list = self._getLoadedKernelModules() - if self._needATIFglrx() and 'fglrx' not in kernel_module_list: - hint = XSetup.RESTART_SYSTEM - else: - if 'fglrx' in kernel_module_list: - hint = XSetup.RESTART_SYSTEM - - hintlist = [hint] - hintlist.extend([screen.getRestartHint() for screen in self.screens]) - return max(hintlist) - - def _needATIFglrx(self): - """Work out if the current configuration require the ATI fglrx kernel module.""" - return self.isAGP() and self.getGfxCardModel() is not None and \ - self.getGfxCardModel().getProprietaryDriver()=='fglrx' and self.isProprietaryDriver() - - def _getLoadedKernelModules(self): - return [line.split()[0] for line in open('/proc/modules')] - - def _getAvailableLayouts(self): - if len(self.screens)>=2: - drv = self._getCurrentDriver() - layouts = XSetup.LAYOUT_SINGLE | XSetup.LAYOUT_DUAL - if drv in ['fglrx', 'nvidia', 'i810']: - layouts |= XSetup.LAYOUT_CLONE - elif drv in ['ati', 'radeon', 'r128', 'intel']: - layouts = XSetup.LAYOUT_SINGLE - return layouts - else: - return XSetup.LAYOUT_SINGLE - - def __str__(self): - screen_string = ",".join([str(s) for s in self.screens]) - driver = self._getCurrentDriver() - return "GfxCard: {model:"+str(self.gfxcard_model)+", driver:"+driver+", screens:"+screen_string+"}" - - def _syncXorgConfig(self): - if self.proprietary_driver and self.gfxcard_model.getProprietaryDriver() is not None: - driver = self.gfxcard_model.getProprietaryDriver() - else: - driver = self.gfxcard_model.getDriver() - - # FIXME maybe this module stuff should migrate into XSetup. - - # --- Fix the module section --- - - # $raw_X->set_devices($card, @{$card->{cards} || []}); - # $raw_X->get_ServerLayout->{Xinerama} = { commented => !$card->{Xinerama}, Option => 1 } - #if defined $card->{Xinerama}; - module_sections = self.x_config.getSections("Module") - if len(module_sections) > 0: - module = module_sections[0] - else: - module = self.x_config.makeSection(None, ["Section", "Module"]) - self.x_config.append(module) - - module.removeModule('GLcore') - module.removeModule('glx') - module.removeModule('dbe') - - # Mandriva - #module.removeModule("/usr/X11R6/lib/modules/extensions/libglx.so") - - if driver=='nvidia': - module.addModule("glx") - - # Mandriva - # This loads the NVIDIA GLX extension module. - # IT IS IMPORTANT TO KEEP NAME AS FULL PATH TO libglx.so ELSE - # IT WILL LOAD XFree86 glx module and the server will crash. - - # module.addModule("/usr/X11R6/lib/modules/extensions/libglx.so") - # FIXME lib64 - elif self.gfxcard_model.getProprietaryDriver()!='fglrx': - module.addModule('glx') - module.addModule('GLcore') - - #module.removeModule("/usr/X11R6/lib/modules/extensions/libglx.a") - if driver=='fglrx': - module.addModule("glx") - module.addModule("dbe") - #elif driver!='nvidia': - # module.addModule("/usr/X11R6/lib/modules/extensions/libglx.a") - - # DRI - module.removeModule('dri') - if self.gfxcard_model.getDriGlx(): - module.addModule('dri') - - module.removeModule('v4l') - if not (self.gfxcard_model.getDriGlx() and self.gfxcard_model.getDriver()=='r128'): - module.addModule('v4l') - - # --- Fix all of the Device sections --- - for i in range(len(self.screens)): - - if i==len(self.x_device): - new_device = self.x_config.makeSection('',['section','device']) - self.x_config.append(new_device) - self.x_device.append(new_device) - new_device.identifier = self.x_config.createUniqueIdentifier("device") - - identifier = self.x_device[i].identifier - busid = self.x_device[i].busid - - self.x_device[i].clear() - - # Create a new Device section in the Xorg config file. - self.x_device[i].identifier = identifier - self.x_device[i].boardname = self.gfxcard_model.getName() - self.x_device[i].busid = self.pci_id - self.x_device[i].driver = driver - self.x_device[i].screen = str(i) - - if self.gfxcard_model.getVendor() is not None: - self.x_device[i].vendorname = self.gfxcard_model.getVendor() - - if self.gfxcard_model.getNeedVideoRam(): - self.x_device[i].videoram = self.video_ram - - # Setup Clone mode for second heads. - if driver in ["ati","r128","radeon"]: # Xorg ATI driver - merged_value = { - XSetup.LAYOUT_CLONE: "on", - XSetup.LAYOUT_SINGLE: "off", - XSetup.LAYOUT_DUAL: "on", - XSetup.LAYOUT_SINGLE_XINERAMA: "off" - }[self.layout] - - merged_option = self.x_device[i].option.makeLine(None,["MergedFB",merged_value]) - self.x_device[i].option.append(merged_option) - - if self.layout==XSetup.LAYOUT_CLONE: - monitor_model = self.setup.getSecondaryScreen().getMonitorModel() - if monitor_model is not None: - if monitor_model.getHorizontalSync() is not None: - hsyncline = self.x_device[i].option.makeLine(None,['CRT2HSync',monitor_model.getHorizontalSync()]) - self.x_device[i].option.append(hsyncline) - - if monitor_model.getVerticalSync() is not None: - vsyncline = self.x_device[i].option.makeLine(None,['CRT2VRefresh',monitor_model.getVerticalSync()]) - self.x_device[i].option.append(vsyncline) - - # FIXME option "CloneMode" "off" - - if driver=='fglrx': # ATI proprietary driver. - if self.layout==XSetup.LAYOUT_CLONE: - new_option = self.x_device[i].option.makeLine(None,["DesktopSetup","c"]) - self.x_device[i].option.append(new_option) - - # FIXME this probably won't work on laptops and DVI. The user will probably - # have to manually select the monitor types. - - # We do this to make sure that the driver starts up in clone mode even - # if it can't detect the second monitor. - new_option = self.x_device[i].option.makeLine(None,["ForceMonitors","crt1,crt2"]) - self.x_device[i].option.append(new_option) - - monitor_model = self.setup.getSecondaryScreen().getMonitorModel() - if monitor_model is not None: - if monitor_model.getHorizontalSync() is not None: - hsyncline = self.x_device[i].option.makeLine(None,['HSync2',monitor_model.getHorizontalSync()]) - self.x_device[i].option.append(hsyncline) - - if monitor_model.getVerticalSync() is not None: - vsyncline = self.x_device[i].option.makeLine(None,['VRefresh2',monitor_model.getVerticalSync()]) - self.x_device[i].option.append(vsyncline) - - if driver=='nvidia': # nVidia proprietary driver. - if self.layout==XSetup.LAYOUT_CLONE: - new_option = self.x_device[i].option.makeLine(None,["TwinView","on"]) - self.x_device[i].option.append(new_option) - new_option = self.x_device[i].option.makeLine(None,["TwinViewOrientation","clone"]) - self.x_device[i].option.append(new_option) - - monitor_model = self.setup.getSecondaryScreen().getMonitorModel() - if monitor_model is not None: - if monitor_model.getHorizontalSync() is not None: - hsyncline = self.x_device[i].option.makeLine(None,['SecondMonitorHorizSync',monitor_model.getHorizontalSync()]) - self.x_device[i].option.append(hsyncline) - - if monitor_model.getVerticalSync() is not None: - vsyncline = self.x_device[i].option.makeLine(None,['SecondMonitorVertRefresh',monitor_model.getVerticalSync()]) - self.x_device[i].option.append(vsyncline) - - if driver in ['i810']: # i810 driver - if self.layout in (XSetup.LAYOUT_SINGLE_XINERAMA, - XSetup.LAYOUT_DUAL, - XSetup.LAYOUT_CLONE): - new_option = self.x_device[i].option.makeLine(None,["MonitorLayout", "CRT,LFP"]) - self.x_device[i].option.append(new_option) - if self.layout==XSetup.LAYOUT_CLONE: - new_option = self.x_device[i].option.makeLine(None,["Clone","on"]) - self.x_device[i].option.append(new_option) - - # Find the closest matching refresh rate for the second monitor. - primary_screen = self.setup.getPrimaryScreen() - secondary_screen = self.setup.getSecondaryScreen() - resolution = primary_screen.getAvailableResolutions()[primary_screen.getResolutionIndex()] - secondary_resolution_index = secondary_screen.getAvailableResolutions().index(resolution) - secondary_rates = secondary_screen.getAvailableRefreshRatesForResolution(secondary_resolution_index) - primary_rate = primary_screen.getAvailableRefreshRates()[primary_screen.getRefreshRateIndex()] - - best_rate = 50 - best_score = 1000000 - for rate in secondary_rates: - score = abs(rate-primary_rate) - if score < best_score: - best_score = score - best_rate = rate - - # Specify a working refresh rate for the second monitor. - new_option = self.x_device[i].option.makeLine(None,["CloneRefresh",str(best_rate)]) - self.x_device[i].option.append(new_option) - - self._insertRawLinesIntoConfig(self.x_device[i], self.gfxcard_model.getLines()) - - self.screens[i]._syncXorgConfig(self.x_device[i]) - - self.original_gfxcard_model = self.gfxcard_model - self.original_proprietary_driver = self.proprietary_driver - self.original_layout = self.layout - - def _insertRawLinesIntoConfig(self,section,lines): - reader = csv.reader(lines,delimiter=' ') - for row in reader: - if len(row)>=2: - if row[0].lower()=="option": - option = section.option.makeLine(None,row[1:]) - section.option.append(option) - -############################################################################ -class Screen(object): - """Represents a single output/screen/monitor on a graphics card. - - Changes to the screen resolution, refresh rate, rotation and reflection - settings are not made active until the method applyResolutionSettings() is - called. After calling applyResolutionSettings(), changes can be backed out - of with the revertResolutionSettings() method. If you, should I say the user, - is satisfied with the new settings then call the acceptResolutionSettings() - method. - - Gamma correction settings take effect immediately, and don't take part in the - apply, revert and accept mechanism above. - """ - - RR_Rotate_0 = xf86misc.XF86Screen.RR_Rotate_0 - RR_Rotate_90 = xf86misc.XF86Screen.RR_Rotate_90 - RR_Rotate_180 = xf86misc.XF86Screen.RR_Rotate_180 - RR_Rotate_270 = xf86misc.XF86Screen.RR_Rotate_270 - RR_Reflect_X = xf86misc.XF86Screen.RR_Reflect_X - RR_Reflect_Y = xf86misc.XF86Screen.RR_Reflect_Y - - def __init__(self, gfx_card=None, x_config_screen=None, x_config_monitor=None, \ - monitor_model=None, x_config=None): - """Create a Screen object. - - This method is private to this module. - """ - self.gfx_card = gfx_card - self.x_config_screen = x_config_screen - - self.x_config_monitor = x_config_monitor - self.monitor_model = monitor_model - self.monitor_aspect = ModeLine.ASPECT_4_3 - self.original_monitor_model = monitor_model - self.x_config = x_config - - # Cookup some sensible screen sizes. - self.standard_sizes = GetMonitorModeDB().getAllResolutions() - - self.x_live_screen = None - - # Intialise the gamma settings with defaults. - self.redgamma = 1.0 - self.greengamma = 1.0 - self.bluegamma = 1.0 - self.allgamma = 1.0 - self.settingall = True - - # If there is a monitor xorg.conf section then look there for gamma info. - if self.x_config_monitor is not None: - gamma_row = self.x_config_monitor.getRow('gamma') - if gamma_row is not None: - # Read the gamma info out of xorg.conf - try: - if len(gamma_row)==3: - self.redgamma = float(gamma_row[0]) - self.greengamma = float(gamma_row[1]) - self.bluegamma = float(gamma_row[2]) - self.allgamma = self.redgamma - elif len(gamma_row)==1: - self.allgamma = float(gamma_row[0]) - self.redgamma = self.allgamma - self.greengamma = self.allgamma - self.bluegamma = self.allgamma - except ValueError: - pass - - # Try to work out if this monitor is setup for 4:3 modes or 16:9. - aspect_43_count = 0 - aspect_169_count = 0 - # Count the number of 4:3 modelines compared to 16:9 modes. - for mode in self.x_config_monitor.modeline: - try: - # Don't count the fallback resolution. It is also present - # if the monitor is widescreen. Just ignore it. - if (mode._row[2],mode._row[6])!=FALLBACK_RESOLUTION: - if MonitorModeDB.aspectRatio(mode._row[2],mode._row[6])==ModeLine.ASPECT_4_3: - aspect_43_count += 1 - else: - aspect_169_count += 1 - except IndexError: - pass - - if aspect_43_count >= aspect_169_count: - self.monitor_aspect = ModeLine.ASPECT_4_3 - else: - self.monitor_aspect = ModeLine.ASPECT_16_9 - - # Backup the settings - (self.originalredgamma, self.originalgreengamma, self.originalbluegamma) = ( - self.redgamma, self.greengamma, self.bluegamma) - self.originalallgamma = self.allgamma - self.originalsettingall = self.settingall - self.original_monitor_aspect = self.monitor_aspect - - def _setXLiveScreen(self,x_live_screen): - self.x_live_screen = x_live_screen - - def _finalizeInit(self): - - if self.x_live_screen is not None and self.x_live_screen.resolutionSupportAvailable(): - self._computeSizesFromXorg() - - (cw,ch,x,x) = self.x_live_screen.getSize() - i = 0 - self.currentsizeindex = 0 - for size in self.available_sizes: - if (cw,ch)==size: - self.currentsizeindex = i - break - i += 1 - - self.currentrefreshrate = self.x_live_screen.getRefreshRate() - self.currentrotation = self.x_live_screen.getRotation() & ( - Screen.RR_Rotate_0 | Screen.RR_Rotate_90 | Screen.RR_Rotate_180 | Screen.RR_Rotate_270) - self.currentreflection = self.x_live_screen.getRotation() & ( - Screen.RR_Reflect_X | Screen.RR_Reflect_Y) - - else: - # There is no live info, so try to collect some info out - # of xorg.conf itself. - - # Cookup some reasonable screen resolutions based on what we know about the monitor. - self._computeSizesFromMonitor() - - (cw,ch) = self.available_sizes[0] - self.currentrefreshrate = None - - # Dig through the Display sections in the xorg.conf Screen section - # and try to find the first resolution/mode. - if self.x_config_screen is not None: - default_depth = self.x_config_screen.defaultdepth - - current_mode_name = None - - for display_section in self.x_config_screen.getSections('display'): - if default_depth is None or display_section.depth==default_depth: - modes_row = display_section.getRow('modes') - if modes_row is not None and len(modes_row)>=1: - current_mode_name = modes_row[0] - break - - if current_mode_name is not None: - for mode in self.mode_list: - if mode.getName()==current_mode_name: - cw = mode.getWidth() - ch = mode.getHeight() - self.currentrefreshrate = mode.getVRefresh() - break - - # Work out the index of the current resolution - i = 0 - for size in self.available_sizes: - if (cw,ch)==size: - self.currentsizeindex = i - break - i += 1 - - if self.currentrefreshrate is None: - self.currentrefreshrate = self.getAvailableRefreshRates()[0] - - self.currentrotation = Screen.RR_Rotate_0 # FIXME - self.currentreflection = 0 # FIXME - - # Gamma settings - if self.x_live_screen is not None: - try: - (self.redgamma, self.greengamma, self.bluegamma, self.allgama, - self.settingall) = self._getGammaFromLiveScreen() - except: - (self.redgamma, self.greengamma, self.bluegamma, self.allgama, - self.settingall) = self._getGammaFromXorg() - else: - (self.redgamma, self.greengamma, self.bluegamma, self.allgama, - self.settingall) = self._getGammaFromXorg() - - self.originalsizeindex = self.currentsizeindex - self.original_size = self.getAvailableResolutions()[self.currentsizeindex] - self.originalrefreshrate = self.currentrefreshrate - self.originalrotation = self.currentrotation - self.originalreflection = self.currentreflection - - self.originalredgamma = self.redgamma - self.originalgreengamma = self.greengamma - self.originalbluegamma = self.bluegamma - - self.originalallgamma = self.allgamma - self.originalsettingall = self.settingall - - def _getGammaFromLiveScreen(self): - """Reads the gamma information from the x server""" - # Read the current gamma settings directly from X. - (redgamma, greengamma, bluegamma) = self.x_live_screen.getGamma() - - # Round the values off to 2 decimal places. - redgamma = round(self.redgamma,2) - greengamma = round(self.greengamma,2) - bluegamma = round(self.bluegamma,2) - - allgamma = redgamma - settingall = redgamma==greengamma==bluegamma - return (redgamma, greengamma, bluegamma, allgamma, settingall) - - def _getGammaFromXorg(self): - """Extracts the gamma information from the xorg configuration""" - # Set some gamma defaults - redgamma = greengamma = bluegamma = allgamma = 1.0 - settingall = True - - # Look for gamma information in xorg.conf - if self.x_config_monitor is not None: - gamma_row = self.x_config_monitor.getRow('gamma') - if gamma_row is not None: - try: - if len(gamma_row)==1: - allgamma = float(gamma_row[0]) - redgamma = greengamma = bluegamma = allgamma - self.settingall = True - elif len(gamma_row.row)==3: - redgamma = float(gamma_row[0]) - greengamma = float(gamma_row[1]) - bluegamma = float(gamma_row[2]) - allgamma = self.redgamma - settingall = False - except ValueError: - pass - return (redgamma, greengamma, bluegamma, allgamma, settingall) - - def _computeSizesFromXorg(self): - all_sizes = self.x_live_screen.getAvailableSizes() - self.available_sizes = [] - - # Some dualhead setups repolonger sizelists, those are unlikely - # to be standard zes, we still want to be able to use them.s - for i in range(len(all_sizes)): - if len(all_sizes[i]) > 2: - self.available_sizes.append(all_sizes[i][:2]) - elif len(alls_sizes[i]) == 2: - if (size[0],size[1]) in self.standard_sizes: - self.available_sizes.append(all_sizes[i]) - self.available_sizes.sort() - - def _computeSizesFromMonitor(self): - monitor_model = self.monitor_model - - if monitor_model is None: - # If there is no monitor model selected, then just use a default - # model so that we at least get some fairly safe resolutions. - monitor_model = GetMonitorModelDB().getMonitorByName("Monitor 800x600") - - self.mode_list = GetMonitorModeDB().getAvailableModes(monitor_model,self.monitor_aspect) - resolutions = set() - for mode in self.mode_list: - pw = mode.getWidth() - ph = mode.getHeight() - if (pw,ph) in self.standard_sizes and pw>=640 and ph>=480: - resolutions.add( (pw,ph) ) - - # Filter the sizes by the amount of video ram that we have. - color_bytes = self._getColorDepth()/8 - if self.gfx_card.getGfxCardModel().getNeedVideoRam(): - video_memory = self.gfx_card.getVideoRam() - else: - video_memory = 65536 # Big enough. - video_memory *= 1024 # Convert to bytes. - - # Filter the list of modes according to available memory. - self.available_sizes = [mode for mode in resolutions if mode[0]*mode[1]*color_bytes <= video_memory] - - self.available_sizes.sort() - - def _getColorDepth(self): - if self.gfx_card.getGfxCardModel().getNeedVideoRam(): - # If this card has limited memory then we fall back to 16bit colour. - if self.gfx_card.getVideoRam() <= 4096: - return 16 # 16bit colour - else: - return 24 # 24bit colour - else: - return 24 - - def getName(self): - try: - return "Screen %i" % (self.gfx_card.setup.getUsedScreens().index(self)+1) - except ValueError: - return "Screen ?" - - def isLive(self): - """Returns True if this screen is currently being used by the X server. - """ - return self.x_live_screen is not None - - def getMonitorModel(self): - """ - - Returns a MonitorModel object or None. - """ - return self.monitor_model - - def setMonitorModel(self,monitor_model): - """ - - Setting the monitor also changes the resolutions that are available. - - """ - self.monitor_model = monitor_model - self._resyncResolution() - - def getMonitorAspect(self): - """ - Get the aspect ratio for the monitor - - Returns one of ModeLine.ASPECT_4_3 or ModeLine.ASPECT_16_9. - """ - return self.monitor_aspect - - def setMonitorAspect(self,aspect): - """Specify the aspect ratio of the monitor. - - Keyword arguments: - aspect -- Aspect ratio. Either the constant ModeLine.ASPECT_4_3 or ModeLine.ASPECT_16_9. - - Setting this also changes the resolutions that are available. - """ - self.monitor_aspect = aspect - self._resyncResolution() - - def _resyncResolution(self): - try: - (preferred_width,preferred_height) = self.getAvailableResolutions()[self.getResolutionIndex()] - except IndexError: - print self.getAvailableResolutions() - (preferred_width,preferred_height) = self.getAvailableResolutions()[-1] - - if self.isResolutionLive(): - self._computeSizesFromXorg() - else: - # The list of resolutions needs to be updated. - self._computeSizesFromMonitor() - - if self.gfx_card.setup.getLayout()==XSetup.LAYOUT_CLONE: - if self.gfx_card.setup.getPrimaryScreen() is self: - # Filter the list of resolutions based on what the secondary screen can show. - secondary_screen = self.gfx_card.setup.getSecondaryScreen() - primary_set = set(self.available_sizes) - secondary_set = set(secondary_screen.available_sizes) - - common_set = primary_set.intersection(secondary_set) - - suitable_resolutions = [] - # Make sure that each resolution also has a common refresh rate. - for resolution in common_set: - primary_rates = self.getAvailableRefreshRatesForResolution(self.available_sizes.index(resolution)) - secondary_rates = secondary_screen.getAvailableRefreshRatesForResolution(secondary_screen.available_sizes.index(resolution)) - - if len(set(primary_rates).intersection(set(secondary_rates)))!=0: - suitable_resolutions.append(resolution) - - suitable_resolutions.sort() - self.available_sizes = suitable_resolutions - - # Now we select a resolution that closely matches the previous resolution. - best_score = 2000000 # big number. - best_index = 0 - resolution_list = self.getAvailableResolutions() - for i in range(len(resolution_list)): - (width,height) = resolution_list[i] - new_score = abs(width-preferred_width) + abs(height-preferred_height) - - if new_score < best_score: - best_index = i - best_score = new_score - self.setResolutionIndex(best_index) - - if self.gfx_card.setup.getLayout()==XSetup.LAYOUT_CLONE: - if self.gfx_card.setup.getSecondaryScreen() is self: - self.gfx_card.setup.getPrimaryScreen()._resyncResolution() - - def isXorgConfigChanged(self): - isroot = os.getuid()==0 - return self.original_monitor_model is not self.monitor_model \ - or self.original_monitor_aspect != self.monitor_aspect \ - or self.isGammaSettingsChanged() \ - or (self.isResolutionSettingsChanged() and (not self.isResolutionLive() or isroot)) - - def getRedGamma(self): - """Get the current red gamma value. - """ - return self.redgamma - - def setRedGamma(self,value): - """Set gamma correction value for red - - This method takes effect immediately on the X server if possible. - - Keyword arguments: - value -- gamma correction value (float) - """ - self.redgamma = value - if self.x_live_screen is not None: - self.x_live_screen.setGamma( (self.redgamma,self.greengamma,self.bluegamma) ) - self.settingall = False - - def getGreenGamma(self): - """Get the current green gamma value - """ - return self.greengamma - - def setGreenGamma(self,value): - """Set gamma correction value for green - - This method takes effect immediately on the X server if possible. - - Keyword arguments: - value -- gamma correction value (float) - """ - self.greengamma = value - if self.x_live_screen is not None: - self.x_live_screen.setGamma( (self.redgamma,self.greengamma,self.bluegamma) ) - self.settingall = False - - def getBlueGamma(self): - """Get the current blue gamma value - """ - return self.bluegamma - - def setBlueGamma(self,value): - """Set gamma correction value for blue - - This method takes effect immediately on the X server if possible. - - Keyword arguments: - value -- gamma correction value (float) - """ - self.bluegamma = value - if self.x_live_screen is not None: - self.x_live_screen.setGamma( (self.redgamma,self.greengamma,self.bluegamma) ) - self.settingall = False - - def getAllGamma(self): - """Get the gamma correction value for all colours. - - Returns a float. - - See isGammaEqual() - """ - return self.allgamma - - def setAllGamma(self,value): - """Set the gamma correction value for all colours. - - Keyword arguments: - value -- gamma correction value (float) - """ - self.allgamma = value - if self.x_live_screen is not None: - self.x_live_screen.setGamma( (self.allgamma,self.allgamma,self.allgamma) ) - self.settingall = True - - def isGammaLive(self): - """Returns true if modifications to the gamma are immediately visible. - """ - return self.x_live_screen is not None - - def isGammaEqual(self): - """Test whether each colour is using the same gamma correction value. - - Returns True if the gamma value is the same for all colours - """ - return self.getRedGamma()==self.getGreenGamma()==self.getBlueGamma() - - def getScreenIndex(self): - return self.gfx_card.getScreens().index(self) - - # Size and resolution - def getResolutionIndex(self): - """Get the current resolution of this screen. - - Returns an index into the list of available resolutions. See - getAvailableResolutions(). - """ - return self.currentsizeindex - - def setResolutionIndex(self,index): - """Set the resolution for this screen. - - This method does not take effect immediately, only after applyResolutionSetttings() - has been called. - - Keyword arguments: - index -- The index of the resolution to use. See getAvailableResolutions(). - """ - self.currentsizeindex = index - - def getAvailableResolutions(self): - """Get the list of available resolutions. - - Returns a list of screen (width,height) tuples. width and height are in - pixels. - """ - return self.available_sizes[:] - - # Rotation - def getRotation(self): - """Get the current rotation settings for this screen. - - Returns one of Screen.RR_Rotate_0, Screen.RR_Rotate_90, - Screen.RR_Rotate_180 or Screen.RR_Rotate_270 - """ - return self.currentrotation - - def setRotation(self,rotation): - """Set the rotation for this screen - - This method does not take effect immediately, only after - applyResolutionSetttings() has been called. See getAvailableRotations() - for how to find out which rotations are supported. - - Keyword arguments: - rotation -- One of Screen.RR_Rotate_0, Screen.RR_Rotate_90, - Screen.RR_Rotate_180 or Screen.RR_Rotate_270 - """ - self.currentrotation = rotation - - def getAvailableRotations(self): - """Get the supported rotations for this screen. - - Returns a bitmask of support rotations for this screen. The returned - integer is the bitwise OR of one or more of the constants here below. - * Screen.RR_Rotate_0 - * Screen.RR_Rotate_90 - * Screen.RR_Rotate_180 - * Screen.RR_Rotate_270 - """ - if self.x_live_screen is not None and self.x_live_screen.resolutionSupportAvailable(): - return self.x_live_screen.getAvailableRotations() & \ - (self.RR_Rotate_0 | self.RR_Rotate_90 | self.RR_Rotate_180 | self.RR_Rotate_270) - else: - return self.RR_Rotate_0 # FIXME - - - # Reflection - def getReflection(self): - """Get the current reflection settings for this screen. - - Returns the reflection settings as a bit string. Use Screen.RR_Reflect_X - and Screen.RR_Reflect_Y as bitmasks to determine which reflections are - in use. - """ - return self.currentreflection - - def setReflection(self,reflection): - """Set the reflection settings for this screen. - - This method does not take effect immediately, only after - applyResolutionSetttings() has been called. See getAvailableReflections() - for how to find out which rotations are supported. - - Keyword arguments: - reflection -- Bit string (Python integer) of desired reflections. - Bitwise OR Screen.RR_Reflect_X and Screen.RR_Reflect_Y - to construct the string. - """ - self.currentreflection = reflection - - def getAvailableReflections(self): - """Get the supported reflections for this screen. - - Returns a bit string (Python integer) of supported reflections. Use - Screen.RR_Reflect_X and Screen.RR_Reflect_Y as bitmasks to determine - which reflections are available. - """ - if self.x_live_screen is not None and self.x_live_screen.resolutionSupportAvailable(): - return self.x_live_screen.getAvailableRotations() & (self.RR_Reflect_X | self.RR_Reflect_Y) - else: - return 0 # FIXME - - # Refresh rates - def getRefreshRateIndex(self): - """Get the current refresh rate index for this screen. - - Returns an index into the list of refresh rates. See getAvailableRefreshRates(). - """ - rates = self.getAvailableRefreshRates() - i = 0 - for r in rates: - if r>=self.currentrefreshrate: - return i - i += 1 - return len(rates)-1 - - def setRefreshRateIndex(self,index): - """Set the refresh rate for this screen. - - Keyword arguments: - index -- Index into the list of refresh rates. See getAvailableRefreshRates(). - """ - self.currentrefreshrate = self.getAvailableRefreshRates()[index] - - def getAvailableRefreshRates(self): - """Get the list of available refresh rates - - Get the list of available refresh rates for the currently selected - resolution. See setResolutionIndex() and getAvailableRefreshRatesForResolution() - - Returns a list of integers in Hz. - """ - return self.getAvailableRefreshRatesForResolution(self.currentsizeindex) - - def getAvailableRefreshRatesForResolution(self,resolution_index): - """Get the list of available refresh rates for the given resolution - - Get the list of available refresh rates for the given resolution. - - Keyword arguments: - resolution_index -- Index into the list of resolutions. - - Returns a list of integers in Hz. - """ - isize = self.available_sizes[resolution_index] - if self.isResolutionLive(): - j = 0 - for size in self.x_live_screen.getAvailableSizes(): - (sw,sh,wm,hm) = size - if isize==(sw,sh): - rates = self.x_live_screen.getAvailableRefreshRates(j) - rates.sort() - return rates - j += 1 - assert False,"Can't find matching screen resolution" - else: - # - rates = [] - for mode in self.mode_list: - if isize==(mode.getWidth(),mode.getHeight()): - rates.append(mode.getVRefresh()) - - rates.sort() - return rates - - # Applying changes. - - def isResolutionLive(self): - return self.x_live_screen is not None and \ - self.x_live_screen.resolutionSupportAvailable() and \ - self.original_monitor_model is self.monitor_model and \ - self.original_monitor_aspect==self.monitor_aspect - - def isResolutionSettingsChanged(self): - try: - current_size = self.getAvailableResolutions()[self.currentsizeindex] - except IndexError: - #FIXME: why does this happen? - return False - return current_size != self.original_size or \ - self.currentrefreshrate != self.originalrefreshrate or \ - self.currentrotation != self.originalrotation or \ - self.currentreflection != self.originalreflection - - def applyResolutionSettings(self): - """Apply any tending resolution changes on the X server if possible. - - - """ - if self.isResolutionSettingsChanged() and self.isResolutionLive(): - # Work out what the correct index is for randr. - (width,height) = self.available_sizes[self.currentsizeindex] - sizeindex = 0 - for size in self.x_live_screen.getAvailableSizes(): - (pw,ph,wm,hm) = size - if pw==width and ph==height: - break - sizeindex += 1 - - rc = self.x_live_screen.setScreenConfigAndRate(sizeindex, \ - self.currentrotation | self.currentreflection, self.currentrefreshrate) - - # FIXME this can fail if the config on the server has been updated. - - def acceptResolutionSettings(self): - """Accept the last resolution change - """ - self.originalsizeindex = self.currentsizeindex - self.original_size = self.getAvailableResolutions()[self.currentsizeindex] - self.originalrefreshrate = self.currentrefreshrate - self.originalrotation = self.currentrotation - self.originalreflection = self.currentreflection - - def revertResolutionSettings(self): - """Revert the last resolution change on the X server - - """ - if self.x_live_screen is not None and self.x_live_screen.resolutionSupportAvailable(): - # Work out what the correct index is for randr. - (width,height) = self.available_sizes[self.originalsizeindex] - sizeindex = 0 - for size in self.x_live_screen.getAvailableSizes(): - (pw,ph,wm,hm) = size - if pw==width and ph==height: - break - sizeindex += 1 - - self.x_live_screen.setScreenConfigAndRate(sizeindex, \ - self.originalrotation | self.originalreflection, self.originalrefreshrate) - # FIXME this can fail if the config on the server has been updated. - - def resetResolutionSettings(self): - """Reset the resolution settings to the last accepted state - - """ - # Restore the resolution settings to their original state. - self.currentsizeindex = self.originalsizeindex - self.currentrefreshrate = self.originalrefreshrate - self.currentrotation = self.originalrotation - self.currentreflection = self.originalreflection - - def isGammaSettingsChanged(self): - return self.redgamma != self.originalredgamma or \ - self.greengamma != self.originalgreengamma or \ - self.bluegamma != self.originalbluegamma or \ - self.allgamma != self.originalallgamma or \ - self.settingall != self.originalsettingall - - def acceptGammaSettings(self): - (self.originalredgamma, self.originalgreengamma, self.originalbluegamma) = ( - self.redgamma, self.greengamma, self.bluegamma) - self.originalallgamma = self.allgamma - self.originalsettingall = self.settingall - - def revertGammaSettings(self): - (self.redgamma, self.greengamma, self.bluegamma) = ( - self.originalredgamma, self.originalgreengamma, self.originalbluegamma) - self.allgamma = self.originalallgamma - self.settingall = self.originalsettingall - - if self.x_live_screen is not None: - if self.settingall: - self.x_live_screen.setGamma( (self.allgamma,self.allgamma,self.allgamma) ) - else: - self.x_live_screen.setGamma( (self.redgamma,self.greengamma,self.bluegamma) ) - - def isGammaSettingsChanged(self): - if self.settingall: - return self.originalallgamma != self.allgamma - else: - return self.originalredgamma != self.redgamma or \ - self.originalgreengamma != self.greengamma or \ - self.originalbluegamma != self.bluegamma - - def reset(self): - if self.isLive(): - self.revertGammaSettings() - self.resetResolutionSettings() - - self.monitor_model = self.original_monitor_model - self.monitor_aspect = self.original_monitor_aspect - - def getRestartHint(self): - if self.original_monitor_model is not self.monitor_model \ - or self.original_monitor_aspect != self.monitor_aspect \ - or (self.isResolutionSettingsChanged() and not self.isResolutionLive()): - return XSetup.RESTART_X - return XSetup.RESTART_NONE - - def _syncXorgConfig(self,x_device): - layout = self.gfx_card.getLayout() - - if self.x_config_screen is None: - self.x_config_screen = self.x_config.makeSection('',['section','screen']) - self.x_config.append(self.x_config_screen) - self.x_config_screen.identifier = self.x_config.createUniqueIdentifier("screen") - self.x_config_screen.device = x_device.identifier - - bit_depth = self.gfx_card.setup._getColorDepth() - self.x_config_screen.defaultdepth = bit_depth - - # Maybe we don't have a X config monitor section. - if self.x_config_monitor is None: - # Make a monitor section. - self.x_config_monitor = self.x_config.makeSection('',['section','monitor']) - self.x_config.append(self.x_config_monitor) - self.x_config_monitor.identifier = self.x_config.createUniqueIdentifier("monitor") - self.x_config_screen.monitor = self.x_config_monitor.identifier - - # Empty the monitor section and fill it in again. - monitor_identifier = self.x_config_monitor.identifier - self.x_config_monitor.clear() - self.x_config_monitor.identifier = monitor_identifier - - if self.monitor_model is not None: - if self.monitor_model.getManufacturer() is not None: - self.x_config_monitor.vendorname = self.monitor_model.getManufacturer() - - self.x_config_monitor.modelname = self.monitor_model.getName() - - if self.monitor_model.getType()!=MonitorModel.TYPE_PLUGNPLAY: - if self.monitor_model.getHorizontalSync() is not None: - hsyncline = self.x_config_monitor.makeLine(None,['HorizSync',self.monitor_model.getHorizontalSync()]) - self.x_config_monitor.append(hsyncline) - - if self.monitor_model.getVerticalSync() is not None: - vsyncline = self.x_config_monitor.makeLine(None,['VertRefresh',self.monitor_model.getVerticalSync()]) - self.x_config_monitor.append(vsyncline) - - # Add a bunch of standard mode lines. - mode_list = GetMonitorModeDB().getAvailableModes(self.monitor_model,self.monitor_aspect) - - if mode_list is not None: - - # Filter the mode list by video memory. - color_bytes = bit_depth/8 - if self.gfx_card.getGfxCardModel().getNeedVideoRam(): - video_memory = self.gfx_card.getVideoRam() - else: - video_memory = 65536 # Big enough. - video_memory *= 1024 # Convert to bytes. - mode_list = [mode for mode in mode_list if mode.getWidth()*mode.getHeight()*color_bytes <= video_memory] - - def mode_cmp(a,b): return cmp(a.getWidth(),b.getWidth()) - mode_list.sort(mode_cmp) - - for mode in mode_list: - modeline = self.x_config_monitor.modeline.makeLine(None,mode.getXorgModeLineList()) - self.x_config_monitor.modeline.append(modeline) - - # Specify the preferred resolution. - - # Get rid of any old display subsections. - for display_section in self.x_config_screen.getSections('display'): - self.x_config_screen.remove(display_section) - - try: - (preferred_width, preferred_height) = self.getAvailableResolutions()[self.currentsizeindex] - preferred_rate = self.getAvailableRefreshRates()[self.getRefreshRateIndex()] - except IndexError, errmsg: - # This is presumed to be better than a crash: - print "Failed to get preferred width, height, or rate - Assuming none. IndexError: ", errmsg - preferred_width = 0 - preferred_height = 0 - preferred_rate = 0 - - # Find the monitor supported mode that best matches what the user has selected. - best_score = 2000000 # big number. - best_index = 0 - for i in range(len(mode_list)): - mode = mode_list[i] - new_score = abs(mode.getWidth()-preferred_width) + \ - abs(mode.getHeight()-preferred_height) + \ - abs(mode.getVRefresh()-preferred_rate) - if new_score < best_score: - best_index = i - best_score = new_score - - # This is all about putting the list of resolutions into a - # sensible preferred order starting with what the user has chosen - # and then the rest of the resolutions. - lower = best_index - 1 - higher = best_index + 1 - len_modes = len(mode_list) - - mode_indexes = [] - mode_indexes.append(best_index) - while lower>=0 or higher=0: - mode_indexes.append(lower) - lower -= 1 - - # Convert the list of resolution indexes into monitor mode names and a modes line for xorg.conf. - mode_list_line = ['modes'] - mode_list_line.extend([ mode_list[mode_index].getName() for mode_index in mode_indexes ]) - - # Create the Display subsections in the Screen section. - display_section = self.x_config_screen.makeSection(None,['SubSection','Display']) - display_section.depth = bit_depth - - # The virtual screen size hack should not be used in combination - # with Xinerama (RandR doesn't work with Xinerama). - if layout!=XSetup.LAYOUT_SINGLE_XINERAMA and self.isLive(): - # Find the largest monitor supported mode. We need this info - # to set the size of the virtual screen. See the big comment - # in displayconfig-restore.py. - virtual_width = max([mode_list[mode_index].getWidth() for mode_index in mode_indexes]) - virtual_height = max([mode_list[mode_index].getHeight() for mode_index in mode_indexes]) - display_section.append(display_section.makeLine(None,["virtual",virtual_width,virtual_height])) - - display_section.append(display_section.makeLine(None,mode_list_line)) - - self.x_config_screen.append(display_section) - - # Set the gamma info too. - if self.settingall: - gamma_row = self.x_config_monitor.makeLine(None,['gamma',str(self.allgamma)]) - else: - gamma_row = self.x_config_monitor.makeLine(None,['gamma',str(self.redgamma),str(self.greengamma),str(self.bluegamma)]) - self.x_config_monitor.append(gamma_row) - - # If resolution changes were not live because the monitor has been changed - # then we also stop them from being live from now on too. - if not self.isResolutionLive(): - self.x_live_screen = None - self.acceptResolutionSettings() - - # The orignal monitor model is now the selected one. => no changes need to be applied now. - self.original_monitor_model = self.monitor_model - self.original_monitor_aspect = self.monitor_aspect - - def _getXorgScreenSection(self): - return self.x_config_screen - - def _getGfxCard(self): - return self.gfx_card - - def __str__(self): - # FIXME string = str(self.getIdentifier()) + " {" - string = " {" - if self.isLive(): - string += "Size: " - string += str(self.getAvailableResolutions()[self.getResolutionIndex()]) - string += " " - else: - string += "Not live, " - if self.monitor_model is not None: - string += "Monitor:" + str(self.monitor_model) - string += "}" - return string - -############################################################################ -class GfxCardModel(object): - """Describes the properties of a particular model of graphics card. - - """ - def __init__(self,name): - self.name = name - self.vendor = None - self.server = None - self.driver = None - self.proprietarydriver = None - self.lines = [] - self.seeobj = None - self.noclockprobe = None - self.unsupported = None - self.driglx = None - self.utahglx = None - self.driglxexperimental = None - self.utahglxexperimental = None - self.badfbrestore = None - self.badfbrestoreexf3 = None - self.multihead = None - self.fbtvout = None - self.needvideoram = None - - def getName(self): return self.name - - def setVendor(self,vendor): self.vendor = vendor - def getVendor(self): return self._get(self.vendor,"getVendor",None) - def setServer(self,server): self.server = server - def getServer(self): return self._get(self.server,"getServer",None) - def setDriver(self,driver): self.driver = driver - def getDriver(self): return self._get(self.driver,"getDriver",None) - def setProprietaryDriver(self,proprietarydriver): self.proprietarydriver = proprietarydriver - def getProprietaryDriver(self): return self._get(self.proprietarydriver,"getProprietaryDriver",None) - def addLine(self,line): self.lines.append(line) - def getLines(self): - if (len(self.lines)==0) and (self.seeobj is not None): - return self.seeobj.getLines() - else: - return self.lines[:] # Copy - - def setNoClockProbe(self,noprobe): self.noclockprobe = noprobe - def getNoClockProbe(self): return self._get(self.noclockprobe,"getNoClockProbe",False) - def setUnsupported(self,unsupported): self.unsupported = unsupported - def getUnsupported(self): return self._get(self.unsupported,"getUnsupported",False) - def setDriGlx(self,on): self.driglx = on - def getDriGlx(self): return self._get(self.driglx,"getDriGlx",False) - def setUtahGlx(self,on): self.utahglx = on - def getUtahGlx(self): return self._get(self.utahglx,"getUtahGlx",False) - def setDriGlxExperimental(self,on): self.driglxexperimental = on - def getDriGlxExperimental(self): return self._get(self.driglxexperimental,"getDriGlxExperimental",False) - def setUtahGlxExperimental(self,on): self.utahglxexperimental = on - def getUtahGlxExperimental(self): return self._get(self.utahglxexperimental,"getUtahGlxExperimental",False) - def setBadFbRestore(self,on): self.badfbrestore = on - def getBadFbRestore(self,proprietary=False): - if proprietary: - driver = self.getProprietaryDriver() - else: - driver = self.getDriver() - if driver in ['i810','intel','fbdev','nvidia','vmware']: - return True - if self.badfbrestore is not None: - return self.badfbrestore - if self.seeobj is not None: - return self.seeobj.getBadFbRestore(proprietary) - return False - def setBadFbRestoreXF3(self,on): self.badfbrestoreexf3 = on - def getBadFbRestoreXF3(self): return self._get(self.badfbrestoreexf3,"getBadFbRestoreXF3",False) - def setMultiHead(self,n): self.multihead = n - def getMultiHead(self): return self._get(self.multihead,"getMultiHead",1) - def setFbTvOut(self,on): self.fbtvout = on - def getFbTvOut(self): return self._get(self.fbtvout,"getFbTvOut",False) - def setNeedVideoRam(self,on): self.needvideoram = on - def getNeedVideoRam(self): return self._get(self.needvideoram,"getNeedVideoRam",False) - def setSee(self,seeobj): self.seeobj = seeobj - - # If the seeobj is set, then all attributes that are not filled in for this - # instance are inheritted from seeobj. - def _get(self,attr,meth,default): - if attr is not None: - return attr - if self.seeobj is not None: - return getattr(self.seeobj,meth)() - else: - return default - - def __str__(self): - return self.getName() - -############################################################################ -gfxcard_model_db_instance = None # Singleton. - -def GetGfxCardModelDB(): - """Returns a GfxCardModelDB instance. - """ - global gfxcard_model_db_instance - # Lazy instantiation. - if gfxcard_model_db_instance is None: - gfxcard_model_db_instance = GfxCardModelDB() - return gfxcard_model_db_instance - -############################################################################ -class GfxCardModelDB(object): - def __init__(self): - # List of gfx card databases, if order of preference. - filename = '/usr/share/ldetect-lst/Cards+' - if not os.path.exists(filename): - filename = os.path.join(data_file_dir,"Cards+") - - # The card DB. A dict mapping card names to card objects. - self.db = {} - # The keys in this dict will be vendor names, values are dicts mapping card names to objects. - self.vendordb = {} - self.driverdb = {} - - self.drivers = self._getAvailableDrivers() - - self.proprietary_drivers = [] - - self._checkProprietaryDrivers() - self._loadDrivers(self.drivers, self.proprietary_drivers) - self._loadDB(filename) - - def getGfxCardModelByName(self,name): - return self.db[name] - - def getGfxCardModelByDriverName(self,driver_name): - return self.driverdb[driver_name] - - def getAllGfxCardModelNames(self): - return self.db.keys() - - def _getDriverDirs(self): - "Returns a list of directories where X driver files may be located" - - # Fallback dir: - defaultDirs = ["/usr/lib/xorg/modules/drivers/"] - - # Get display number: - display_number = 0 - if "DISPLAY" in os.environ: - display_name = os.environ["DISPLAY"] - displayRE = re.compile("^.*:(\d+)\.\d+$") - m = displayRE.match(display_name) - if m: - display_number = int(m.group(1)) - else: - print "failed to parse display number from '%s' - falling back to default (%d)" % (display_name, display_number) - else: - print "$DISPLAY not set - falling back to default number (%d)" % display_number - - # Get the list of module paths from the Xorg log file: - XLogfile = "/var/log/Xorg.%d.log" % display_number - cmd = "awk -F \" ModulePath set to \" '/^\(..\) ModulePath set to (.*)/ {print $2}' %s" % XLogfile - - baseList = os.popen(cmd).readline().strip().strip('"') - if baseList == "": - print "warning: failed to get module paths from '%s' - falling back to default" % XLogfile - return defaultDirs - - pathList = [] - for basePath in baseList.split(","): - pathList.append("%s/drivers/" % basePath) - - return pathList - - def _getAvailableDrivers(self): - """ - Returns the list of available X graphics drivers. - Algorithm taken from Xorg source (see GenerateDriverlist() in xf86Config.C). - """ - - # These are drivers that cannot actually be used in xorg.conf, hence they are hidden: - hiddenDrivers = ( - "atimisc", # seems to be just the internal implementation for ati driver - "dummy", # dummy driver without any output - "v4l", # not an actual video device driver, but just the v4l module - "ztv" # seems to be the TV output module for AMD Geode - ) - - drivers = [] - driverDirectories = self._getDriverDirs() - - driverNameRE = re.compile("^(.+)_drv.(s)?o$") - for ddir in driverDirectories: - try: - driverFiles = os.listdir(ddir) - except OSError: - print "error reading directory '%s'" % ddir - continue - for f in driverFiles: - m = driverNameRE.match(f) - if m: - driverName = m.group(1) - if driverName in drivers: - print "ignoring duplicate driver '%s/%s'" % (ddir, f) - else: - if driverName in hiddenDrivers: - #print "ignoring hidden driver '%s'" % driverName - pass - else: - drivers.append(driverName) - else: - #print "ignoring driver file with invalid name '%s'" % f - pass - #print "found %d drivers" % len(drivers) - return drivers - - def _checkProprietaryDrivers(self): - # Check for the NVidia driver. - # FIXME x86_64 => 'lib64' - - if (os.path.exists("/usr/X11R6/lib/modules/drivers/nvidia_drv.o") and \ - os.path.exists("/usr/X11R6/lib/modules/extensions/libglx.so")) \ - or \ - (os.path.exists("/usr/lib/xorg/modules/drivers/nvidia_drv.o") and \ - os.path.exists("/usr/lib/xorg/modules/libglx.so")) \ - or \ - (os.path.exists("/usr/lib/xorg/modules/drivers/nvidia_drv.so") and \ - os.path.exists("/usr/lib/xorg/modules/extensions/libglx.so")): - self.proprietary_drivers.append("nvidia") - - # Check for the ATI driver - if (os.path.exists("/usr/X11R6/lib/modules/dri/fglrx_dri.so") and \ - os.path.exists("/usr/X11R6/lib/modules/drivers/fglrx_drv.o")) or \ - (os.path.exists("/usr/lib/dri/fglrx_dri.so") and \ - os.path.exists("/usr/lib/xorg/modules/drivers/fglrx_drv.so")): - self.proprietary_drivers.append("fglrx") - - # FIXME MATROX_HAL? - - def _loadDrivers(self, drivers, proprietary_drivers): - # Insert the Driver entries. - for drivername in drivers: - cardobj = GfxCardModel(drivername) - cardobj.setDriver(drivername) - self.db[drivername] = cardobj - self.driverdb[drivername] = cardobj - - if drivername=="nv" and "nvidia" in proprietary_drivers: - cardobj.setProprietaryDriver("nvidia") - self.driverdb["nvidia"] = cardobj - elif drivername=="ati" and "fglrx" in proprietary_drivers: - cardobj.setProprietaryDriver("fglrx") - self.driverdb["fglrx"] = cardobj - - def _loadDB(self,filename): - vendors = ['3Dlabs', 'AOpen', 'ASUS', 'ATI', 'Ark Logic', 'Avance Logic', - 'Cardex', 'Chaintech', 'Chips & Technologies', 'Cirrus Logic', 'Compaq', - 'Creative Labs', 'Dell', 'Diamond', 'Digital', 'ET', 'Elsa', 'Genoa', - 'Guillemot', 'Hercules', 'Intel', 'Leadtek', 'Matrox', 'Miro', 'NVIDIA', - 'NeoMagic', 'Number Nine', 'Oak', 'Orchid', 'RIVA', 'Rendition Verite', - 'S3', 'Silicon Motion', 'STB', 'SiS', 'Sun', 'Toshiba', 'Trident', - 'VideoLogic'] - - cardobj = None - # FIXME the file might be compressed. - fhandle = open(filename,'r') - for line in fhandle.readlines(): - line = line.strip() - if len(line)!=0: - if not line.startswith("#"): - if line.startswith("NAME"): - cardobj = GfxCardModel(line[4:].strip()) - cardname = cardobj.getName() - self.db[cardname] = cardobj - - # Try to extract a vendor name from the card's name. - for vendor in vendors: - if vendor in cardname: - cardobj.setVendor(vendor) - if vendor not in self.vendordb: - self.vendordb[vendor] = {} - self.vendordb[vendor][cardname] = cardobj - break - else: - if "Other" not in self.vendordb: - self.vendordb["Other"] = {} - self.vendordb["Other"][cardname] = cardobj - - elif line.startswith("SERVER"): - cardobj.setServer(line[6:].strip()) - elif line.startswith("DRIVER2"): - driver = line[7:].strip() - if driver in self.proprietary_drivers: - cardobj.setProprietaryDriver(driver) - elif line.startswith("DRIVER"): - cardobj.setDriver(line[6:].strip()) - elif line.startswith("LINE"): - cardobj.addLine(line[4:].strip()) - elif line.startswith("SEE"): - try: - cardobj.setSee(self.db[line[3:].strip()]) - except KeyError: - pass - elif line.startswith("NOCLOCKPROBE"): - cardobj.setNoClockProbe(True) - elif line.startswith("UNSUPPORTED"): - cardobj.setUnsupported(True) - elif line.startswith("DRI_GLX"): - cardobj.setDriGlx(True) - elif line.startswith("UTAH_GLX"): - cardobj.setUtahGlx(True) - elif line.startswith("DRI_GLX_EXPERIMENTAL"): - cardobj.setDriGlxExperimental(True) - elif line.startswith("UTAH_GLX_EXPERIMENTAL"): - cardobj.setUtahGlxExperimental(True) - elif line.startswith("BAD_FB_RESTORE"): - cardobj.setBadFbRestore(True) - elif line.startswith("BAD_FB_RESTORE_XF3"): - cardobj.setBadFbRestoreXF3(True) - elif line.startswith("MULTI_HEAD"): - cardobj.setMultiHead(int(line[10:].strip())) - elif line.startswith("FB_TVOUT"): - cardobj.setFbTvOut(True) - elif line.startswith("NEEDVIDEORAM"): - cardobj.setNeedVideoRam(True) - fhandle.close() - -############################################################################ -class MonitorModel(object): - TYPE_NORMAL = 0 - TYPE_PLUGNPLAY = 1 - TYPE_CUSTOM = 2 - - def __init__(self): - self.name = None - self.manufacturer = None - self.eisaid = None - self.horizontalsync = None - self.verticalsync = None - self.dpms = False - self.type = MonitorModel.TYPE_NORMAL - - def copy(self): - newmonitor = MonitorModel() - newmonitor.name = self.name - newmonitor.manufacturer = self.manufacturer - newmonitor.eisaid = self.eisaid - newmonitor.horizontalsync = self.horizontalsync - newmonitor.verticalsync = self.verticalsync - newmonitor.dpms = self.dpms - return newmonitor - - def getName(self): return self.name - def setName(self,name): self.name = name - def getManufacturer(self): return self.manufacturer - def setManufacturer(self,manufacturer): self.manufacturer = manufacturer - def setEisaId(self,eisaid): self.eisaid = eisaid - def getEisaId(self): return self.eisaid - def setDpms(self,on): self.dpms = on - def getDpms(self): return self.dpms - def getHorizontalSync(self): return self.horizontalsync - def setHorizontalSync(self,horizontalsync): self.horizontalsync = horizontalsync - def getVerticalSync(self): return self.verticalsync - def setVerticalSync(self,verticalsync): self.verticalsync = verticalsync - def setType(self,flag): self.type = flag - def getType(self): return self.type - def __str__(self): - return "{Name:"+self.name+"}" - -############################################################################ -class PlugNPlayMonitorModel(MonitorModel): - def __init__(self,monitor_model_db): - MonitorModel.__init__(self) - self.monitor_detected = False - self.monitor_model_db = monitor_model_db - - def getEisaId(self): - self._detectMonitor() - return self.eisaid - - def getHorizontalSync(self): - self._detectMonitor() - return self.horizontalsync - - def getVerticalSync(self): - self._detectMonitor() - return self.verticalsync - - def _detectMonitor(self): - if not self.monitor_detected: - (eisaid, horizontalsync, verticalsync) = self.monitor_model_db._detectMonitor() - if eisaid is not None: - self.eisaid = eisaid - if horizontalsync is not None: - self.horizontalsync = horizontalsync - if verticalsync is not None: - self.verticalsync = verticalsync - - self.monitor_detected = True - -############################################################################ -monitor_model_db_instance = None # Singleton - -def GetMonitorModelDB(force=False): - """Returns a GetMonitorModelDB instance. - """ - global monitor_model_db_instance - if monitor_model_db_instance is None or force == True: - monitor_model_db_instance = MonitorModelDB() - return monitor_model_db_instance - -############################################################################ -class MonitorModelDB(object): - def __init__(self): - self.db = {} - self.vendordb = {} - self.genericdb = {} - self.customdb = {} - self.custom_counter = 1 - self.monitor_detect_run = False - - # Plug'n Play is a kind of fake entry for monitors that are detected but unknown. - # It's frequency info is filled in by hardware detection or from the X server config. - self._plugnplay = PlugNPlayMonitorModel(self) - self._plugnplay.setName("Plug 'n' Play") - self._plugnplay.setManufacturer(self._plugnplay.getName()) - self._plugnplay.setType(MonitorModel.TYPE_PLUGNPLAY) - # This default is what Xorg claims to use when there is no - # horizontal sync info in the a monitor section. - self._plugnplay.setHorizontalSync("28.0-33.0") - # This default is what Xorg claims to use when there is no - # vertical sync info in the a monitor section. - self._plugnplay.setVerticalSync("43-72") - self.customdb[self._plugnplay.getName()] = self._plugnplay - self.db[self._plugnplay.getName()] = self._plugnplay - - # Load monitors from the shipped database - filename = "/usr/share/ldetect-lst/MonitorsDB" - if not os.path.exists(filename): - filename = os.path.join(data_file_dir,"MonitorsDB") - self.load(filename) - # Load monitors from the custom database - filename = os.path.join(var_data_dir, "CustomMonitorsDB") - if os.path.exists(filename): - self.load(filename) - - def load(self,filename,split=";"): - fhandle = open(filename,'r') - for line in fhandle.readlines(): - line = line.strip() - if len(line)!=0: - if not line.startswith("#"): - try: - parts = line.split(split) - monitorobj = MonitorModel() - monitorobj.setManufacturer(parts[0].strip()) - monitorobj.setName(parts[1].strip()) - monitorobj.setEisaId(parts[2].strip().upper()) - monitorobj.setHorizontalSync(parts[3].strip()) - monitorobj.setVerticalSync(parts[4].strip()) - if len(parts)>=6: - monitorobj.setDpms(parts[5].strip()=='1') - self.db[monitorobj.getName()] = monitorobj - - if monitorobj.getManufacturer() in \ - ["Generic LCD Display", "Generic CRT Display"]: - self.genericdb[monitorobj.getName()] = monitorobj - else: - if monitorobj.getManufacturer() not in self.vendordb: - self.vendordb[monitorobj.getManufacturer()] = {} - self.vendordb[monitorobj.getManufacturer()]\ - [monitorobj.getName()] = monitorobj - - except IndexError: - print "Bad monitor line:",line - fhandle.close() - - def getMonitorByName(self,name): - return self.db.get(name,None) - - def newCustomMonitor(self,name=None): - custom_model = MonitorModel() - if name is None: - name = "Custom %i" % self.custom_counter - custom_model.setName(name) - self.db[custom_model.getName()] = custom_model - self.customdb[name] = custom_model - self.custom_counter += 1 - return custom_model - - def getCustomMonitors(self): - return self.customdb - - def detect(self): - """Detect the attached monitor. - - Returns a 'monitor' object on success, else None. - """ - (eisaid,hrange,vrange) = self._detectMonitor() - - # Look up the EISAID in our database. - if eisaid is not None: - for monitor in self.db: - if eisaid==self.db[monitor].getEisaId(): - return self.db[monitor] - - return self._plugnplay - - def _detectMonitor(self): - if not self.monitor_detect_run: - eisaid = None - hrange = None - vrange = None - - if os.path.isfile("/usr/sbin/monitor-edid"): - # This utility appeared in Mandriva 2005 LE - output = ExecWithCapture("/usr/sbin/monitor-edid",["monitor-edid","-v"]) - for line in output.split("\n"): - if "HorizSync" in line: - hrange = line.split()[1] - elif "VertRefresh" in line: - vrange = line.split()[1] - elif line.startswith("EISA ID:"): - eisaid = line[9:].upper() - - elif os.path.isfile("/usr/sbin/ddcxinfos"): - # This utility _was_ standard on Mandrake 10.1 and earlier. - output = ExecWithCapture("/usr/sbin/ddcxinfos",["ddcxinfos"]) - for line in output.split("\n"): - if "HorizSync" in line: - hrange = line.split()[0] - elif "VertRefresh" in line: - vrange = line.split()[0] - elif "EISA ID=" in line: - eisaid = line[line.find("EISA ID=")+8:].upper() - - elif os.path.isfile("/usr/sbin/ddcprobe"): - # on Debian - """ - ddcprobe's output looks like this: - - ... - eisa: SAM00b1 - ... - monitorrange: 30-81, 56-75 - ... - """ - output = ExecWithCapture("/usr/sbin/ddcprobe",["ddcprobe"]) - for line in output.split("\n"): - if line.startswith("eisa:"): - parts = line.split(":") - if len(parts)>=2: - eisaid = parts[1].strip().upper() - elif line.startswith("monitorrange:"): - parts = line.replace(',','').split() - if len(parts)==3: - hrange = parts[1].strip() - vrange = parts[2].strip() - - self.detected_eisa_id = eisaid - self.detected_h_range = hrange - self.detected_v_range = vrange - self.monitor_detect_run = True - - return (self.detected_eisa_id, self.detected_h_range, self.detected_v_range) - -############################################################################ - -SYNC_TOLERANCE = 0.01 # 1 percent -class ModeLine(object): - ASPECT_4_3 = 0 - ASPECT_16_9 = 1 - - XF86CONF_PHSYNC = 0x0001 - XF86CONF_NHSYNC = 0x0002 - XF86CONF_PVSYNC = 0x0004 - XF86CONF_NVSYNC = 0x0008 - XF86CONF_INTERLACE = 0x0010 - XF86CONF_DBLSCAN = 0x0020 - XF86CONF_CSYNC = 0x0040 - XF86CONF_PCSYNC = 0x0080 - XF86CONF_NCSYNC = 0x0100 - XF86CONF_HSKEW = 0x0200 # hskew provided - XF86CONF_BCAST = 0x0400 - XF86CONF_CUSTOM = 0x0800 # timing numbers customized by editor - XF86CONF_VSCAN = 0x1000 - flags = {"interlace": XF86CONF_INTERLACE, - "doublescan": XF86CONF_DBLSCAN, - "+hsync": XF86CONF_PHSYNC, - "-hsync": XF86CONF_NHSYNC, - "+vsync": XF86CONF_PVSYNC, - "-vsync": XF86CONF_NVSYNC, - "composite": XF86CONF_CSYNC, - "+csync": XF86CONF_PCSYNC, - "-csync": XF86CONF_NCSYNC } - - # Thanks go out to Redhat for this code donation. =) - def __init__(self, elements): - self.name = elements[1].strip('"') - self.clock = float(elements[2]) - self.hdisp = int(elements[3]) - self.hsyncstart = int(elements[4]) - self.hsyncend = int(elements[5]) - self.htotal = int(elements[6]) - self.vdisp = int(elements[7]) - self.vsyncstart = int(elements[8]) - self.vsyncend = int(elements[9]) - self.vtotal = int(elements[10]) - - self.flags = 0 - for i in range(11, len(elements)): - try: - self.flags |= ModeLine.flags[string.lower(elements[i])] - except KeyError: - pass - - def getWidth(self): - return self.hdisp - - def getHeight(self): - return self.vdisp - - def getName(self): - return self.name - - def getVRefresh(self): - vrefresh = self.clock * 1000000.0 / float(self.htotal * self.vtotal) - if self.flags & ModeLine.XF86CONF_INTERLACE: - vrefresh = vrefresh * 2.0 - if self.flags & ModeLine.XF86CONF_DBLSCAN: - vrefresh = vrefresh / 2.0 - return int(round(vrefresh)) - - # Basically copied from xf86CheckModeForMonitor - def supports(self, monitor_hsync, monitor_vsync): - hsync = self.clock * 1000 / self.htotal - for freq in monitor_hsync: - if hsync > freq[0] * (1.0 - SYNC_TOLERANCE) and hsync < freq[1] * (1.0 + SYNC_TOLERANCE): - break - else: - return False - - vrefresh = self.getVRefresh() - for freq in monitor_vsync: - if vrefresh > freq[0] * (1.0 - SYNC_TOLERANCE) and vrefresh < freq[1] * (1.0 + SYNC_TOLERANCE): - return True - return False - - def getXorgModeLineList(self): - row = [self.name, str(self.clock), str(self.hdisp), str(self.hsyncstart), str(self.hsyncend), - str(self.htotal), str(self.vdisp), str(self.vsyncstart), str(self.vsyncend), str(self.vtotal)] - - for (flag_name,flag_bit) in ModeLine.flags.iteritems(): - if self.flags & flag_bit: - row.append(flag_name) - return row - - def __str__(self): - return "ModeLine:"+self.name - -############################################################################ -monitor_mode_db_instance = None # Singleton - - -def GetMonitorModeDB(): - """Returns a GetMonitorModeDB instance. - """ - global monitor_mode_db_instance - if monitor_mode_db_instance is None: - monitor_mode_db_instance = MonitorModeDB() - return monitor_mode_db_instance - -############################################################################ -class MonitorModeDB(object): - def __init__(self): - self.db = {} - self.db169 = {} - - module_dir = os.path.dirname(os.path.join(os.getcwd(),__file__)) - self.load(os.path.join(data_file_dir,"vesamodes")) - self.load(os.path.join(data_file_dir,"extramodes")) - self.load(os.path.join(data_file_dir,"widescreenmodes")) - - # Make a list of screen sizes for the getAllResolutions() method. - self.all_resolutions = [] - for mode in self.db.values()+self.db169.values(): - size = (mode.getWidth(),mode.getHeight()) - if size not in self.all_resolutions: - self.all_resolutions.append(size) - - self.all_resolutions.sort() - - def load(self,filename): - fd = open(filename, 'r') - lines = fd.readlines() - fd.close() - - for line in lines: - if line[0] != "#" and line[0] != '/': - line = line.strip() - elements = line.split() - if line!="": - if len(elements) < 11 or string.lower(elements[0]) != "modeline": - print "Bad modeline found:",line - continue - name = elements[1][1:-1] - new_mode = ModeLine(elements) - - width = new_mode.getWidth() - height = new_mode.getHeight() - if self.aspectRatio(width, height)==ModeLine.ASPECT_4_3: - self.db[name] = new_mode - else: - self.db169[name] = new_mode - - if (width,height)==FALLBACK_RESOLUTION: - # We grab these modes and use them a fallbacks in the widescreen list. - self.db169[name] = new_mode - - @staticmethod - def aspectRatio(width,height): - ratio = float(width)/float(height) - # 4/3 is 1.333333 - # 16/9 is 1.777777 - # We will just consider anything below 1.45 to be standard. - if ratio < 1.45: - return ModeLine.ASPECT_4_3 - else: - return ModeLine.ASPECT_16_9 - - def getAvailableModes(self,monitor,aspect): - """ - Get the list of video modes that this monitor supports. - - Returns a list of modeline objects or None if the available modes for this monitor are unknown. - """ - if monitor.horizontalsync is None or monitor.verticalsync is None: - return None - - result = [] - - hsync_list = self._list_from_string(monitor.getHorizontalSync()) - vsync_list = self._list_from_string(monitor.getVerticalSync()) - - if aspect==ModeLine.ASPECT_4_3: - db = self.db - else: - db = self.db169 - - for modeline in db.values(): - if modeline.supports(hsync_list, vsync_list): - result.append(modeline) - return result - - def getAllResolutions(self): - return self.all_resolutions - - def _list_from_string(self,src): - l = [] - pieces = src.split(",") - for piece in pieces: - tmp = string.split(piece, "-") - if len(tmp) == 1: - l.append( (float(tmp[0].strip()), float(tmp[0].strip())) ) - else: - l.append( (float(tmp[0].strip()), float(tmp[1].strip())) ) - return l - -############################################################################ - -def ranges_to_string(array, length): - stringobj = "" - for i in range(length): - r = array[i] - if stringobj != "": - stringobj = stringobj + "," - if r[0] == r[1]: - stringobj = stringobj + repr(r[0]) - else: - stringobj = stringobj + repr(r[0]) + "-" + repr(r[1]) - return stringobj - - -def main(): - # FIXME: turns this into a real set of unit tests. - SetDataFileDir("ldetect-lst") - - #xs = XSetup() - #xs = XSetup('xorg.conf.test') - xs = XSetup(xorg_config_filename='bug_data/tonio_intel/xorg.conf', - debug_scan_pci_filename="bug_data/tonio_intel/PCIbus.txt") - print str(xs) - return - - #screen1 = xs.getGfxCards()[0].getScreens()[0] - #monitor_db = GetMonitorModelDB() - #new_model = monitor_db.getMonitorByName('Samsung SyncMaster 15GL') - #print new_model - #screen1.setMonitorModel(new_model) - - #screen2 = xs.getGfxCards()[0].getScreens()[1] - #screen2.setMonitorModel(new_model) - - print "getAvailableLayouts(): ",xs.getAvailableLayouts() - xs.getGfxCards()[0].setProprietaryDriver(True) - print str(xs) - xs.setLayout(XSetup.LAYOUT_CLONE) # XSetup.LAYOUT_DUAL. - print "getAvailableLayouts(): ",xs.getAvailableLayouts() - print str(xs) - - #gfxcard_db = GetGfxCardModelDB() - #new_gfxcard_model = gfxcard_db.getGfxCardModelByName('NVIDIA GeForce FX (generic)') - ##'ATI Radeon 8500' - ##'NVIDIA GeForce FX (generic)' - #print new_gfxcard_model - #gfx_card = xs.getGfxCards()[0] - #gfx_card.setProprietaryDriver(False) - #gfx_card.setGfxCardModel(new_gfxcard_model) - xs.writeXorgConfig('xorg.conf.test') - -if __name__=='__main__': - main() diff --git a/displayconfig/displayconfighardwaretab.py b/displayconfig/displayconfighardwaretab.py deleted file mode 100644 index 833dea6..0000000 --- a/displayconfig/displayconfighardwaretab.py +++ /dev/null @@ -1,741 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file '/home/sebas/dev/guidance/trunk/displayconfig/displayconfighardwaretab.ui' -# -# Created: Sat Apr 23 14:39:39 2005 -# by: The PyQt User Interface Compiler (pyuic) 3.13 -# -# WARNING! All changes made in this file will be lost! - - -import sys -from qt import * - -image0_data = [ -"32 32 522 2", -"Qt c None", -".i c #000000", -"bA c #0037a6", -"bU c #0038a6", -"ch c #0038a7", -"bo c #003ba8", -"cA c #003ba9", -"bT c #003ca8", -"bG c #003ca9", -"fp c #020202", -"cS c #0242ae", -"fq c #030303", -"bH c #0341ab", -"cg c #0441ab", -"b1 c #0443ae", -"fo c #050505", -"fB c #060606", -"bS c #0642ad", -"a7 c #0740a5", -"cf c #0744ad", -"fC c #080808", -".5 c #083fa5", -"bn c #0841a5", -"d# c #0848b2", -"bF c #0942a6", -"bh c #0949b1", -".h c #0a0a0a", -"cz c #0a47b0", -"ce c #0a48b0", -"dY c #0a4fb7", -"fI c #0b0b0b", -"b0 c #0b44a9", -"cm c #0b4ab2", -"b2 c #0c4ab1", -"fA c #0e0e0e", -"dk c #0e4eb5", -"bz c #0f4db2", -"b3 c #0f4db3", -"bI c #0f4db4", -".A c #111111", -"cl c #114bad", -"cR c #114eb4", -"cd c #114fb4", -"b4 c #1250b5", -"cG c #1250b6", -"fr c #131313", -"cy c #1351b5", -"dA c #1353b8", -"cn c #1452b6", -"aJ c #1550af", -"bR c #1552b7", -"eR c #161616", -"cQ c #1653b7", -"bp c #1654b7", -"d. c #1654b8", -"a8 c #1656b9", -"cx c #1756b8", -"cF c #1852b2", -"b5 c #1857b9", -"cZ c #1857ba", -".2 c #191919", -"dX c #195cbf", -"cP c #1a58ba", -"cc c #1a59ba", -"#p c #1a5dbf", -"cH c #1b59bb", -"co c #1b5abb", -"ag c #1c1c1c", -"c9 c #1c5abb", -"dH c #1c60c2", -"dg c #1d5ebf", -"a3 c #1e1e1e", -"cY c #1e58b6", -"bJ c #1e5dbd", -"dG c #1f5ebc", -"cp c #1f5ebd", -"aY c #1f5fbf", -"cI c #205ebd", -"b6 c #205fbe", -"dW c #2063c3", -"bX c #212121", -"c8 c #215fbe", -"c0 c #2160bf", -"cb c #2161bf", -"#v c #225db7", -"cq c #2261c0", -"cw c #2262c0", -"df c #235db9", -"by c #2362c0", -"ds c #2364c2", -"cD c #242424", -"bQ c #2463c0", -"cr c #2464c1", -"aj c #2560b9", -"dp c #262626", -"cv c #2665c1", -"c1 c #2665c2", -"aB c #2667c4", -"dI c #266ac7", -".# c #272727", -"dr c #2763bc", -"b7 c #2766c2", -"cJ c #2766c3", -"cs c #2767c2", -"ca c #2767c3", -"eq c #282828", -"cO c #2867c3", -"bg c #2968c3", -"ct c #2968c4", -"cu c #2969c4", -"ab c #296bc7", -"bK c #2a69c5", -"b8 c #2a6ac5", -".6 c #2a6eca", -"#V c #2b66bc", -"cK c #2b6ac6", -"bq c #2b6bc5", -"c7 c #2b6bc6", -".o c #2c2c2c", -"#q c #2c5cb7", -"bi c #2c5eb7", -"bx c #2c6bc6", -"bP c #2c6cc6", -"aK c #2c6cc7", -"#P c #2c6ec8", -"g. c #2d2d2d", -"bB c #2d60b9", -"c# c #2d6dc7", -"cL c #2d6ec7", -"dJ c #2d71cb", -"dV c #2d71cc", -"aX c #2e6dc7", -"b9 c #2e6ec7", -"c. c #2e6ec8", -"fb c #2f2f2f", -"c2 c #2f6ec8", -"a9 c #2f6fc8", -"cT c #3063bb", -"cM c #3070c8", -"bw c #3070c9", -"ak c #3072cb", -"bf c #3171c9", -"br c #3171ca", -"aA c #3271c9", -"cN c #3272c9", -"aW c #3272ca", -"c3 c #3372ca", -"dt c #3372cb", -"dz c #3373ca", -"b. c #3373cb", -"bL c #3374cb", -"dK c #3377cf", -"dU c #3379d0", -"aZ c #3467be", -"aL c #3474cb", -"#o c #3478d0", -"da c #3567bf", -"dZ c #356cc3", -"aa c #3575cc", -"bO c #3576cc", -"#W c #3576ce", -".B c #363636", -"bM c #3676cc", -"be c #3676cd", -"c6 c #3677cd", -"fJ c #373737", -"az c #3777cd", -"bN c #3778cd", -"#T c #383838", -"bv c #3878cd", -"bs c #3878ce", -"#O c #3879ce", -"fZ c #393939", -"dl c #396cc1", -"aM c #3979ce", -"#w c #397bd1", -"dL c #397dd3", -"#n c #397ed3", -"fz c #3a3a3a", -"c4 c #3a7bcf", -"bu c #3a7bd0", -"dT c #3a7fd4", -"aG c #3b3b3b", -"c5 c #3b7bcf", -"bd c #3b7bd0", -"a# c #3b7cd0", -".7 c #3b80d5", -"gh c #3c3c3c", -"dB c #3c70c3", -"ay c #3c7cd1", -"aV c #3c7dd1", -"a4 c #3d3d3d", -"#X c #3d7dd1", -"aN c #3d7ed1", -"dy c #3d7ed2", -"bt c #3e7fd1", -"dh c #3e7fd2", -"dM c #3e83d7", -"bk c #3f3f3f", -"#Q c #3f73c5", -"al c #3f7fd2", -"#N c #3f80d2", -"b# c #3f80d3", -"dS c #3f85d7", -"#x c #4081d3", -"#m c #4084d7", -"f5 c #414141", -"a. c #4182d3", -"aU c #4182d4", -"bY c #424242", -"aC c #4276c6", -"aO c #4282d4", -"ax c #4283d4", -"bc c #4283d5", -"di c #4284d4", -".8 c #4287d9", -"#Y c #4384d5", -"dN c #4389da", -"cW c #444444", -"dj c #4484d5", -"dR c #4489db", -"g# c #454545", -"#M c #4586d6", -"bb c #4587d6", -"dd c #464646", -"ac c #467ac9", -"aT c #4687d7", -"aP c #4788d7", -"#y c #4788d8", -"#l c #478ddc", -"dO c #478ddd", -"er c #484848", -"ba c #4889d7", -"aw c #4889d8", -"am c #488ad8", -".9 c #488edd", -"dE c #494949", -"#Z c #498ad8", -"dx c #498bd9", -"d2 c #4a4a4a", -"aS c #4a8bd9", -"dP c #4a90de", -"aQ c #4b8cda", -"du c #4b8dda", -"#L c #4b8ddb", -"fU c #4c4c4c", -"dw c #4c8eda", -"dv c #4c8edb", -"dQ c #4c92df", -"av c #4d8edb", -"#z c #4d8fdb", -"an c #4d8fdc", -"#9 c #4e8fdc", -"#0 c #4e90dc", -"#k c #4f94e1", -"#. c #4f95e2", -"aR c #5092dd", -"au c #5193de", -"ao c #5294de", -"#K c #5294df", -"#A c #5395df", -"#1 c #5395e0", -"ap c #5597e0", -"at c #5597e1", -"#j c #559ce6", -"## c #579de6", -"#8 c #589ae2", -"aq c #589be2", -"fs c #595959", -"#B c #599be3", -"as c #599ce3", -"ar c #5a9ce3", -"#7 c #5c9fe6", -"#2 c #5d9fe5", -"#i c #5da3ea", -"fH c #5e5e5e", -"#C c #5ea2e7", -"#a c #5ea4eb", -"#J c #5fa1e6", -"gg c #606060", -"#6 c #60a3e7", -"#3 c #60a3e8", -"#5 c #62a4e9", -"#4 c #62a5e9", -"#I c #63a7ea", -"#h c #63aaef", -"#D c #64a7ea", -"#b c #64abef", -".g c #666666", -"f4 c #686868", -"#E c #68abed", -"#g c #69b1f2", -"#H c #6aaeee", -"#F c #6aaeef", -"#c c #6ab1f3", -"#G c #6bafef", -"#f c #6db4f5", -"#d c #6eb5f5", -"#e c #6eb6f6", -".E c #7087ae", -".n c #717171", -"f9 c #757575", -".Y c #758fb7", -"fO c #787878", -"el c #7ba0d7", -".F c #7d98be", -"gf c #7e7e7e", -"f0 c #808080", -"ek c #83a7dc", -"ga c #848484", -".X c #85a2c7", -".a c #868686", -"d5 c #86abdf", -"fy c #878787", -".W c #87a5c9", -"ej c #87abdd", -"d4 c #88aadc", -"f6 c #898989", -".Z c #899cc0", -".G c #8aa7ca", -"ei c #8aafe0", -"fD c #8b8b8b", -".V c #8ba8ca", -".H c #8ca9cb", -"d6 c #8cb1e2", -".U c #8eaccd", -"eh c #8eb3e3", -".I c #8faccd", -"d7 c #90b5e4", -".T c #92afcf", -"em c #92afdd", -".J c #92b0d0", -"eg c #92b7e5", -"d8 c #93b8e6", -".j c #949494", -".S c #95b3d1", -".K c #95b3d2", -"d9 c #96bbe8", -"ge c #979797", -".R c #98b6d3", -".L c #98b6d4", -"e. c #99bfea", -".f c #9a9a9a", -".e c #9b9b9b", -".Q c #9bb9d4", -".M c #9bb9d6", -".d c #9c9c9c", -"ef c #9cc2ec", -".c c #9d9d9d", -"e# c #9dc2eb", -".b c #9e9e9e", -".N c #9ebcd7", -"ee c #9ec4ed", -"ea c #9fc4ee", -".O c #a0bed8", -".P c #a0bfd8", -"ed c #a0c5ee", -"eb c #a0c6ee", -"ec c #a1c6ef", -"gd c #a3a3a3", -"gb c #a4a4a4", -"fa c #a5a5a5", -"gc c #a6a6a6", -"fN c #a8a8a8", -"fc c #acacac", -"fi c #b4b4b4", -"f8 c #b5b5b5", -"fm c #b8b8b8", -"fj c #b9b9b9", -"fl c #bababa", -"fk c #bbbbbb", -"fn c #bcbcbc", -"fx c #bebebe", -"fw c #bfbfbf", -"fh c #c1c1c1", -"fv c #c2c2c2", -"fu c #c3c3c3", -"eQ c #c4c4c4", -"eo c #c6c6c5", -"fE c #c6c6c6", -".4 c #c6c9d0", -"fe c #c7c7c7", -".z c #c8c8c8", -"#u c #c8ccd3", -"fd c #c9c9c9", -"d1 c #cac9c8", -"aF c #cacaca", -"f# c #cbcac9", -"ep c #cbcbcb", -"a2 c #cccccc", -"dD c #cdccca", -"do c #cdcdcd", -"#U c #cdd0d7", -"f. c #cecccc", -"af c #cecece", -"ai c #ced1d8", -"aI c #ced2d9", -"dn c #cfcecd", -"eP c #cfcfcf", -"e9 c #d0cfcf", -"ft c #d0d0d0", -"eO c #d0d0d1", -"dc c #d1d1cf", -"fg c #d1d1d1", -"e8 c #d2d2d1", -"#s c #d2d2d2", -"a6 c #d2d6dc", -".1 c #d3d3d3", -"cV c #d4d3d2", -"eN c #d4d3d3", -"e7 c #d4d4d3", -"f7 c #d4d4d4", -"bm c #d4d7de", -"ff c #d5d5d5", -"eM c #d5d6d6", -"d0 c #d5d7da", -"cC c #d6d5d4", -"e6 c #d6d6d5", -"f3 c #d6d6d6", -"en c #d6d7d9", -"dC c #d6d8db", -"bE c #d6d9e0", -"fY c #d7d7d7", -"eL c #d7d8d7", -".D c #d7d8db", -"bZ c #d7dbe2", -"fX c #d8d8d8", -"e5 c #d8d9d8", -"dm c #d8d9dc", -"cj c #d9d8d7", -"eK c #d9d9d9", -"db c #d9dbde", -"ck c #d9dde4", -"fM c #dadada", -"cU c #dadcdf", -"e4 c #dbdbda", -"eJ c #dbdbdb", -"cB c #dbdde0", -"dF c #dbdfe5", -"bW c #dcdbda", -"eI c #dcdcdc", -"cE c #dce0e6", -"fQ c #dddddd", -"cX c #dde1e8", -"e3 c #dedddc", -"fT c #dedede", -"ci c #dedfe2", -"dq c #dee1e7", -"de c #dee2e8", -"bD c #dfdedc", -"eH c #dfdfdf", -"bV c #dfe1e4", -"e2 c #e0dfdd", -"bC c #e0e2e5", -"bj c #e1e0df", -"eG c #e1e1e1", -"a0 c #e1e3e6", -"aD c #e1e3e7", -"e1 c #e2e1e0", -"eF c #e2e2e2", -"a1 c #e3e2e1", -"eE c #e3e3e3", -"e0 c #e4e2e3", -"aE c #e4e3e1", -"fS c #e4e4e4", -"fR c #e5e5e5", -"eZ c #e6e5e5", -"eD c #e6e6e6", -"fF c #e7e7e7", -"eY c #e8e7e7", -"eC c #e8e8e8", -"eX c #e9e9e8", -"eB c #e9eaea", -"d3 c #e9ecef", -".p c #eaeaea", -"ad c #eaebef", -"eA c #ebebeb", -"eW c #ecebea", -"fP c #ececec", -"ez c #ededec", -"fW c #ededed", -"f2 c #eeeeee", -"ey c #efeeef", -"f1 c #efefef", -"ex c #f0f0f0", -"#R c #f0f2f6", -"ae c #f1f0ef", -".m c #f1f1f1", -"ew c #f1f2f2", -"fL c #f2f2f2", -"fG c #f3f3f3", -"#r c #f3f5f8", -"ev c #f4f3f3", -"eV c #f4f4f3", -".3 c #f4f4f4", -"et c #f4f6f8", -".C c #f5f5f5", -"eU c #f6f6f4", -"#t c #f6f6f6", -"eu c #f6f7f8", -"fV c #f7f7f7", -"ah c #f8f8f8", -".0 c #f8f9fa", -"eT c #f9f7f7", -"aH c #f9f9f9", -"fK c #fafafa", -"eS c #fbfafa", -"a5 c #fbfbfb", -"bl c #fcfcfc", -"es c #fdfdfc", -".k c #fdfdfd", -".y c #fefefe", -".x c #fffcf8", -".w c #fffcf9", -".v c #fffdf9", -".u c #fffef9", -".t c #fffefa", -"#S c #fffefd", -".s c #fffffa", -".r c #fffffc", -".q c #fffffd", -".l c #ffffff", -"Qt.#.a.b.c.c.c.c.c.c.c.c.c.d.d.d.d.d.d.d.d.d.e.e.e.f.f.f.e.g.hQt", -".i.j.k.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.l.m.n.i", -".o.p.l.l.q.r.s.s.s.t.u.v.v.w.x.x.x.v.v.v.v.u.u.u.u.u.s.r.y.l.z.A", -".B.C.l.D.E.F.G.H.I.J.K.L.M.N.O.P.O.N.Q.R.S.T.U.V.W.X.Y.Z.0.l.1.2", -".B.3.l.4.5.6.7.8.9#.###a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r.l#s.2", -".B#t.l#u#v#w#x#y#z#A#B#C#D#E#F#G#H#E#I#J#B#K#L#M#N#O#P#Q#R#S#s.2", -"#T#t.l#U#V#W#X#Y#Z#0#1#B#2#3#4#4#5#6#7#8#A#9#ya.a#aaabacadaeafag", -"#Tah.laiajak#Oal#Yamanaoapaqararas#8atauavawaxayazaAaBaCaDaEaFag", -"aGaH.laIaJaKaLaMaNaOaPaQanaRauauauaR#zaSaTaUaVazaWaXaYaZa0a1a2a3", -"a4a5.la6a7a8a9b.aza#b##Y#M#y#Z#Z#Zbabbbc#NbdbebfaXbgbhbia0bja2a3", -"bkbl.lbmbnbobpbqbraabsa#bt#N#x#x#x#NaNbubvaLbwbxbybzbAbBbCbDa2a3", -"bkbl.lbEbFbGbHbIbJbKbwbLbMbNbsbsbvazbOb.bwbPbQbRbSbTbUbBbVbWa2bX", -"bY.k.lbZb0b1b2b3b4b5b6b7b8aXb9c.c.c#bqcacbcccdcecfcgchbBcicja2bX", -"bY.y.lckclcmcnb5cocpcqcrcsctcucuctcacvcwcpcocxcyb3czcAbBcBcCa2cD", -"bY.l.lcEcFcGcHcIbycJcKcLcMbfcNcNbfcMaXbqcObQcpcPcQcRcScTcUcVa2cD", -"cW.l.lcXcYcZc0c1b8c2c3bMaMc4c5c5c4aMc6b.a9c7c1c8c9d.d#dadbdca2cD", -"dd.l.ldedfdgcac#bfbec4dh#xdidjdjdiaUdhbdazbrbPcJcbc9dkdldmdndodp", -"dd.l.ldqdrdsaKdtbv#XaxaTamdudvdwaQdxaTaxdy#OdzbPcJc0dAdBdCdDa2dp", -"dE.l.ldFdGdHdIdJdKdLdMdNdOdPdQdQdP.9dRdSdTdUdVdIdWdXdYdZd0d1a2dp", -"d2.l.ld3d4d5d6d7d8d9e.e#eaebececedeeefe.d9egeheiejekelemeneoepeq", -"er.leseteu#tevewexeyezeAeBeCeDeEeFeGeHeIeJeKeLeMeN#seOeP.zeQa2.#", -"eRaf.l.yeseSeTeUeVaeeWeXeYeZe0e1e2e3e4e5e6cCcCe7e8e9f.f#.zeJfa.i", -"Qtfbfc#sdoa2epfdeQfeff.1#sfgePafdoa2epaFaFfhfifjfkflfjfmfn.jag.i", -"Qt.i.ifofofpfqfqfrfsfeftepfdfeeQfufvfwfxfxfyfzfA.ifBfCfCfC.i.iQt", -"QtQtQtQtQtQtfzfDfEeAfteDeAeCeCeCfFfFeCeAffeDfGfifHfIQtQtQtQtQtQt", -"QtQtQtQtQtfJfg.l.l.l.meJeA.CaHaHfKahfLfM.1aH.l.l.lfNfCQtQtQtQtQt", -"QtQtQtQtQtfO.l.ka5aH#tfPfQeHfReDfSeIaffda2fTbla5.l.lfUQtQtQtQtQt", -"QtQtQtQtQtfHfVfVfLfL.mfW.peEeIeJfXfYeJeHfF.mfLfLfKfPfZQtQtQtQtQt", -"QtQtQtQtQtfBf0eFf1f1fP.p.p.p.p.p.p.peAfPfPfWf1f2f3f4.iQtQtQtQtQt", -"QtQtQtQtQtQt.if5f6fkfYeFeEeEfSfSfSfSeEeEeFf7f8f9g..i.iQtQtQtQtQt", -"QtQtQtQtQtQtQt.i.i.2g#.gga.fgbgcgcgdgegfgggh.A.i.iQtQtQtQtQtQtQt", -"QtQtQtQtQtQtQtQtQtQt.i.i.ifqfofpfpfofq.i.i.i.iQtQtQtQtQtQtQtQtQt" -] - -class Form1(QDialog): - def __init__(self,parent = None,name = None,modal = 0,fl = 0): - QDialog.__init__(self,parent,name,modal,fl) - - self.image0 = QPixmap(image0_data) - - if not name: - self.setName("Form1") - - - - self.groupBox3 = QGroupBox(self,"groupBox3") - self.groupBox3.setGeometry(QRect(10,320,680,133)) - self.groupBox3.setColumnLayout(0,Qt.Vertical) - self.groupBox3.layout().setSpacing(6) - self.groupBox3.layout().setMargin(11) - groupBox3Layout = QHBoxLayout(self.groupBox3.layout()) - groupBox3Layout.setAlignment(Qt.AlignTop) - - layout92 = QGridLayout(None,1,1,0,6,"layout92") - - self.textLabel2_4 = QLabel(self.groupBox3,"textLabel2_4") - - layout92.addWidget(self.textLabel2_4,0,1) - - self.textLabel5 = QLabel(self.groupBox3,"textLabel5") - - layout92.addWidget(self.textLabel5,1,2) - - self.textLabel1_4 = QLabel(self.groupBox3,"textLabel1_4") - self.textLabel1_4.setAlignment(QLabel.WordBreak | QLabel.AlignVCenter) - - layout92.addMultiCellWidget(self.textLabel1_4,2,2,0,3) - - self.comboBox4 = QComboBox(0,self.groupBox3,"comboBox4") - - layout92.addWidget(self.comboBox4,1,3) - - self.comboBox2 = QComboBox(0,self.groupBox3,"comboBox2") - - layout92.addWidget(self.comboBox2,0,3) - - self.textLabel3 = QLabel(self.groupBox3,"textLabel3") - - layout92.addWidget(self.textLabel3,0,0) - - self.kPushButton1 = KPushButton(self.groupBox3,"kPushButton1") - - layout92.addMultiCellWidget(self.kPushButton1,1,1,0,1) - - self.textLabel4 = QLabel(self.groupBox3,"textLabel4") - - layout92.addWidget(self.textLabel4,0,2) - groupBox3Layout.addLayout(layout92) - - self.groupBox1 = QGroupBox(self,"groupBox1") - self.groupBox1.setGeometry(QRect(10,10,320,300)) - self.groupBox1.setSizePolicy(QSizePolicy(7,1,0,0,self.groupBox1.sizePolicy().hasHeightForWidth())) - - self.pixmapLabel1 = QLabel(self.groupBox1,"pixmapLabel1") - self.pixmapLabel1.setGeometry(QRect(11,33,16,17)) - self.pixmapLabel1.setSizePolicy(QSizePolicy(0,0,0,0,self.pixmapLabel1.sizePolicy().hasHeightForWidth())) - self.pixmapLabel1.setScaledContents(1) - - self.textLabel2 = QLabel(self.groupBox1,"textLabel2") - self.textLabel2.setGeometry(QRect(19,45,60,17)) - self.textLabel2.setSizePolicy(QSizePolicy(1,1,0,0,self.textLabel2.sizePolicy().hasHeightForWidth())) - - self.textLabel2_3 = QLabel(self.groupBox1,"textLabel2_3") - self.textLabel2_3.setGeometry(QRect(85,45,213,17)) - self.textLabel2_3.setSizePolicy(QSizePolicy(3,1,0,0,self.textLabel2_3.sizePolicy().hasHeightForWidth())) - - self.textLabel1_3 = QLabel(self.groupBox1,"textLabel1_3") - self.textLabel1_3.setGeometry(QRect(80,20,213,17)) - self.textLabel1_3.setSizePolicy(QSizePolicy(3,1,0,0,self.textLabel1_3.sizePolicy().hasHeightForWidth())) - - self.textLabel1 = QLabel(self.groupBox1,"textLabel1") - self.textLabel1.setGeometry(QRect(19,22,60,17)) - self.textLabel1.setSizePolicy(QSizePolicy(1,1,0,0,self.textLabel1.sizePolicy().hasHeightForWidth())) - - self.pushButton2 = QPushButton(self.groupBox1,"pushButton2") - self.pushButton2.setGeometry(QRect(160,70,144,26)) - self.pushButton2.setSizePolicy(QSizePolicy(5,1,0,0,self.pushButton2.sizePolicy().hasHeightForWidth())) - - self.groupBox2 = QGroupBox(self,"groupBox2") - self.groupBox2.setGeometry(QRect(350,10,348,300)) - self.groupBox2.setSizePolicy(QSizePolicy(5,1,0,0,self.groupBox2.sizePolicy().hasHeightForWidth())) - - LayoutWidget = QWidget(self.groupBox2,"layout11") - LayoutWidget.setGeometry(QRect(12,24,324,44)) - layout11 = QHBoxLayout(LayoutWidget,11,6,"layout11") - - self.pixmapLabel3 = QLabel(LayoutWidget,"pixmapLabel3") - self.pixmapLabel3.setSizePolicy(QSizePolicy(0,0,0,0,self.pixmapLabel3.sizePolicy().hasHeightForWidth())) - self.pixmapLabel3.setPixmap(self.image0) - self.pixmapLabel3.setScaledContents(1) - layout11.addWidget(self.pixmapLabel3) - - layout10 = QGridLayout(None,1,1,0,6,"layout10") - - self.textLabel2_2_2 = QLabel(LayoutWidget,"textLabel2_2_2") - self.textLabel2_2_2.setSizePolicy(QSizePolicy(3,1,0,0,self.textLabel2_2_2.sizePolicy().hasHeightForWidth())) - - layout10.addWidget(self.textLabel2_2_2,1,1) - - self.textLabel1_2_2 = QLabel(LayoutWidget,"textLabel1_2_2") - self.textLabel1_2_2.setSizePolicy(QSizePolicy(4,1,0,0,self.textLabel1_2_2.sizePolicy().hasHeightForWidth())) - - layout10.addWidget(self.textLabel1_2_2,0,1) - - self.textLabel1_2 = QLabel(LayoutWidget,"textLabel1_2") - self.textLabel1_2.setSizePolicy(QSizePolicy(1,1,0,0,self.textLabel1_2.sizePolicy().hasHeightForWidth())) - - layout10.addWidget(self.textLabel1_2,0,0) - - self.textLabel2_2 = QLabel(LayoutWidget,"textLabel2_2") - self.textLabel2_2.setSizePolicy(QSizePolicy(1,1,0,0,self.textLabel2_2.sizePolicy().hasHeightForWidth())) - - layout10.addWidget(self.textLabel2_2,1,0) - layout11.addLayout(layout10) - - self.pushButton2_2 = QPushButton(self.groupBox2,"pushButton2_2") - self.pushButton2_2.setGeometry(QRect(180,70,158,26)) - self.pushButton2_2.setSizePolicy(QSizePolicy(5,1,0,0,self.pushButton2_2.sizePolicy().hasHeightForWidth())) - - self.languageChange() - - self.resize(QSize(702,472).expandedTo(self.minimumSizeHint())) - self.clearWState(Qt.WState_Polished) - - - def languageChange(self): - self.setCaption(self.__tr("Form1")) - self.groupBox3.setTitle(self.__tr("Default Display Settings")) - self.textLabel2_4.setText(self.__tr("1280x1024 @ 60Hz")) - self.textLabel5.setText(self.__tr("DPI:")) - self.textLabel1_4.setText(self.__tr("These settings are defaults. Each user of this computer may specify their own personal settings.")) - self.comboBox4.clear() - self.comboBox4.insertItem(self.__tr("75 DPI (small fonts)")) - self.comboBox4.insertItem(self.__tr("100 DPI (large fonts)")) - self.comboBox4.insertItem(self.__tr("Auto (84 DPI)")) - self.comboBox2.clear() - self.comboBox2.insertItem(self.__tr("Millions (24bit)")) - self.textLabel3.setText(self.__tr("Screen size:")) - self.kPushButton1.setText(self.__tr("Use current settings as system default")) - self.textLabel4.setText(self.__tr("Colors:")) - self.groupBox1.setTitle(self.__tr("Graphics Card")) - self.textLabel2.setText(self.__tr("Memory:")) - self.textLabel2_3.setText(self.__tr("32 Mb")) - self.textLabel1_3.setText(self.__tr("GeForce 2")) - self.textLabel1.setText(self.__tr("Name:")) - self.pushButton2.setText(self.__tr("Configure...")) - self.groupBox2.setTitle(self.__tr("Monitor")) - self.textLabel2_2_2.setText(self.__tr("1600x1200 @ 60Hz")) - self.textLabel1_2_2.setText(self.__tr("Philips 107S")) - self.textLabel1_2.setText(self.__tr("Name:")) - self.textLabel2_2.setText(self.__tr("Max. Resolution:")) - self.pushButton2_2.setText(self.__tr("Configure...")) - - - def __tr(self,s,c = None): - return tqApp.translate("Form1",s,c) - -if __name__ == "__main__": - a = QApplication(sys.argv) - QObject.connect(a,SIGNAL("lastWindowClosed()"),a,SLOT("quit()")) - w = Form1() - a.setMainWidget(w) - w.show() - a.exec_loop() diff --git a/displayconfig/displayconfigwidgets.py b/displayconfig/displayconfigwidgets.py deleted file mode 100644 index 009fe7e..0000000 --- a/displayconfig/displayconfigwidgets.py +++ /dev/null @@ -1,809 +0,0 @@ - -from qt import * -from tdecore import * -from tdeui import * -import os -from displayconfigabstraction import * - -# Running as the root user or not? -isroot = os.getuid()==0 - -############################################################################ -class ResizeSlider(QVGroupBox): - """ An abstracted QSlider in a nice box to change the resolution of a screen """ - def __init__(self,parent): - # Screen size group - QVGroupBox.__init__(self,parent) - self.updating_gui = True - self._buildGUI() - self.updating_gui = False - - def _buildGUI(self): - self.setTitle(i18n("Screen Size")) - self.setInsideSpacing(KDialog.spacingHint()) - self.setInsideMargin(KDialog.marginHint()) - - hbox3 = QHBox(self) - hbox3.setSpacing(KDialog.spacingHint()) - label = QLabel(hbox3,"textLabel2_4") - label.setText(i18n("Lower")) - self.screensizeslider = QSlider(hbox3,"slider1") - self.screensizeslider.setMinValue(0) - self.screensizeslider.setMaxValue(4) - self.screensizeslider.setPageStep(1) - self.screensizeslider.setOrientation(QSlider.Horizontal) - self.screensizeslider.setTickmarks(QSlider.Below) - self.connect(self.screensizeslider,SIGNAL("valueChanged(int)"),self.slotResolutionChange) - label = QLabel(hbox3) - label.setText(i18n("Higher")) - - self.resolutionlabel = QLabel(self) - self.resolutionlabel.setText("640x400") - - def setScreen(self, screen): - self.updating_gui = True - self.screen = screen - self.screensizeslider.setMaxValue(len(screen.getAvailableResolutions())-1) - self.screensizeslider.setValue(screen.getResolutionIndex()) - self.updating_gui = False - self.setResolutionIndex(screen.getResolutionIndex()) - - def slotResolutionChange(self,i): - """ Pass signal from slider through to App """ - if self.updating_gui: - return - self.setResolutionIndex(i) - self.emit(PYSIGNAL("resolutionChange(int)"),(i,)) - - def setMaxValue(self,value): - self.updating_gui = True - self.screensizeslider.setMaxValue(value) - self.updating_gui = False - - def setMinValue(self,value): - self.updating_gui = True - self.screensizeslider.setMinValue(value) - self.updating_gui = False - - def setValue(self,value): - self.updating_gui = True - self.screensizeslider.setValue(value) - self.updating_gui = False - - def value(self): - return self.screensizeslider.value() - - def setResolutionLabel(self,text): - self.resolutionlabel.setText(text) - - def setResolutionIndex(self,i): - self.updating_gui = True - width,height = self.screen.getAvailableResolutions()[i] - self.setResolutionLabel(i18n("%1 x %2").arg(width).arg(height)) - self.updating_gui = False - -############################################################################ -class MonitorPreview(QWidget): - """ A ResizableMonitor is an Image in a grid which has resizable edges, - fixed-size corners and is thus expandable. """ - ROTATE_0 = 0 - ROTATE_90 = 1 - ROTATE_180 = 2 - ROTATE_270 = 3 - - def __init__(self, parent=None, imagedir="", name=None): - QWidget.__init__(self,parent) - - self.rotation = MonitorPreview.ROTATE_0 - - self.screen_width = 1280 - self.screen_height = 1024 - - self.reflect_x = False - self.reflect_y = False - - self.setBackgroundMode(Qt.NoBackground) - - self.imagedir = imagedir + "monitor_resizable/" - - self.image_monitor = QPixmap(self.imagedir+"monitor.png") - self.image_monitor_wide = QPixmap(self.imagedir+"monitor_wide.png") - self.image_monitor_r90 = QPixmap(self.imagedir+"monitor_r90.png") - self.image_monitor_wide_r90 = QPixmap(self.imagedir+"monitor_wide_r90.png") - - self.image_background = QPixmap(self.imagedir+"background.png") - self.image_background_wide = QPixmap(self.imagedir+"background_wide.png") - self.image_background_r90 = QPixmap(self.imagedir+"background_r90.png") - self.image_background_wide_r90 = QPixmap(self.imagedir+"background_wide_r90.png") - - self.image_window = QPixmap(self.imagedir+"window_4th.png") - self.image_window_bottom_left = QPixmap(self.imagedir+"window_bottom_left_4th.png") - self.image_window_bottom_right = QPixmap(self.imagedir+"window_bottom_right_4th.png") - - def sizeHint(self): - max_width = max(self.image_monitor.width(), self.image_monitor_wide.width(), - self.image_monitor_r90.width(), self.image_monitor_wide_r90.width()) - max_height = max(self.image_monitor.height(), self.image_monitor_wide.height(), - self.image_monitor_r90.height(), self.image_monitor_wide_r90.height()) - return QSize(max_width, max_height) - - def sizePolicy(self): - return QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) - - def paintEvent(self,paint_event): - screen_width = self.screen_width - screen_height = self.screen_height - - # Widescreen format: preview width: 176, height: 99, 16:9 - is_wide = abs(float(screen_width)/float(screen_height)-16.0/9.0) < 0.2 - - if not is_wide: - preview_screen_width = 152 - preview_screen_height = 114 - else: - preview_screen_width = 176 - preview_screen_height = 99 - - if self.rotation==MonitorPreview.ROTATE_0 or self.rotation==MonitorPreview.ROTATE_180: - # Normal, landscape orientation. - if not is_wide: - screen_x_offset = 23 - screen_y_offset = 15 - image_background = self.image_background - else: - screen_x_offset = 23 - screen_y_offset = 29 - image_background = self.image_background_wide - else: - # Portrait orientation. Swap some values around. - t = preview_screen_width - preview_screen_width = preview_screen_height - preview_screen_height = t - - t = screen_width - screen_width = screen_height - screen_height = t - - if not is_wide: - screen_x_offset = 42 - screen_y_offset = 15 - image_background = self.image_background_r90 - else: - screen_x_offset = 50 - screen_y_offset = 15 - image_background = self.image_background_wide_r90 - - # Draw everything off screen in a buffer - preview_buffer = QPixmap(preview_screen_width,preview_screen_height) - painter = QPainter(preview_buffer) - - # Draw the background on the monitor's screen - painter.drawPixmap(0, 0, image_background) - - # Work out the scaling factor for the eye candy in the preview winodw. - scale_factor = 4.0*float(preview_screen_width) / float(screen_width) - transform_matrix = QWMatrix().scale(scale_factor,scale_factor) - - # Draw the little window on the background - scaled_window = self.image_window.xForm(transform_matrix) - - sx = (preview_screen_width-scaled_window.width())/2 - sy = (preview_screen_height-scaled_window.height())/2 - if sx < 0: - sx = 0 - if sy < 0: - sy = 0 - sw = scaled_window.width() - if sw>preview_screen_width: - sw = preview_screen_width - - sh = scaled_window.height() - if sh>preview_screen_height: - sh = preview_screen_height - - painter.drawPixmap(sx, sy, scaled_window, 0, 0, sw, sh) - - # Now draw the clock in the lower right corner - scaled_window = self.image_window_bottom_right.xForm(transform_matrix) - - sx = preview_screen_width - scaled_window.width() - sy = preview_screen_height - scaled_window.height() - sw = scaled_window.width()#preview_screen_width/2 - sh = scaled_window.height() - - sx_offset = 0 - if sx<0: # Some simple clipping for the left edge - sx_offset = -sx - sw = preview_screen_width - sx = 0 - - painter.drawPixmap(sx, sy, scaled_window, sx_offset, 0, sw, sh) - - # Now draw the k menu in the lower left corner - scaled_window = self.image_window_bottom_left.xForm(transform_matrix) - - sx = 0 - sy = preview_screen_height - scaled_window.height() - sw = preview_screen_width/2 # Just draw on the left side of the preview. - sh = scaled_window.height() - painter.drawPixmap(sx, sy, scaled_window, 0, 0, sw, sh) - painter.end() - - # Transform the preview image. Do reflections. - reflect_x = 1 - if self.reflect_x: - reflect_x = -1 - reflect_y = 1 - if self.reflect_y: - reflect_y = -1 - - preview_buffer = preview_buffer.xForm(QWMatrix().scale(reflect_x,reflect_y)) - - # Draw the monitor on another buffer. - off_screen_buffer = QPixmap(self.width(),self.height()) - off_screen_painter = QPainter(off_screen_buffer) - - # Erase the buffer first - off_screen_painter.setBackgroundColor(self.paletteBackgroundColor()) - off_screen_painter.eraseRect(0, 0, off_screen_buffer.width(), off_screen_buffer.height()) - - if self.rotation==MonitorPreview.ROTATE_0 or self.rotation==MonitorPreview.ROTATE_180: - if not is_wide: - image_monitor = self.image_monitor - else: - image_monitor = self.image_monitor_wide - else: - if not is_wide: - image_monitor = self.image_monitor_r90 - else: - image_monitor = self.image_monitor_wide_r90 - - top_edge = self.height()-image_monitor.height() - left_edge = (self.width()-image_monitor.width())/2 - - # Draw the monitor - off_screen_painter.drawPixmap(left_edge, top_edge, image_monitor) - off_screen_painter.end() - - # Copy the preview onto the off screen buffer with the monitor. - bitBlt(off_screen_buffer, left_edge+screen_x_offset, top_edge+screen_y_offset, preview_buffer, - 0, 0, preview_buffer.width(), preview_buffer.height(),Qt.CopyROP, False) - - # Update the widget - bitBlt(self, 0, 0, off_screen_buffer, 0, 0, self.width(), self.height(), Qt.CopyROP, False) - - def setResolution(self,width,height): - self.screen_width = width - self.screen_height = height - self.update() - - def setRotation(self, rotation): - self.rotation = rotation - self.update() - - def setReflectX(self, enable): - self.reflect_x = enable - self.update() - - def setReflectY(self, enable): - self.reflect_y = enable - self.update() - -############################################################################ -class DualMonitorPreview(QWidget): - """ This is the Widget to use elsewhere. It consists of a canvas and an - arbitrary number of gizmos on the canvas. The gizmos can be dragged and - dropped around. Painting is double-buffered so flickering should not occur. - """ - def __init__(self, parent, size, imagedir): - QWidget.__init__(self,parent) - self.setBackgroundMode(Qt.NoBackground) - - self.imagedir = imagedir + "dualhead/" - self.snap_distance = 25 - self.snapping = True - self.size = size - self.position = XSetup.POSITION_LEFTOF - - self.current_screen = 0 - - self.resize(size,size) - self.setMouseTracking(True) - - self.gizmos = [] - self.gizmos.append(MovingGizmo("Monitor 1","monitor_1.png",QPoint(20,50),self.imagedir)) - self.gizmos.append(MovingGizmo("Monitor 2","monitor_2.png",QPoint(180,50),self.imagedir)) - - self.gizmos[0].setWidth(1280) - self.gizmos[0].setHeight(1024) - self.gizmos[0].setHighlightColor(self.colorGroup().highlight()) - self.gizmos[1].setWidth(1280) - self.gizmos[1].setHeight(1024) - self.gizmos[1].setHighlightColor(self.colorGroup().highlight()) - - self.dragging = False - self.dragging_gizmo = 0 - self.drag_handle = None - - self._positionGizmos() - self.setCurrentScreen(0) - - def minimumSizeHint(self): - return QSize(self.size,self.size) - - def setCurrentScreen(self,screen): - self.current_screen = screen - self.gizmos[0].setHighlight(screen==0) - self.gizmos[1].setHighlight(screen==1) - self.update() - - def getCurrentScreen(self): - return self.current_screen - - def setPosition(self,position): - self.position = position - self._positionGizmos() - self.update() - - def getPosition(self): - """Returns one of XSetup.POSITION_LEFTOF, XSetup.POSITION_RIGHTOF, - XSetup.POSITION_ABOVE or XSetup.POSITION_BELOW. - """ - return self.position - - def setScreenResolution(self,screenNumber,width,height): - self.gizmos[screenNumber].setWidth(width) - self.gizmos[screenNumber].setHeight(height) - self.setPosition(self.position) # Reposition and force update. - - def _positionGizmos(self): - g1 = self.gizmos[0] - g2 = self.gizmos[1] - - # Treat POSITION_RIGHTOF and POSITION_BELOW as LEFTOF and ABOVE with the - # gizmos swapped around. - if self.position==XSetup.POSITION_RIGHTOF or self.position==XSetup.POSITION_BELOW: - tmp = g1 - g1 = g2 - g2 = tmp - - if self.position==XSetup.POSITION_LEFTOF or self.position==XSetup.POSITION_RIGHTOF: - x = -g1.getWidth() - y = -max(g1.getHeight(), g2.getHeight())/2 - g1.setPosition(QPoint(x,y)) - - x = 0 - g2.setPosition(QPoint(x,y)) - - else: - x = -max(g1.getWidth(), g2.getWidth())/2 - y = -g1.getHeight() - g1.setPosition(QPoint(x,y)) - - y = 0 - g2.setPosition(QPoint(x,y)) - - def mousePressEvent(self,event): - # Translate the point in the window into our gizmo space. - world_point = self._getGizmoMatrix().invert()[0].map(event.pos()) - - # If the mouse is in the air space of a gizmo, then we change the cursor to - # indicate that the gizmo can be dragged. - for giz in self.gizmos: - if giz.getRect().contains(world_point): - self.setCurrentScreen(self.gizmos.index(giz)) - break - else: - return - - # Pressing down the mouse button on a gizmo also starts a drag operation. - self.dragging = True - self.dragging_gizmo = self.getCurrentScreen() - self.drag_handle = world_point - self.gizmos[self.dragging_gizmo].getPosition() - - # Let other people know that a gizmo has been selected. - self.emit(PYSIGNAL("pressed()"), (self.current_screen,) ) - - def mouseReleaseEvent(self,event): - if not self.dragging: - return - - # Translate the point in the window into our gizmo space. - world_point = self._getGizmoMatrix().invert()[0].map(event.pos()) - - if self._moveGizmo(world_point): - self.setPosition(self.drag_position) - self.emit(PYSIGNAL("positionChanged()"), (self.position,) ) - else: - self.setPosition(self.position) - self.dragging = False - - def mouseMoveEvent(self,event): - # Translate the point in the window into our gizmo space. - world_point = self._getGizmoMatrix().invert()[0].map(event.pos()) - - # If the mouse is in the air space of a gizmo, then we change the cursor to - # indicate that the gizmo can be dragged. - for giz in self.gizmos: - if giz.getRect().contains(world_point): - self.setCursor(QCursor(Qt.SizeAllCursor)) - break - else: - self.unsetCursor() - - if self.dragging: - self._moveGizmo(world_point) - self.update() - - return - - def _moveGizmo(self,worldPoint): - new_drag_position = worldPoint-self.drag_handle - - # Drag gizmo is simply the thing being dragged. - drag_gizmo = self.gizmos[self.dragging_gizmo] - drag_x = new_drag_position.x() - drag_y = new_drag_position.y() - - # Snap gizmo is other (stationary) thing that we "snap" against. - snap_gizmo = self.gizmos[1-self.dragging_gizmo] - snap_x = snap_gizmo.getPosition().x() - snap_y = snap_gizmo.getPosition().y() - - # Calculate the list of "snap points". - snap_points = [ - (snap_x-drag_gizmo.getWidth(), snap_y), # Left of - (snap_x+snap_gizmo.getWidth(), snap_y), # Right of - (snap_x, snap_y-drag_gizmo.getHeight()), # Above - (snap_x, snap_y+snap_gizmo.getHeight())] # Below - - # Find the snap point that the drag gizmo is closest to. - best_index = -1 - best_distance = 0 - i = 0 - for snap_point in snap_points: - dx = snap_point[0] - drag_x - dy = snap_point[1] - drag_y - distance_squared = dx*dx + dy*dy - if best_index==-1 or distance_squared < best_distance: - best_index = i - best_distance = distance_squared - i += 1 - - # Lookup the best dualhead position that this configuration matches. - if self.dragging_gizmo==0: - self.drag_position = [ - XSetup.POSITION_LEFTOF, - XSetup.POSITION_RIGHTOF, - XSetup.POSITION_ABOVE, - XSetup.POSITION_BELOW][best_index] - else: - self.drag_position = [ - XSetup.POSITION_RIGHTOF, - XSetup.POSITION_LEFTOF, - XSetup.POSITION_BELOW, - XSetup.POSITION_ABOVE][best_index] - - # Convert the auto-snap distance in pixels into a distance in the gizmo coordinate system. - world_snap_distance = self.snap_distance / self._getGizmoToPixelsScaleFactor() - - # Should this drag gizmo visually snap? - snapped = False - if best_distance <= (world_snap_distance*world_snap_distance): - new_drag_position = QPoint(snap_points[best_index][0],snap_points[best_index][1]) - snapped = True - - # Move the gizmo - self.gizmos[self.dragging_gizmo].setPosition(new_drag_position) - - return snapped - - def paintEvent(self,event=None): - QWidget.paintEvent(self,event) - - # Paint to an off screen buffer first. Later we copy it to widget => flicker free. - off_screen_buffer = QPixmap(self.width(),self.height()) - off_screen_painter = QPainter(off_screen_buffer) - - # Erase the buffer first - off_screen_painter.setBackgroundColor(self.colorGroup().mid() ) - off_screen_painter.eraseRect(0, 0, off_screen_buffer.width(), off_screen_buffer.height()) - - # - off_screen_painter.setWorldMatrix(self._getGizmoMatrix()) - - # Paint the non-selected gizmo first. - self.gizmos[ 1-self.current_screen ].paint(off_screen_painter) - - # Now paint the selected gizmo - self.gizmos[self.current_screen].paint(off_screen_painter) - - # Turn off the world matrix transform. - off_screen_painter.setWorldXForm(False) - - # Draw the rounded border - off_screen_painter.setPen(QPen(self.colorGroup().dark(),1)) - off_screen_painter.drawRoundRect(0,0,self.width(),self.height(),2,2) - - off_screen_painter.end() - - # Update the widget - bitBlt(self, 0, 0, off_screen_buffer, 0, 0, self.width(), self.height(), Qt.CopyROP, False) - - def _getGizmoMatrix(self): - matrix = QWMatrix() - matrix.translate(self.width()/2,self.height()/2) - - scale_factor = self._getGizmoToPixelsScaleFactor() - matrix.scale(scale_factor,scale_factor) - return matrix - - def _getGizmoToPixelsScaleFactor(self): - g1 = self.gizmos[0] - g2 = self.gizmos[1] - size = min(self.width(),self.height()) - vscale = float(self.height()) / (2.1 * (g1.getHeight()+g2.getHeight())) - hscale = float(self.width()) / (2.1 * (g1.getWidth()+g2.getWidth())) - return min(vscale,hscale) - -############################################################################ -class MovingGizmo(object): - """A gizmo represents a screen/monitor. It also has a width and height that - correspond to the resolution of screen.""" - - def __init__(self,label,filename,initial_pos=QPoint(0,0),imagedir="."): - self.width = 100 - self.height = 100 - self.pixmap = QPixmap(imagedir+filename) - - self.highlight = False - self.highlight_color = QColor(255,0,0) - - self.setPosition(initial_pos) - - # Used for caching the scaled pixmap. - self.scaled_width = -1 - self.scaled_height = -1 - - def setHighlight(self,enable): - self.highlight = enable - - def setHighlightColor(self,color): - self.highlight_color = color - - def setPosition(self,position): - self.position = position - - def getSize(self): - return QSize(self.width,self.height) - - def getPosition(self): - return self.position - - def getRect(self): - return QRect(self.position,self.getSize()) - - def setWidth(self,width): - self.width = width - - def getWidth(self): - return self.width - - def setHeight(self,height): - self.height = height - - def getHeight(self): - return self.height - - def paint(self,painter): - painter.save() - if self.highlight: - pen = QPen(self.highlight_color,6) - painter.setPen(pen) - - painter.drawRect(self.position.x(), self.position.y(), self.width, self.height) - - to_pixels_matrix = painter.worldMatrix() - top_left_pixels = to_pixels_matrix.map(self.position) - bottom_right_pixels = to_pixels_matrix.map( QPoint(self.position.x()+self.width, self.position.y()+self.height) ) - - # Scale the pixmap. - scaled_width = bottom_right_pixels.x() - top_left_pixels.x() - scaled_height = bottom_right_pixels.y() - top_left_pixels.y() - - if (scaled_width,scaled_height) != (self.scaled_width,self.scaled_height): - scale_matrix = QWMatrix() - scale_matrix.scale( - float(scaled_width)/float(self.pixmap.width()), - float(scaled_height)/float(self.pixmap.height()) ) - - self.scaled_pixmap = self.pixmap.xForm(scale_matrix) - (self.scaled_width,self.scaled_height) = (scaled_width,scaled_height) - - # Paste in the scaled pixmap. - bitBlt(painter.device(), top_left_pixels.x(), top_left_pixels.y(), self.scaled_pixmap, 0, 0, - self.scaled_pixmap.width(), self.scaled_pixmap.height(),Qt.CopyROP, False) - - painter.restore() - -############################################################################ -class GfxCardWidget(QVGroupBox): - def __init__(self, parent, xsetup, gfxcard, gfxcarddialog, monitordialog): - global imagedir - QVGroupBox.__init__(self,parent) - - self.xsetup = xsetup - self.gfxcard = gfxcard - self.gfxcarddialog = gfxcarddialog - self.monitordialog = monitordialog - self._buildGUI() - self._syncGUI() - - def _buildGUI(self): - # Create the GUI - - gridwidget = QWidget(self) - grid = QGridLayout(gridwidget,2+3*len(self.gfxcard.getScreens())) - grid.setSpacing(KDialog.spacingHint()) - grid.setColStretch(0,0) - grid.setColStretch(1,0) - grid.setColStretch(2,0) - grid.setColStretch(3,1) - grid.setColStretch(4,0) - - gfxcardpic = QLabel(gridwidget) - gfxcardpic.setPixmap(UserIcon('hi32-gfxcard')) - grid.addMultiCellWidget(gfxcardpic,0,1,0,0) - - label = QLabel(gridwidget) - label.setText(i18n("Graphics card:")) - grid.addWidget(label,0,1) - - self.gfxcardlabel = QLabel(gridwidget) - grid.addWidget(self.gfxcardlabel,0,2) - - label = QLabel(gridwidget) - label.setText(i18n("Driver:")) - grid.addWidget(label,1,1) - - self.driverlabel = QLabel(gridwidget) - grid.addMultiCellWidget(self.driverlabel,1,1,2,3) - - gfxbutton = QPushButton(gridwidget) - gfxbutton.setText(i18n("Configure...")) - self.connect(gfxbutton,SIGNAL("clicked()"),self.slotGfxCardConfigureClicked) - grid.addWidget(gfxbutton,0,4) - gfxbutton.setEnabled(self.xsetup.mayModifyXorgConfig()) - - # Add all of the screens - row = 2 - count = 1 - self.monitorlabels = [] - self.monitor_buttons = [] - self.monitor_roles = [] - for screen in self.gfxcard.getScreens(): - frame = QFrame(gridwidget) - frame.setFrameShape(QFrame.HLine) - frame.setFrameShadow(QFrame.Sunken) - grid.addMultiCellWidget(frame,row,row,0,4) - row += 1 - - monitorpic = QLabel(gridwidget) - monitorpic.setPixmap(UserIcon('hi32-display')) - grid.addMultiCellWidget(monitorpic,row,row+1,0,0) - - # Monitor label - label = QLabel(gridwidget) - if len(self.gfxcard.getScreens())==1: - label.setText(i18n("Monitor:")) - else: - label.setText(i18n("Monitor #%1:").arg(count)) - grid.addWidget(label,row,1) - - self.monitorlabels.append(QLabel(gridwidget)) - grid.addMultiCellWidget(self.monitorlabels[-1],row,row,2,3) - - # Role pulldown - if len(self.xsetup.getAllScreens())!=1: - label = QLabel(gridwidget) - label.setText(i18n("Role:")) - grid.addWidget(label,row+1,1) - - role_combo = KComboBox(False,gridwidget) - role_combo.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) - self.monitor_roles.append(role_combo) - role_combo.insertItem(i18n("Primary (1)")) - role_combo.insertItem(i18n("Secondary (2)")) - if len(self.xsetup.getAllScreens())>=3: - role_combo.insertItem(i18n("Unused")) - self.connect(role_combo,SIGNAL("activated(int)"),self.slotRoleSelected) - grid.addWidget(role_combo,row+1,2) - role_combo.setEnabled(self.xsetup.mayModifyXorgConfig()) - - monitorbutton = QPushButton(gridwidget) - self.monitor_buttons.append(monitorbutton) - monitorbutton.setText(i18n("Configure...")) - self.connect(monitorbutton,SIGNAL("clicked()"),self.slotMonitorConfigureClicked) - grid.addWidget(monitorbutton,row,4) - monitorbutton.setEnabled(self.xsetup.mayModifyXorgConfig()) - row += 2 - count += 1 - - def syncConfig(self): - self._syncGUI() - - def _syncGUI(self): - if self.gfxcard.getGfxCardModel() is not None: - self.setTitle(self.gfxcard.getGfxCardModel().getName()) - self.gfxcardlabel.setText(self.gfxcard.getGfxCardModel().getName()) - - if self.gfxcard.isProprietaryDriver(): - try: - # Displayconfig thinks there is a proprietary driver - self.driverlabel.setText(self.gfxcard.getGfxCardModel().getProprietaryDriver()) - except TypeError, errormsg: - # If there isn't it dies, so try again LP: #198269 - self.driverlabel.setText(self.gfxcard.getGfxCardModel().getDriver()) - else: - self.driverlabel.setText(self.gfxcard.getGfxCardModel().getDriver()) - else: - self.setTitle(i18n("")) - self.gfxcardlabel.setText(i18n("")) - self.driverlabel.setText(i18n("")) - - # Sync the screens and monitors. - for i in range(len(self.gfxcard.getScreens())): - screen = self.gfxcard.getScreens()[i] - - if screen.getMonitorModel() is None: - monitor_name = i18n("") - else: - monitor_name = QString(screen.getMonitorModel().getName()) - if screen.getMonitorAspect()==ModeLine.ASPECT_16_9: - monitor_name.append(i18n(" (widescreen)")) - self.monitorlabels[i].setText(monitor_name) - - if len(self.xsetup.getAllScreens())!=1: - self.monitor_roles[i].setCurrentItem( - {XSetup.ROLE_PRIMARY: 0, - XSetup.ROLE_SECONDARY: 1, - XSetup.ROLE_UNUSED: 2} - [self.xsetup.getScreenRole(screen)]) - - def slotGfxCardConfigureClicked(self): - result = self.gfxcarddialog.do(self.gfxcard.getGfxCardModel(), \ - self.gfxcard.isProprietaryDriver(), self.gfxcard.getDetectedGfxCardModel(), - self.gfxcard.getVideoRam()) - - (new_card_model, new_proprietary_driver, new_video_ram) = result - - if new_card_model is self.gfxcard.getGfxCardModel() and \ - new_proprietary_driver==self.gfxcard.isProprietaryDriver() and \ - new_video_ram==self.gfxcard.getVideoRam(): - return - self.gfxcard.setGfxCardModel(new_card_model) - self.gfxcard.setProprietaryDriver(new_proprietary_driver) - self.gfxcard.setVideoRam(new_video_ram) - self._syncGUI() - self.emit(PYSIGNAL("configChanged"), () ) - - def slotMonitorConfigureClicked(self): - screen_index = self.monitor_buttons.index(self.sender()) - screen_obj = self.gfxcard.getScreens()[screen_index] - - (new_monitor_model,new_aspect) = self.monitordialog.do(screen_obj.getMonitorModel(), - screen_obj.getMonitorAspect(), - self.xsetup.getGfxCards()[0].getScreens()[0] is screen_obj) - - screen_obj.setMonitorModel(new_monitor_model) - screen_obj.setMonitorAspect(new_aspect) - self._syncGUI() - self.emit(PYSIGNAL("configChanged"), () ) - - def slotRoleSelected(self,index): - screen_index = self.monitor_roles.index(self.sender()) - screen_obj = self.gfxcard.getScreens()[screen_index] - self.xsetup.setScreenRole(screen_obj,[XSetup.ROLE_PRIMARY,XSetup.ROLE_SECONDARY,XSetup.ROLE_UNUSED][index]) - - self._syncGUI() - self.emit(PYSIGNAL("configChanged"), () ) diff --git a/displayconfig/driver-options.txt b/displayconfig/driver-options.txt deleted file mode 100644 index 100a60e..0000000 --- a/displayconfig/driver-options.txt +++ /dev/null @@ -1,1054 +0,0 @@ -Driver options: -=================== - -This document contains driver specific options for Xorg and XFree86 and what -effect they are meant to have. These options are only valid in conjuntion with -the specified driver and generally have no meaning / effect when used with -other graphics drivers. - -o fbdev -o fglrx (binary ATi driver) -o i740 -o i810 -o mga -o nv -o nvidia -o radeon -o sis -o vesa - -Driver fbdev: --------------- -(source: man fbdev) - - Option "fbdev" "string" - The framebuffer device to use. Default: /dev/fb0. - - Option "ShadowFB" "boolean" - Enable or disable use of the shadow framebuffer layer. Default: on. - - Option "Rotate" "string" - Enable rotation of the display. The supported values are "CW" (clock‐ - wise, 90 degrees), "UD" (upside down, 180 degrees) and "CCW" (counter - clockwise, 270 degrees). Implies use of the shadow framebuffer layer. - Default: off. - - -Driver fglrx (ATi binary driver): ----------------------------------- - -Section "Device" - Identifier "Radeon 9600XT - fglrx" - Driver "fglrx" -# ### generic DRI settings ### -# === disable PnP Monitor === - #Option "NoDDC" -# === disable/enable XAA/DRI === - Option "no_accel" "no" - Option "no_dri" "no" -# === misc DRI settings === - Option "mtrr" "off" # disable DRI mtrr mapper, driver has its own code for mtrr -# ### FireGL DDX driver module specific settings ### -# === Screen Management === - Option "DesktopSetup" "0x00000000" - Option "MonitorLayout" "AUTO, AUTO" - Option "IgnoreEDID" "off" - Option "HSync2" "" - Option "VRefresh2" "" - Option "ScreenOverlap" "0" -# === TV-out Management === - Option "NoTV" "yes" - Option "TVStandard" "NTSC-M" - Option "TVHSizeAdj" "0" - Option "TVVSizeAdj" "0" - Option "TVHPosAdj" "0" - Option "TVVPosAdj" "0" - Option "TVHStartAdj" "0" - Option "TVColorAdj" "0" - Option "GammaCorrectionI" "0x00000000" - Option "GammaCorrectionII" "0x00000000" -# === OpenGL specific profiles/settings === - Option "Capabilities" "0x00000000" -# === Video Overlay for the Xv extension === - Option "VideoOverlay" "on" -# === OpenGL Overlay === -# Note: When OpenGL Overlay is enabled, Video Overlay -# will be disabled automatically - Option "OpenGLOverlay" "off" -# === Center Mode (Laptops only) === - Option "CenterMode" "off" -# === Pseudo Color Visuals (8-bit visuals) === - Option "PseudoColorVisuals" "off" -# === QBS Management === - Option "Stereo" "off" - Option "StereoSyncEnable" "1" -# === FSAA Management === - Option "FSAAEnable" "yes" - Option "FSAAScale" "4" - Option "FSAADisableGamma" "no" - Option "FSAACustomizeMSPos" "no" - Option "FSAAMSPosX0" "0.000000" - Option "FSAAMSPosY0" "0.000000" - Option "FSAAMSPosX1" "0.000000" - Option "FSAAMSPosY1" "0.000000" - Option "FSAAMSPosX2" "0.000000" - Option "FSAAMSPosY2" "0.000000" - Option "FSAAMSPosX3" "0.000000" - Option "FSAAMSPosY3" "0.000000" - Option "FSAAMSPosX4" "0.000000" - Option "FSAAMSPosY4" "0.000000" - Option "FSAAMSPosX5" "0.000000" - Option "FSAAMSPosY5" "0.000000" -# === Misc Options === - Option "UseFastTLS" "0" - Option "BlockSignalsOnLock" "on" - Option "UseInternalAGPGART" "yes" - Option "ForceGenericCPU" "no" - BusID "PCI:1:0:0" # vendor=1002, device=4152 - Screen 0 -EndSection - -Driver i740: -------------- -(No info yet) - - -Driver i810: -------------- - - Option "NoAccel" "boolean" - Disable or enable acceleration. Default: acceleration is enabled. - - Option "SWCursor" "boolean" - Disable or enable software cursor. Default: software cursor is dis‐ - able and a hardware cursor is used for configurations where the - hardware cursor is available. - - Option "ColorKey" "integer" - This sets the default pixel value for the YUV video overlay key. - Default: undefined. - - Option "CacheLines" "integer" - This allows the user to change the amount of graphics memory used for - 2D acceleration and video. Decreasing this amount leaves more for 3D - textures. Increasing it can improve 2D performance at the expense of - 3D performance. Default: depends on the resolution, depth, and - available video memory. The driver attempts to allocate at least - enough to hold two DVD-sized YUV buffers by default. The default - used for a specific configuration can be found by examining the Xorg - log file. - - Option "DRI" "boolean" - Disable or enable DRI support. Default: DRI is enabled for configu‐ - rations where it is supported. - - The following driver Options are supported for the i810 and i815 chipsets: - - Option "DDC" "boolean" - Disable or enable DDC support. Default: enabled. - - Option "Dac6Bit" "boolean" - Enable or disable 6-bits per RGB for 8-bit modes. Default: 8-bits - per RGB for 8-bit modes. - - Option "XvMCSurfaces" "integer" - This option enables XvMC. The integer parameter specifies the number - of surfaces to use. Valid values are 6 and 7. Default: XvMC is dis‐ - abled. - - The following driver Options are supported for the 830M and later chipsets: - - Option "VBERestore" "boolean" - Enable or disable the use of VBE save/restore for saving and restor‐ - ing the initial text mode. This is disabled by default because it - causes lockups on some platforms. However, there are some cases - where it must enabled for the correct restoration of the initial - video mode. If you are having a problem with that, try enabling this - option. Default: Disabled. - - Option "VideoKey" "integer" - This is the same as the "ColorKey" option described above. It is - provided for compatibility with most other drivers. - - Option "XVideo" "boolean" - Disable or enable XVideo support. Default: XVideo is enabled for - configurations where it is supported. - - Option "MonitorLayout" "anystr" - Allow different monitor configurations. e.g. "CRT,LFP" will configure - a CRT on Pipe A and an LFP on Pipe B. Regardless of the primary - heads’ pipe it is always configured as ",". Addition‐ - ally you can add different configurations such as "CRT+DFP,LFP" which - would put a digital flat panel and a CRT on pipe A, and a local flat - panel on pipe B. For single pipe configurations you can just specify - the monitors types on Pipe A, such as "CRT+DFP" which will enable the - CRT and DFP on Pipe A. Valid monitors are CRT, LFP, DFP, TV, CRT2, - LFP2, DFP2, TV2 and NONE. NOTE: Some configurations of monitor types - may fail, this depends on the Video BIOS and system configuration. - Default: Not configured, and will use the current head’s pipe and - monitor. - - Option "Clone" "boolean" - Enable Clone mode on pipe B. This will setup the second head as a - complete mirror of the monitor attached to pipe A. NOTE: Video over‐ - lay functions will not work on the second head in this mode. If you - require this, then use the MonitorLayout above and do (as an example) - "CRT+DFP,NONE" to configure both a CRT and DFP on Pipe A to achieve - local mirroring and disable the use of this option. Default: Clone - mode on pipe B is disabled. - - Option "CloneRefresh" "integer" - When the Clone option is specified we can drive the second monitor at - a different refresh rate than the primary. Default: 60Hz. - - Option "CheckLid" "boolean" - On mobile platforms it’s desirable to monitor the lid status and - switch the outputs accordingly when the lid is opened or closed. By - default this option is on, but may incur a very minor performance - penalty as we need to poll a register on the card to check for this - activity. It can be turned off using this option. This only works - with the 830M, 852GM and 855GM systems. Default: enabled. - - Option "FlipPrimary" "boolean" - When using a dual pipe system, it may be preferable to switch the - primary screen to the alternate pipe to display on the other monitor - connection. NOTE: Using this option may cause text mode to be - restored incorrectly, and thus should be used with caution. Default: - disabled. - - Option "DisplayInfo" "boolean" - It has been found that a certain BIOS call can lockup the Xserver - because of a problem in the Video BIOS. The log file will identify if - you are suffering from this problem and tell you to turn this option - off. Default: enabled - - Option "DevicePresence" "boolean" - Tell the driver to perform an active detect of the currently con‐ - nected monitors. This option is useful if the monitor was not con‐ - nected when the machine has booted, but unfortunately it doesn’t - always work and is extremely dependent upon the Video BIOS. Default: - disabled - - -Driver mga: ------------- - - Option "ColorKey" "integer" - Set the colormap index used for the transparency key for the depth 8 - plane when operating in 8+24 overlay mode. The value must be in the - range 2-255. Default: 255. - - Option "HWCursor" "boolean" - Enable or disable the HW cursor. Default: on. - - Option "MGASDRAM" "boolean" - Specify whether G100, G200 or G400 cards have SDRAM. The driver - attempts to auto-detect this based on the card’s PCI subsystem ID. - This option may be used to override that auto-detection. The mga - driver is not able to auto-detect the presence of of SDRAM on sec‐ - ondary heads in multihead configurations so this option will often - need to be specified in multihead configurations. Default: - auto-detected. - - Option "NoAccel" "boolean" - Disable or enable acceleration. Default: acceleration is enabled. - - Option "NoHal" "boolean" - Disable or enable loading the "mga_hal" module. Default: the module - is loaded when available and when using hardware that it supports. - - Option "OverclockMem" - Set clocks to values used by some commercial X Servers (G100, G200 - and G400 only). Default: off. - - Option "Overlay" "value" - Enable 8+24 overlay mode. Only appropriate for depth 24. Recognized - values are: "8,24", "24,8". Default: off. (Note: the G100 is unac‐ - celerated in the 8+24 overlay mode due to a missing hardware fea‐ - ture.) - - Option "PciRetry" "boolean" - Enable or disable PCI retries. Default: off. - - Option "Rotate" "CW" - - Option "Rotate" "CCW" - Rotate the display clockwise or counterclockwise. This mode is unac‐ - celerated. Default: no rotation. - - Option "ShadowFB" "boolean" - Enable or disable use of the shadow framebuffer layer. Default: off. - - Option "SyncOnGreen" "boolean" - Enable or disable combining the sync signals with the green signal. - Default: off. - - Option "UseFBDev" "boolean" - Enable or disable use of on OS-specific fb interface (and is not sup‐ - ported on all OSs). See fbdevhw(4x) for further information. - Default: off. - - Option "VideoKey" "integer" - This sets the default pixel value for the YUV video overlay key. - Default: undefined. - - Option "TexturedVideo" "boolean" - This has XvImage support use the texture engine rather than the video - overlay. This option is only supported by G200 and later chips, and - only at 16 and 32 bits per pixel. Default: off. - - -Driver nv: ------------ -(source: man nv) - Option "HWCursor" "boolean" - Enable or disable the HW cursor. Default: on. - - Option "NoAccel" "boolean" - Disable or enable acceleration. Default: acceleration is enabled. - - Option "UseFBDev" "boolean" - Enable or disable use of on OS-specific fb interface (and is not sup- - ported on all OSs). See fbdevhw(4x) for further information. - Default: off. - - Option "CrtcNumber" "integer" - GeForce2 MX, nForce2, Quadro4, GeForce4, Quadro FX and GeForce FX may - have two video outputs. The driver attempts to autodetect which one - the monitor is connected to. In the case that autodetection picks - the wrong one, this option may be used to force usage of a particular - output. The options are "0" or "1". Default: autodetected. - - Option "FlatPanel" "boolean" - The driver usually can autodetect the presence of a digital flat - panel. In the case that this fails, this option can be used to force - the driver to treat the attached device as a digital flat panel. - With this driver, a digital flat panel will only work if it was - POSTed by the BIOS, that is, the machine must have booted to the - panel. If you have a dual head card you may also need to set the - option CrtcNumber described above. Default: off. - - Option "FPDither" "boolean" - Many digital flat panels (particularly ones on laptops) have only 6 - bits per component color resolution. This option tells the driver to - dither from 8 bits per component to 6 before the flat panel truncates - it. This is only supported in depth 24 on GeForce2 MX, nForce2, - GeForce4, Quadro4, Geforce FX and Quadro FX. Default: off. - - Option "FPScale" "boolean" - Supported only on GeForce4, Quadro4, Geforce FX and Quadro FX. This - option tells to the driver to scale lower resolutions up to the flat - panel's native resolution. Default: on. - - Option "Rotate" "CW" - - Option "Rotate" "CCW" - Rotate the display clockwise or counterclockwise. This mode is unac- - celerated. Default: no rotation. - - Note: The Resize and Rotate extension will be disabled if the Rotate - option is used. - - Option "ShadowFB" "boolean" - Enable or disable use of the shadow framebuffer layer. Default: off. - - - -Driver nvidia.ko (binary driver): ----------------------------------- -(source: ftp://download.nvidia.com/XFree86/Linux-x86/1.0-7174/README.txt) - - Option "NvAGP" "integer" - Configure AGP support. Integer argument can be one of: - 0 : disable agp - 1 : use NVIDIA's internal AGP support, if possible - 2 : use AGPGART, if possible - 3 : use any agp support (try AGPGART, then NVIDIA's AGP) - Please note that NVIDIA's internal AGP support cannot - work if AGPGART is either statically compiled into your - kernel or is built as a module, but loaded into your - kernel (some distributions load AGPGART into the kernel - at boot up). Default: 3 (the default was 1 until after - 1.0-1251). - - Option "NoLogo" "boolean" - Disable drawing of the NVIDIA logo splash screen at - X startup. Default: the logo is drawn. - - Option "RenderAccel" "boolean" - Enable or disable hardware acceleration of the RENDER - extension. THIS OPTION IS EXPERIMENTAL. ENABLE IT AT YOUR - OWN RISK. There is no correctness test suite for the - RENDER extension so NVIDIA can not verify that RENDER - acceleration works correctly. Default: hardware - acceleration of the RENDER extension is disabled. - - Option "NoRenderExtension" "boolean" - Disable the RENDER extension. Other than recompiling - the X-server, XFree86 does not seem to have another way of - disabling this. Fortunatly, we can control this from the - driver so we export this option. This is useful in depth - 8 where RENDER would normally steal most of the default - colormap. Default: RENDER is offered when possible. - - Option "UBB" "boolean" - Enable or disable Unified Back Buffer on any Quadro - based GPUs (Quadro4 NVS excluded); please see - Appendix M for a description of UBB. This option has - no affect on non-Quadro chipsets. Default: UBB is on - for Quadro chipsets. - - Option "NoFlip" "boolean" - Disable OpenGL flipping; please see Appendix M for - a description. Default: OpenGL will swap by flipping - when possible. - - Option "DigitalVibrance" "integer" - Enables Digital Vibrance Control. The range of valid - values are 0 through 255. This feature is not available - on products older than GeForce2. Default: 0. - - Option "Dac8Bit" "boolean" - Most Quadro parts by default use a 10 bit color look - up table (LUT) by default; setting this option to TRUE forces - these graphics chips to use an 8 bit (LUT). Default: - a 10 bit LUT is used, when available. - - Option "Overlay" "boolean" - Enables RGB workstation overlay visuals. This is only - supported on Quadro4 and Quadro FX chips (Quadro4 NVS - excluded) in depth 24. This option causes the server to - advertise the SERVER_OVERLAY_VISUALS root window property - and GLX will report single and double buffered, Z-buffered - 16 bit overlay visuals. The transparency key is pixel - 0x0000 (hex). There is no gamma correction support in - the overlay plane. This feature requires XFree86 version - 4.1.0 or newer (or the Xorg X server). NV17/18 based - Quadros (ie. 500/550 XGL) have additional restrictions, - namely, overlays are not supported in TwinView mode - or with virtual desktops larger than 2046x2047 in any - dimension (eg. it will not work in 2048x1536 modes). - Quadro 7xx/9xx and Quadro FX will offer overlay visuals - in these modes (TwinView, or virtual desktops larger - than 2046x2047), but the overlay will be emulated with - a substantial performance penalty. RGB workstation - overlays are not supported when the Composite extension is - enabled. Default: off. - - Option "CIOverlay" "boolean" - Enables Color Index workstation overlay visuals with - identical restrictions to Option "Overlay" above. - The server will offer visuals both with and without a - transparency key. These are depth 8 PseudoColor visuals. - Enabling Color Index overlays on X servers older than - XFree86 4.3 will force the RENDER extension to be disabled - due to bugs in the RENDER extension in older X servers. - Color Index workstation overlays are not supported when the - Composite extension is enabled. Default: off. - - Option "TransparentIndex" "integer" - When color index overlays are enabled, use this option - to choose which pixel is used for the transparent pixel - in visuals featuring transparent pixels. This value - is clamped between 0 and 255 (Note: some applications - such as Alias's Maya require this to be zero - in order to work correctly). Default: 0. - - Option "OverlayDefaultVisual" "boolean" - When overlays are used, this option sets the default - visual to an overlay visual thereby putting the root - window in the overlay. This option is not recommended - for RGB overlays. Default: off. - - Option "RandRRotation" "boolean" - Enable rotation support for the XRandR extension. This - allows use of the XRandR X server extension for - configuring the screen orientation through rotation. - This feature is supported on GeForce2 or better hardware - using depth 24. This requires an XOrg 6.8.1 or newer - X server. This feature does not work with hardware overlays, - emulated overlays will be used instead at a substantial - performance penalty. See APPENDIX W for details. - Default: off. - - Option "SWCursor" "boolean" - Enable or disable software rendering of the X cursor. - Default: off. - - Option "HWCursor" "boolean" - Enable or disable hardware rendering of the X cursor. - Default: on. - - Option "CursorShadow" "boolean" Enable or disable use of a - shadow with the hardware accelerated cursor; this is a - black translucent replica of your cursor shape at a - given offset from the real cursor. This option is - only available on GeForce2 or better hardware (ie - everything but TNT/TNT2, GeForce 256, GeForce DDR and - Quadro). Default: no cursor shadow. - - Option "CursorShadowAlpha" "integer" - The alpha value to use for the cursor shadow; only - applicable if CursorShadow is enabled. This value must - be in the range [0, 255] -- 0 is completely transparent; - 255 is completely opaque. Default: 64. - - Option "CursorShadowXOffset" "integer" - The offset, in pixels, that the shadow image will be - shifted to the right from the real cursor image; only - applicable if CursorShadow is enabled. This value must - be in the range [0, 32]. Default: 4. - - Option "CursorShadowYOffset" "integer" - The offset, in pixels, that the shadow image will be - shifted down from the real cursor image; only applicable - if CursorShadow is enabled. This value must be in the - range [0, 32]. Default: 2. - - Option "ConnectedMonitor" "string" - Allows you to override what the NVIDIA kernel module - detects is connected to your video card. This may - be useful, for example, if you use a KVM (keyboard, - video, mouse) switch and you are switched away when - X is started. In such a situation, the NVIDIA kernel - module cannot detect what display devices are connected, - and the NVIDIA X driver assumes you have a single CRT. - - Valid values for this option are "CRT" (cathode ray - tube), "DFP" (digital flat panel), or "TV" (television); - if using TwinView, this option may be a comma-separated - list of display devices; e.g.: "CRT, CRT" or "CRT, DFP". - - NOTE: anything attached to a 15 pin VGA connector is - regarded by the driver as a CRT. "DFP" should only be - used to refer to flatpanels connected via a DVI port. - - Default: string is NULL. - - Option "UseEdidFreqs" "boolean" - This option causes the X server to use the HorizSync - and VertRefresh ranges given in a display device's EDID, - if any. EDID provided range information will override - the HorizSync and VertRefresh ranges specified in the - Monitor section. If a display device does not provide an - EDID, or the EDID does not specify an hsync or vrefresh - range, then the X server will default to the HorizSync - and VertRefresh ranges specified in the Monitor section. - - Option "IgnoreEDID" "boolean" - Disable probing of EDID (Extended Display Identification - Data) from your monitor. Requested modes are compared - against values gotten from your monitor EDIDs (if any) - during mode validation. Some monitors are known to lie - about their own capabilities. Ignoring the values that - the monitor gives may help get a certain mode validated. - On the other hand, this may be dangerous if you do not - know what you are doing. Default: Use EDIDs. - - Option "NoDDC" "boolean" - Synonym for "IgnoreEDID" - - Option "FlatPanelProperties" "string" - Requests particular properties of any connected flat - panels as a comma-separated list of property=value pairs. - Currently, the only two available properties are 'Scaling' - and 'Dithering'. The possible values for 'Scaling' are: - 'default' (the driver will use whatever scaling state - is current), 'native' (the driver will use the flat - panel's scaler, if it has one), 'scaled' (the driver - will use the NVIDIA scaler, if possible), 'centered' - (the driver will center the image, if possible), - and 'aspect-scaled' (the driver will scale with the - NVIDIA scaler, but keep the aspect ratio correct). - The possible values for 'Dithering' are: 'default' - (the driver will decide when to dither), 'enabled' (the - driver will always dither when possible), and 'disabled' - (the driver will never dither). If any property is not - specified, it's value shall be 'default'. An example - properties string might look like: - - "Scaling = centered, Dithering = enabled" - - Option "UseInt10Module" "boolean" - Enable use of the X Int10 module to soft-boot all - secondary cards, rather than POSTing the cards through - the NVIDIA kernel module. Default: off (POSTing is done - through the NVIDIA kernel module). - - Option "TwinView" "boolean" - Enable or disable TwinView. Please see APPENDIX I for - details. Default: TwinView is disabled. - - Option "TwinViewOrientation" "string" - Controls the relationship between the two display devices - when using TwinView. Takes one of the following values: - "RightOf" "LeftOf" "Above" "Below" "Clone". Please see - APPENDIX I for details. Default: string is NULL. - - Option "SecondMonitorHorizSync" "range(s)" - This option is like the HorizSync entry in the Monitor - section, but is for the second monitor when using - TwinView. Please see APPENDIX I for details. Default: - none. - - Option "SecondMonitorVertRefresh" "range(s)" - This option is like the VertRefresh entry in the Monitor - section, but is for the second monitor when using - TwinView. Please see APPENDIX I for details. Default: - none. - - Option "MetaModes" "string" - This option describes the combination of modes to use - on each monitor when using TwinView. Please see APPENDIX - I for details. Default: string is NULL. - - Option "NoTwinViewXineramaInfo" "boolean" - When in TwinView, the NVIDIA X driver normally provides - a Xinerama extension that X clients (such as window - managers) can use to to discover the current TwinView - configuration. Some window mangers can get confused by - this information, so this option is provided to disable - this behavior. Default: TwinView Xinerama information - is provided. - - Option "TVStandard" "string" - Please see (app-j) APPENDIX J: CONFIGURING TV-OUT. - - Option "TVOutFormat" "string" - Please see (app-j) APPENDIX J: CONFIGURING TV-OUT. - - Option "TVOverScan" "Decimal value in the range 0.0 to 1.0" - Valid values are in the range 0.0 through 1.0; please see - (app-j) APPENDIX J: CONFIGURING TV-OUT. - - Option "Stereo" "integer" - Enable offering of quad-buffered stereo visuals on Quadro. - Integer indicates the type of stereo glasses being used: - - 1 - DDC glasses. The sync signal is sent to the glasses - via the DDC signal to the monitor. These usually - involve a passthrough cable between the monitor and - video card. - - 2 - "Blueline" glasses. These usually involve - a passthrough cable between the monitor and video - card. The glasses know which eye to display based - on the length of a blue line visible at the bottom - of the screen. When in this mode, the root window - dimensions are one pixel shorter in the Y dimension - than requested. This mode does not work with virtual - root window sizes larger than the visible root window - size (desktop panning). - - 3 - Onboard stereo support. This is usually only found - on professional cards. The glasses connect via a - DIN connector on the back of the video card. - - 4 - TwinView clone mode stereo (aka "passive" stereo). - On video cards that support TwinView, the left eye - is displayed on the first display, and the right - eye is displayed on the second display. This is - normally used in conjuction with special projectors - to produce 2 polarized images which are then viewed - with polarized glasses. To use this stereo mode, - you must also configure TwinView in clone mode with - the same resolution, panning offset, and panning - domains on each display. - - Stereo is only available on Quadro cards. Stereo - options 1, 2, and 3 (aka "active" stereo) may be used - with TwinView if all modes within each metamode have - identical timing values. Please see (app-l) APPENDIX - L: PROGRAMMING MODES for suggestions on making sure the - modes within your metamodes are identical. The identical - modeline requirement is not necessary for Stereo option 4 - ("passive" stereo). Currently, stereo operation may - be "quirky" on the original Quadro (NV10) chip and - left-right flipping may be erratic. We are trying - to resolve this issue for a future release. Default: - Stereo is not enabled. - - Stereo options 1, 2, and 3 (aka "active" stereo) are not - supported on Digital Flatpanels. - - Option "AllowDFPStereo" "boolean" - By default, the NVIDIA X driver performs a check which - disables active stereo (stereo options 1, 2, and 3) - if the X screen is driving a DFP. The "AllowDFPStereo" - option bypasses this check. - - Option "NoBandWidthTest" "boolean" - As part of mode validation, the X driver tests if a - given mode fits within the hardware's memory bandwidth - constraints. This option disables this test. Default: - the memory bandwidth test is performed. - - Option "IgnoreDisplayDevices" "string" - This option tells the NVIDIA kernel module to completely - ignore the indicated classes of display devices when - checking what display devices are connected. You may - specify a comma-separated list containing any of "CRT", - "DFP", and "TV". - - For example: - - Option "IgnoreDisplayDevices" "DFP, TV" - - will cause the NVIDIA driver to not attempt to detect - if any flatpanels or TVs are connected. - - This option is not normally necessary; however, some video - BIOSes contain incorrect information about what display - devices may be connected, or what i2c port should be - used for detection. These errors can cause long delays - in starting X. If you are experiencing such delays, you - may be able to avoid this by telling the NVIDIA driver to - ignore display devices which you know are not connected. - - NOTE: anything attached to a 15 pin VGA connector is - regarded by the driver as a CRT. "DFP" should only be - used to refer to flatpanels connected via a DVI port. - - Option "MultisampleCompatibility" "boolean" - Enable or disable the use of separate front and back - multisample buffers. This will consume more memory - but is necessary for correct output when rendering to - both the front and back buffers of a multisample or - FSAA drawable. This option is necessary for correct - operation of SoftImage XSI. Default: a singlemultisample - buffer is shared between the front and back buffers. - - Option "NoPowerConnectorCheck" "boolean" - The NVIDIA X driver will abort X server initialization - if it detects that a GPU that requires an external power - connector does not have an external power connector - plugged in. This option can be used to bypass this test. - Default: the power connector test is performed. - - Option "XvmcUsesTextures" "boolean" - Forces XvMC to use the 3D engine for XvMCPutSurface - requests rather than the video overlay. Default: video - overlay is used when available. - - Option "AllowGLXWithComposite" "boolean" - Enables GLX even when the Composite X extension is loaded. - ENABLE AT YOUR OWN RISK. OpenGL applications will not - display correctly in many circumstances with this setting - enabled. Default: GLX is disabled when Composite is - loaded. - - Option "ExactModeTimingsDVI" "boolean" - Forces the initialization of the X server with the exact - timings specified in the ModeLine. Default: For DVI - devices, the X server inilializes with the closest mode in - the EDID list. - - -Driver radeon: ---------------- -(source: manpage radeon) - - Option "SWcursor" "boolean" - Selects software cursor. The default is off. - - Option "NoAccel" "boolean" - Enables or disables all hardware acceleration. - The default is to enable hardware acceleration. - - Option "Dac6Bit" "boolean" - Enables or disables the use of 6 bits per color component when in 8 - bpp mode (emulates VGA mode). By default, all 8 bits per color com- - ponent are used. - The default is off. - - Option "VideoKey" "integer" - This overrides the default pixel value for the YUV video overlay key. - The default value is 0x1E. - - Option "UseFBDev" "boolean" - Enable or disable use of an OS-specific framebuffer device interface - (which is not supported on all OSs). MergedFB does not work when - this option is in use. See fbdevhw(4x) for further information. - The default is off. - - Option "AGPMode" "integer" - Set AGP data transfer rate. (used only when DRI is enabled) - 1 -- x1 (default) - 2 -- x2 - 4 -- x4 - others -- invalid - - Option "AGPFastWrite" "boolean" - Enable AGP fast write. - (used only when DRI is enabled) - The default is off. - - Option "BusType" "string" - Used to replace previous ForcePCIMode option. Should only be used - when driver’s bus detection is incorrect or you want to force a AGP - card to PCI mode. Should NEVER force a PCI card to AGP bus. - PCI -- PCI bus - AGP -- AGP bus - PCIE -- PCI Express (falls back to PCI at present) - (used only when DRI is enabled) - The default is auto detect. - - Option "DDCMode" "boolean" - Force to use the modes queried from the connected monitor. - The default is off. - - Option "DisplayPriority" "string" - Used to prevent flickering or tearing problem caused by display - buffer underflow. - AUTO -- Driver calculated (default). - BIOS -- Remain unchanged from BIOS setting. - Use this if the calculation is not correct - for your card. - HIGH -- Force to the highest priority. - Use this if you have problem with above options. - This may affect performence slightly. - The default value is AUTO. - - Option "MonitorLayout" "string" - This option is used to overwrite the detected monitor types. This is - only required when driver makes a false detection. The possible mon- - itor types are: - NONE -- Not connected - CRT -- Analog CRT monitor - TMDS -- Desktop flat panel - LVDS -- Laptop flat panel - This option can be used in following format: - Option "MonitorLayout" "[type on primary], [type on secondary]" - For example, Option "MonitorLayout" "CRT, TMDS" - - Primary/Secondary head for dual-head cards: - (when only one port is used, it will be treated as the primary - regardless) - Primary head: - DVI port on DVI+VGA cards - LCD output on laptops - Internal TMDS port on DVI+DVI cards - Secondary head: - VGA port on DVI+VGA cards - VGA port on laptops - External TMDS port on DVI+DVI cards - - The default value is undefined. - - Option "MergedFB" "boolean" - This enables merged framebuffer mode. In this mode you have a single - shared framebuffer with two viewports looking into it. It is similar - to Xinerama, but has some advantages. It is faster than Xinerama, - the DRI works on both heads, and it supports clone modes. - Merged framebuffer mode provides two linked viewports looking into a - single large shared framebuffer. The size of the framebuffer is - determined by the Virtual keyword defined on the Screen section of - your XF86Config file. It works just like regular virtual desktop - except you have two viewports looking into it instead of one. - For example, if you wanted a desktop composed of two 1024x768 view- - ports looking into a single desktop you would create a virtual desk- - top of 2048x768 (left/right) or 1024x1536 (above/below), e.g., - Virtual 2048 768 or Virtual 1024 1536 - The virtual desktop can be larger than larger than the size of the - viewports looking into it. In this case the linked viewports will - scroll around in the virtual desktop. Viewports with different sizes - are also supported (e.g., one that is 1024x768 and one that is - 640x480). In this case the smaller viewport will scroll relative to - the larger one such that none of the virtual desktop is inaccessable. - If you do not define a virtual desktop the driver will create one - based on the orientation of the heads and size of the largest defined - mode in the display section that is supported on each head. - The relation of the viewports in specified by the CRT2Position - Option. The options are Clone , LeftOf , RightOf , Above , and - Below. MergedFB is enabled by default if a monitor is detected on - each output. If no position is given it defaults to clone mode (the - old clone options are now deprecated, also, the option OverlayOnCRTC2 - has been replaced by the Xv attribute XV_SWITCHCRT; the overlay can - be switched to CRT1 or CRT2 on the fly in clone mode). - The maximum framebuffer size that the 2D acceleration engine can han- - dle is 8192x8192. The maximum framebuffer size that the 3D engine - can handle is 2048x2048. - Note: Page flipping does not work well in certain configurations with - MergedFB. If you see rendering errors or other strange behavior, - disable page flipping. Also MergedFB is not compatible with the UseF- - BDev option. - The default value is undefined. - - Option "CRT2HSync" "string" - Set the horizontal sync range for the secondary monitor. It is not - required if a DDC-capable monitor is connected. - For example, Option "CRT2HSync" "30.0-86.0" - The default value is undefined. - - Option "CRT2VRefresh" "string" - Set the vertical refresh range for the secondary monitor. It is not - required if a DDC-capable monitor is connected. - For example, Option "CRT2VRefresh" "50.0-120.0" - The default value is undefined. - - Option "CRT2Position" "string" - Set the relationship of CRT2 relative to CRT1. Valid options are: - Clone , LeftOf , RightOf , Above , and Below - For example, Option "CRT2Position" "RightOf" - The default value is Clone. - - Option "MetaModes" "string" - MetaModes are mode combinations for CRT1 and CRT2. If you are using - merged frame buffer mode and want to change modes (CTRL-ALT-+/-), - these define which modes will be switched to on CRT1 and CRT2. The - MetaModes are defined as CRT1Mode-CRT2Mode (800x600-1024x768). Modes - listed individually (800x600) define clone modes, that way you can - mix clone modes with non-clone modes. Also some programs require - "standard" modes. - Note: Any mode you use in the MetaModes must be defined in the - Screen section of your XF86Config file. Modes not defined there will - be ignored when the MetaModes are parsed since the driver uses them - to make sure the monitors can handle those modes. If you do not - define a MetaMode the driver will create one based on the orientation - of the heads and size of the largest defined mode in the display sec- - tion that is supported on each head. - Modes 1024x768 800x600 640x480 - For example, Option "MetaModes" "1024x768-1024x768 800x600-1024x768 - 640x480-800x600 800x600" - The default value is undefined. - - Option "OverlayOnCRTC2" "boolean" - Force hardware overlay to clone head. - The default value is off. - - Option "NoMergedXinerama" "boolean" - Since merged framebuffer mode does not use Xinerama, apps are not - able to intelligently place windows. Merged framebuffer mode pro- - vides its own pseudo-Xinerama. This allows Xinerama compliant appli- - cations to place windows appropriately. There are some caveats. - Since merged framebuffer mode is able to change relative screen sizes - and orientations on the fly, as well has having overlapping view- - ports, pseudo-Xinerama, might not always provide the right hints. - Also many Xinerama compliant applications only query Xinerama once at - startup; if the information changes, they may not be aware of the - change. If you are already using Xinerama (e.g., a single head card - and a dualhead card providing three heads), pseudo-Xinerama will be - disabled. - This option allows you turn off the driver provided pseudo-Xinerama - extension. - The default value is FALSE. - - Option "MergedXineramaCRT2IsScreen0" "boolean" - By default the pseudo-Xinerama provided by the driver makes the left- - most or bottom head Xinerama screen 0. Certain Xinerama-aware appli- - cations do special things with screen 0. To change that behavior, - use this option. - The default value is undefined. - - Option "MergedDPI" "string" - The driver will attempt to figure out an appropriate DPI based on the - DDC information and the orientation of the heads when in merged - framebuffer mode. If this value does not suit you, you can manually - set the DPI using this option. - For example, Option "MergedDPI" "100 100" - The default value is undefined. - - Option "IgnoreEDID" "boolean" - Do not use EDID data for mode validation, but DDC is still used for - monitor detection. This is different from NoDDC option. - The default value is off. - - Option "PanelSize" "string" - Should only be used when driver cannot detect the correct panel size. - Apply to both desktop (TMDS) and laptop (LVDS) digital panels. When - a valid panel size is specified, the timings collected from DDC and - BIOS will not be used. If you have a panel with timings different - from that of a standard VESA mode, you have to provide this informa- - tion through the Modeline. - For example, Option "PanelSize" "1400x1050" - The default value is none. - - Option "PanelOff" "boolean" - Disable panel output. - The default value is off. - - Option "EnablePageFlip" "boolean" - Enable page flipping for 3D acceleration. This will increase perfor- - mance but not work correctly in some rare cases, hence the default is - off. - Note: Page flipping does not work well in certain configurations with - MergedFB. If you see rendering errors or other strange behavior, - disable page flipping. - - Option "ForceMinDotClock" "frequency" - Override minimum dot clock. Some Radeon BIOSes report a minimum dot - clock unsuitable (too high) for use with television sets even when - they actually can produce lower dot clocks. If this is the case you - can override the value here. Note that using this option may damage - your hardware. You have been warned. The frequency parameter may be - specified as a float value with standard suffixes like "k", "kHz", - "M", "MHz". - - Option "RenderAccel" "boolean" - Enables or disables hardware Render acceleration. This driver does - not support component alpha (subpixel) rendering. It is only sup- - ported on Radeon series up to and including 9200 (9500/9700 and newer - unsupported). The default is to enable Render acceleration. - - Option "SubPixelOrder" "string" - Force subpixel order to specified order. Subpixel order is used for - subpixel decimation on flat panels. - NONE -- No subpixel (CRT like displays) - RGB -- in horizontal RGB order (most flat panels) - BGR -- in horizontal BGR order (some flat panels) - - This option is intended to be used in following cases: - 1. The default subpixel order is incorrect for your panel. - 2. Enable subpixel decimation on analog panels. - 3. Adjust to one display type in dual-head clone mode setup. - 4. Get better performance with Render acceleration on digital panels - (use NONE setting). - The default is NONE for CRT, RGB for digital panels - - Option "DynamicClocks" "boolean" - Enable dynamic clock scaling. The on-chip clocks will scale dynami- - cally based on usage. This can help reduce heat and increase battery - life by reducing power usage. Some users report reduced 3D prefor- - mance with this enabled. The default is off. - - - -Driver sis: ------------- - - Option "NoAccel" "boolean" - Disable or enable 2D acceleration. Default: acceleration is enabled. - - Option "HWCursor" "boolean" - Enable or disable the HW cursor. Default: HWCursor is on. - - Option "SWCursor" "boolean" - The opposite of HWCursor. Default: SWCursor is off. - - Option "Rotate" "CW" - Rotate the display clockwise. This mode is unaccelerated, and uses - the Shadow Frame Buffer layer. Using this option disables the Resize - and Rotate extension (RandR). Default: no rotation. - - Option "Rotate" "CCW" - Rotate the display counterclockwise. This mode is unaccelerated, and - uses the Shadow Frame Buffer layer. Using this option disables the - Resize and Rotate extension (RandR). Default: no rotation. - - Option "ShadowFB" "boolean" - Enable or disable use of the shadow framebuffer layer. Default: - Shadow framebuffer is off. - - Option "CRT1Gamma" "boolean" - Enable or disable gamma correction. Default: Gamma correction is on. - - - -Driver vesa: -------------- -(source: man vesa) - - Option "ShadowFB" "boolean" - Enable or disable use of the shadow framebuffer layer. Default: on. - This option is recommended for performance reasons. - diff --git a/displayconfig/energy.py b/displayconfig/energy.py deleted file mode 100644 index 28c0799..0000000 --- a/displayconfig/energy.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'energy.ui' -# -# Created: Fri Jun 24 03:45:58 2005 -# by: The PyQt User Interface Compiler (pyuic) 3.14.1 -# -# WARNING! All changes made in this file will be lost! - - -from qt import * - -class DPMSTab(QDialog): - def __init__(self,parent = None,name = None,modal = 0,fl = 0): - QDialog.__init__(self,parent,name,modal,fl) - - if not name: - self.setName("DPMSTab") - - - DPMSTabLayout = QVBoxLayout(self,11,6,"DPMSTabLayout") - - titlelayout = QHBoxLayout(None,0,6,"titlelayout") - topspacer = QSpacerItem(221,20,QSizePolicy.Expanding,QSizePolicy.Minimum) - titlelayout.addItem(topspacer) - - self.energystarpix = QLabel(self,"energystarpix") - self.energystarpix.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.energystarpix.sizePolicy().hasHeightForWidth())) - self.energystarpix.setMinimumSize(QSize(150,77)) - self.energystarpix.setPixmap(QPixmap("energystar.png")) - self.energystarpix.setScaledContents(1) - titlelayout.addWidget(self.energystarpix) - DPMSTabLayout.addLayout(titlelayout) - - self.screensavergroup = QGroupBox(self,"screensavergroup") - self.screensavergroup.setCheckable(1) - self.screensavergroup.setColumnLayout(0,Qt.Vertical) - self.screensavergroup.layout().setSpacing(6) - self.screensavergroup.layout().setMargin(11) - screensavergroupLayout = QHBoxLayout(self.screensavergroup.layout()) - screensavergroupLayout.setAlignment(Qt.AlignTop) - spacer4 = QSpacerItem(101,20,QSizePolicy.Expanding,QSizePolicy.Minimum) - screensavergroupLayout.addItem(spacer4) - - self.screensavertext = QLabel(self.screensavergroup,"screensavertext") - screensavergroupLayout.addWidget(self.screensavertext) - - self.screensavercombo = QComboBox(0,self.screensavergroup,"screensavercombo") - screensavergroupLayout.addWidget(self.screensavercombo) - DPMSTabLayout.addWidget(self.screensavergroup) - - self.dpmsgroup = QGroupBox(self,"dpmsgroup") - self.dpmsgroup.setCheckable(1) - self.dpmsgroup.setColumnLayout(0,Qt.Vertical) - self.dpmsgroup.layout().setSpacing(6) - self.dpmsgroup.layout().setMargin(11) - dpmsgroupLayout = QHBoxLayout(self.dpmsgroup.layout()) - dpmsgroupLayout.setAlignment(Qt.AlignTop) - spacer4_2 = QSpacerItem(244,20,QSizePolicy.Expanding,QSizePolicy.Minimum) - dpmsgroupLayout.addItem(spacer4_2) - - self.dpmstext = QLabel(self.dpmsgroup,"dpmstext") - dpmsgroupLayout.addWidget(self.dpmstext) - - self.dpmscombo = QComboBox(0,self.dpmsgroup,"dpmscombo") - dpmsgroupLayout.addWidget(self.dpmscombo) - DPMSTabLayout.addWidget(self.dpmsgroup) - bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding) - DPMSTabLayout.addItem(bottomspacer) - - self.languageChange() - - self.resize(QSize(508,372).expandedTo(self.minimumSizeHint())) - self.clearWState(Qt.WState_Polished) - - - def languageChange(self): - self.setCaption(self.__tr("Display power saving")) - self.screensavergroup.setTitle(self.__tr("Enable screensaver")) - self.screensavertext.setText(self.__tr("Start screensaver after")) - self.dpmsgroup.setTitle(self.__tr("Enable display powermanagement")) - self.dpmstext.setText(self.__tr("Switch display off after")) - - - def __tr(self,s,c = None): - return tqApp.translate("DPMSTab",s,c) diff --git a/displayconfig/energystar.png b/displayconfig/energystar.png deleted file mode 100644 index 1a79fe7..0000000 Binary files a/displayconfig/energystar.png and /dev/null differ diff --git a/displayconfig/execwithcapture.py b/displayconfig/execwithcapture.py deleted file mode 100644 index 10c8e23..0000000 --- a/displayconfig/execwithcapture.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python - -import os -import select - -############################################################################ -def ExecWithCapture(command, argv, searchPath = 0, root = '/', stdin = 0, - catchfd = 1, closefd = -1): - - if not os.access(root + command, os.X_OK) and not searchPath: - raise RuntimeError, command + " can not be run" - - (read, write) = os.pipe() - childpid = os.fork() - if (not childpid): - if (root and root != '/'): os.chroot(root) - os.dup2(write, catchfd) - os.close(write) - os.close(read) - - if closefd != -1: - os.close(closefd) - if stdin: - os.dup2(stdin, 0) - os.close(stdin) - if searchPath: - os.execvp(command, argv) - else: - os.execv(command, argv) - sys.exit(1) - os.close(write) - - rc = "" - s = "1" - while s: - select.select([read], [], []) - s = os.read(read, 1000) - rc = rc + s - - os.close(read) - - try: - os.waitpid(childpid, 0) - except OSError, (errno, msg): - print __name__, "waitpid:", msg - - return rc diff --git a/displayconfig/extramodes b/displayconfig/extramodes deleted file mode 100644 index 94dec61..0000000 --- a/displayconfig/extramodes +++ /dev/null @@ -1,39 +0,0 @@ -// -// Extra modes to include as default modes in the X server. -// -// Based on Xorg's xc/programs/Xserver/hw/xfree86/etc/extramodes file. -// The mode names have been changed to include the refresh rate. -// - -# 832x624 @ 75Hz (74.55Hz) (fix if the official/Apple spec is different) hsync: 49.725kHz -ModeLine "832x624@75" 57.284 832 864 928 1152 624 625 628 667 -Hsync -Vsync - -# 1280x960 @ 60.00 Hz (GTF) hsync: 59.64 kHz; pclk: 102.10 MHz -Modeline "1280x960@60" 102.10 1280 1360 1496 1712 960 961 964 994 -HSync +Vsync - -# 1280x960 @ 75.00 Hz (GTF) hsync: 75.15 kHz; pclk: 129.86 MHz -Modeline "1280x960@75" 129.86 1280 1368 1504 1728 960 961 964 1002 -HSync +Vsync - -# 1152x768 @ 54.8Hz (Titanium PowerBook) hsync: 44.2kHz -ModeLine "1152x768@54" 64.995 1152 1178 1314 1472 768 771 777 806 +hsync +vsync - -# 1400x1050 @ 60Hz (VESA GTF) hsync: 65.5kHz -ModeLine "1400x1050@60" 122.0 1400 1488 1640 1880 1050 1052 1064 1082 +hsync +vsync - -# 1400x1050 @ 75Hz (VESA GTF) hsync: 82.2kHz -ModeLine "1400x1050@75" 155.8 1400 1464 1784 1912 1050 1052 1064 1090 +hsync +vsync - -# 1600x1024 @ 60Hz (SGI 1600SW) hsync: 64.0kHz -Modeline "1600x1024@60" 106.910 1600 1620 1640 1670 1024 1027 1030 1067 -hsync -vsync - -# 1920x1440 @ 85Hz (VESA GTF) hsync: 128.5kHz -Modeline "1920x1440@85" 341.35 1920 2072 2288 2656 1440 1441 1444 1512 -hsync +vsync - -# 2048x1536 @ 60Hz (VESA GTF) hsync: 95.3kHz -Modeline "2048x1536@60" 266.95 2048 2200 2424 2800 1536 1537 1540 1589 -hsync +vsync - -# 2048x1536 @ 75Hz (VESA GTF) hsync: 120.2kHz -Modeline "2048x1536@75" 340.48 2048 2216 2440 2832 1536 1537 1540 1603 -hsync +vsync - -# 2048x1536 @ 85Hz (VESA GTF) hsync: 137.0kHz -Modeline "2048x1536@85" 388.04 2048 2216 2440 2832 1536 1537 1540 1612 -hsync +vsync diff --git a/displayconfig/infimport.py b/displayconfig/infimport.py deleted file mode 100755 index f51475d..0000000 --- a/displayconfig/infimport.py +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/python -# -# Based on inf2mondb.py from RedHat -# -# originally by Matt Wilson -# option parsing and database comparison by Fred New -# ini parsing completely rewritten by Matt Domsch 2006 -# -# Copyright 2002 Red Hat, Inc. -# Copyright 2006 Dell, Inc. -# Copyright 2007 Sebastian Heinlein -# -# 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. -""" -Provides an importer for Microsoft Windows monitor descriptions - -The code can be used as a python module for or as a script to add new monitor -definitions to a monitor database. - -In code example: Read the list of monitors from an inf file. - -import infimport -monitors = infimport.get_monitors_from_inf(PATH) - -Script example: To check for monitors of an inf file that are not yet in the database. - -./infimport.py MONITORS.inf /usr/share/hwdata/MonitorsDB -""" - -import sys -import string -import re -import ConfigParser -import os - -import logging - -logging.basicConfig() -log = logging.getLogger("infimport") -#log.setLevel(logging.DEBUG) -log.setLevel(logging.INFO) - -# this is a class to deal with various file line endings and leading whitespace -# converts all \r line endings to \n. -# It also strips leading whitespace. -# NOTE: be sure to always return _something_, even if it is just "\n", or we -# break the file API. (nothing == eof) -class myFile(object): - def __init__(self, *args): - self.fd = open(*args) - - def close(self): - return self.fd.close() - - def readline(self, *args): - line = self.fd.readline(*args) - line = line.replace('\r', '\n') - line = line.replace('\n\n', '\n') - line = line.lstrip(" \t") - return line - - -# we will use this to override default option parsing in ConfigParser to handle -# Microsoft-style "INI" files. (Which do not necessarily have " = value " after -# the option name -OPTCRE = re.compile( - r'(?P