@ -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
|
|
@ -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("<xxxxxxxxxBHxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxHH",buf)
|
|
||||||
#print "STRUCT: ",struct.unpack("@xxxxxxxxxBHxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxHH",buf)
|
|
||||||
if (entry.subvendor==0 and entry.subdevice==0) or \
|
|
||||||
(entry.subvendor==entry.vendor and entry.subdevice==entry.device):
|
|
||||||
entry.subvendor = 0xffff
|
|
||||||
entry.subdevice = 0xffff
|
|
||||||
if entry.pci_class == PCIBus.PCI_CLASS_SERIAL_USB:
|
|
||||||
# taken from kudzu's pci.c
|
|
||||||
if class_prog == 0:
|
|
||||||
entry.module = "usb-uhci"
|
|
||||||
elif class_prog == 0x10:
|
|
||||||
entry.module = "usb-ohci"
|
|
||||||
elif class_prog == 0x20:
|
|
||||||
entry.module = "ehci-hcd"
|
|
||||||
if entry.pci_class == PCIBus.PCI_CLASS_SERIAL_FIREWIRE:
|
|
||||||
# taken from kudzu's pci.c
|
|
||||||
if class_prog == 0x10:
|
|
||||||
entry.module = "ohci1394"
|
|
||||||
infohandle.close()
|
|
||||||
except IOError:
|
|
||||||
pass
|
|
||||||
fhandle.close()
|
|
||||||
|
|
||||||
#if False or os.path.exists("/usr/share/ldetect-lst/pcitable"):
|
|
||||||
#self._resolveDevicesWithLdetect()
|
|
||||||
#else:
|
|
||||||
self._resolveDevicesWithHwdata()
|
|
||||||
#self._resolveDevicesWithDiscover()
|
|
||||||
|
|
||||||
def _resolveDevicesWithLdetect(self):
|
|
||||||
# Scan the PCI database.
|
|
||||||
#fhandle = open(os.path.join(self.data_file_dir,"pcitable"),"r")
|
|
||||||
fhandle = open(os.path.join("/opt/trinity/share/apps/guidance/","pcitable"),"r")
|
|
||||||
|
|
||||||
# This class is just for skipping comment lines in the database file.
|
|
||||||
# This whole class is just an iterator wrapper that we put around our file iterator.
|
|
||||||
class commentskipperiterator(object):
|
|
||||||
def __init__(self,fhandle):
|
|
||||||
self.fhandle = iter(fhandle)
|
|
||||||
def __iter__(self):
|
|
||||||
return self
|
|
||||||
def next(self):
|
|
||||||
line = self.fhandle.next()
|
|
||||||
while line[0]=="#":
|
|
||||||
line = self.fhandle.next()
|
|
||||||
return line
|
|
||||||
|
|
||||||
unknowndevices = self.devices[:]
|
|
||||||
|
|
||||||
# Process each row of the DB.
|
|
||||||
for row in csv.reader(commentskipperiterator(fhandle),delimiter='\t'):
|
|
||||||
if len(row)==4:
|
|
||||||
(vendor,device,module,text) = row
|
|
||||||
elif len(row)==6:
|
|
||||||
(vendor, device, subvendor, subdevice, module, text) = row
|
|
||||||
subvendor = int(subvendor[2:],16)
|
|
||||||
subdevice = int(subdevice[2:],16)
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
vendor = int(vendor[2:],16) # parse hex numbers of the form 0x1abc
|
|
||||||
device = int(device[2:],16)
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
while i<len(unknowndevices):
|
|
||||||
pcidevice = unknowndevices[i]
|
|
||||||
if pcidevice.vendor==vendor and pcidevice.device==device \
|
|
||||||
and (len(row)==4 \
|
|
||||||
or (pcidevice.subvendor==subvendor and pcidevice.subdevice==subdevice)):
|
|
||||||
if module!="unknown":
|
|
||||||
pcidevice.module = module
|
|
||||||
pcidevice.text = text
|
|
||||||
if len(row)==6: # Close match, also matched on subdevice/subvendor ids.
|
|
||||||
del unknowndevices[i]
|
|
||||||
else:
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
fhandle.close()
|
|
||||||
|
|
||||||
def _resolveDevicesWithDiscover(self):
|
|
||||||
|
|
||||||
unknown_devices = self.devices[:]
|
|
||||||
self._resolveDevicesWithDiscoverFile("/usr/share/discover/pci-26.lst",unknown_devices)
|
|
||||||
self._resolveDevicesWithDiscoverFile("/usr/share/discover/pci.lst",unknown_devices)
|
|
||||||
|
|
||||||
def _resolveDevicesWithDiscoverFile(self,filename,unknown_devices):
|
|
||||||
# Scan the PCI database.
|
|
||||||
fhandle = open(filename,"r")
|
|
||||||
|
|
||||||
# Process each row of the DB.
|
|
||||||
for line in fhandle:
|
|
||||||
row = line.replace("\t"," ").split(" ")
|
|
||||||
if len(row) >= 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 i<len(unknown_devices):
|
|
||||||
pcidevice = unknown_devices[i]
|
|
||||||
if pcidevice.vendor==vendor and pcidevice.device==device:
|
|
||||||
pcidevice.module = module
|
|
||||||
pcidevice.text = text
|
|
||||||
del unknown_devices[i]
|
|
||||||
else:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
fhandle.close()
|
|
||||||
|
|
||||||
def _resolveDevicesWithHwdata(self):
|
|
||||||
# Scan the PCI database.
|
|
||||||
fhandle = open("/usr/share/hwdata/pci.ids","r")
|
|
||||||
|
|
||||||
# This class is just for skipping comment lines in the database file.
|
|
||||||
# This whole class is just an iterator wrapper that we put around our file iterator.
|
|
||||||
class commentskipperiterator(object):
|
|
||||||
def __init__(self,fhandle):
|
|
||||||
self.fhandle = iter(fhandle)
|
|
||||||
def __iter__(self):
|
|
||||||
return self
|
|
||||||
def next(self):
|
|
||||||
line = self.fhandle.next()
|
|
||||||
while line[0]=="#":
|
|
||||||
line = self.fhandle.next()
|
|
||||||
return line
|
|
||||||
|
|
||||||
unknowndevices = self.devices[:]
|
|
||||||
|
|
||||||
# Process each row of the DB.
|
|
||||||
for row in fhandle:
|
|
||||||
stripped_row = row.strip()
|
|
||||||
|
|
||||||
if stripped_row=='' or stripped_row[0]=='#':
|
|
||||||
continue # Comment or blank line, skip it.
|
|
||||||
|
|
||||||
if stripped_row[0]=='C':
|
|
||||||
# Reached the device class data, stop.
|
|
||||||
break
|
|
||||||
|
|
||||||
if row[0]!='\t':
|
|
||||||
# Vendor line
|
|
||||||
vendor_parts = stripped_row.split(' ')
|
|
||||||
vendor = int(vendor_parts[0],16)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if row[1]!='\t':
|
|
||||||
# Device line
|
|
||||||
device_parts = stripped_row.split(' ')
|
|
||||||
device = int(device_parts[0],16)
|
|
||||||
subvendor = None
|
|
||||||
subdevice = None
|
|
||||||
else:
|
|
||||||
# Subvendor line
|
|
||||||
subvendor_parts = stripped_row.split(' ')
|
|
||||||
subvendor = int(subvendor_parts[0],16)
|
|
||||||
subdevice = int(subvendor_parts[1],16)
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
while i<len(unknowndevices):
|
|
||||||
pcidevice = unknowndevices[i]
|
|
||||||
if pcidevice.vendor==vendor and pcidevice.device==device \
|
|
||||||
and (subvendor is None \
|
|
||||||
or (pcidevice.subvendor==subvendor and pcidevice.subdevice==subdevice)):
|
|
||||||
#pcidevice.module = module
|
|
||||||
if subvendor is None:
|
|
||||||
pcidevice.text = ' '.join(vendor_parts[1:]) + '|' + ' '.join(device_parts[1:]).strip()
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
pcidevice.text = ' '.join(vendor_parts[1:]) + '|' + ' '.join(device_parts[1:]+subvendor_parts[2:]).strip()
|
|
||||||
del unknowndevices[i] # Perfect match, finished with this device.
|
|
||||||
else:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
fhandle.close()
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return "\n".join([str(x) for x in self.devices])
|
|
||||||
|
|
||||||
def loadFromFile(self,filename):
|
|
||||||
fhandle = open(filename,'r')
|
|
||||||
for line in fhandle.readlines():
|
|
||||||
if line.strip()!="":
|
|
||||||
entry = PCIDevice(line=line)
|
|
||||||
self.devices.append(entry)
|
|
||||||
fhandle.close()
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
def main():
|
|
||||||
bus = PCIBus("ldetect-lst/")
|
|
||||||
if len(sys.argv)>1:
|
|
||||||
if sys.argv[1]=="--help" or sys.argv[1]=="-h":
|
|
||||||
print "Usage:\n ScanPCI.py <pci device file name>"
|
|
||||||
sys.exit(0)
|
|
||||||
bus.detect(sys.argv[1])
|
|
||||||
else:
|
|
||||||
bus.detect()
|
|
||||||
print bus
|
|
||||||
|
|
||||||
if __name__=='__main__':
|
|
||||||
main()
|
|
@ -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] <Riddell> you are brave indeed
|
|
||||||
# [21:21] <Sime> I figured some kind of non-interactive "dpkg-reconfigure xorg" might be enough.
|
|
||||||
# [21:22] <Riddell> 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()
|
|
@ -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.
|
|
||||||
# <number> - 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<len(xserver.getScreens()):
|
|
||||||
xscreen = xserver.getScreens()[id]
|
|
||||||
|
|
||||||
if xscreen.resolutionSupportAvailable():
|
|
||||||
available_sizes = xscreen.getAvailableSizes()
|
|
||||||
|
|
||||||
# Find the closest matching resolution
|
|
||||||
best_score = 1000000
|
|
||||||
best_size_id = 0
|
|
||||||
for size_id in range(len(available_sizes)):
|
|
||||||
size = available_sizes[size_id]
|
|
||||||
score = abs(size[0]-width)+abs(size[1]-height)
|
|
||||||
if score < best_score:
|
|
||||||
best_size_id = size_id
|
|
||||||
best_score = score
|
|
||||||
|
|
||||||
# Now find the best refresh for this resolution
|
|
||||||
best_score = 1000000
|
|
||||||
best_refresh = 50
|
|
||||||
for available_refresh in xscreen.getAvailableRefreshRates(best_size_id):
|
|
||||||
score = abs(refresh-available_refresh)
|
|
||||||
if score < best_score:
|
|
||||||
best_refresh = available_refresh
|
|
||||||
best_score = score
|
|
||||||
|
|
||||||
# Mask out any unsupported rotations.
|
|
||||||
rotation &= xscreen.getAvailableRotations()
|
|
||||||
xscreen.setScreenConfigAndRate(best_size_id, rotation, best_refresh)
|
|
||||||
|
|
||||||
# Restore the gamma settings.
|
|
||||||
if redgamma is not None and greengamma is not None and bluegamma is not None:
|
|
||||||
try:
|
|
||||||
xscreen.setGamma( (float(redgamma), float(greengamma), float(bluegamma)) )
|
|
||||||
except ValueError,e:
|
|
||||||
pass
|
|
||||||
|
|
||||||
FixXorgDPI(dpi)
|
|
||||||
except xf86misc.XF86Error,err:
|
|
||||||
print err
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
else:
|
|
||||||
# Ensure that the xorgs virtual screen size matches the default resolution
|
|
||||||
# of the server. Why does this matter? When Xorg starts up it reads its
|
|
||||||
# config file chooses the first mode in the "modes" line of the active
|
|
||||||
# Screen section and uses it as the virtual screen size and as the
|
|
||||||
# screen resolution (ie 1024x768 resolution screen showing a 1024x768 gfx
|
|
||||||
# buffer). But, this means that you can't use RandR to get to any higher
|
|
||||||
# screen resolutions (ie 1280x1024) because Xorg requires that the virtual
|
|
||||||
# screen size 'cover' the screen resolution being displayed.
|
|
||||||
#
|
|
||||||
# So, to get around this problem and make it possible for people to select
|
|
||||||
# a lower resolution screen *and* still have the option later to use
|
|
||||||
# RandR/displayconfig to switch to higher resolution, displayconfig
|
|
||||||
# explicitly sets the virtual screen size in xorg.conf to the largest
|
|
||||||
# resoluution that the monitor/gfx card can support. The down side to
|
|
||||||
# this is that the X server and tdm get the correct resolution but the
|
|
||||||
# wrong (virtual) screen size. The user can now scroll around on the
|
|
||||||
# greater virtual screen. Kind of annoying for tdm, unacceptable once
|
|
||||||
# the user has logged in.
|
|
||||||
#
|
|
||||||
# What we do now as the user's KDE session is being started up is check
|
|
||||||
# what the real virtual screen size is meant to be (=same as the real
|
|
||||||
# resolution being used) and then use the RandR extension to explicitly
|
|
||||||
# set the correct resolution. This has the effect of changing the virtual
|
|
||||||
# screeen size to what we really want. (RandR can change the virtual
|
|
||||||
# screen size, thankfully)
|
|
||||||
import displayconfigabstraction
|
|
||||||
|
|
||||||
try:
|
|
||||||
xserver = xf86misc.XF86Server()
|
|
||||||
|
|
||||||
for xscreen in xserver.getScreens():
|
|
||||||
if xscreen.resolutionSupportAvailable():
|
|
||||||
mode_line = ixf86misc.XF86VidModeGetModeLine(xserver.getDisplay(),xscreen.getScreenId())
|
|
||||||
|
|
||||||
hdisplay = mode_line[1]
|
|
||||||
vdisplay = mode_line[5]
|
|
||||||
|
|
||||||
live_refresh_rate = xscreen.getRefreshRate()
|
|
||||||
try:
|
|
||||||
(live_width,live_height,x,x) = xscreen.getAvailableSizes()[xscreen.getSizeID()]
|
|
||||||
except IndexError, errmsg:
|
|
||||||
print "IndexError:", errmsg, "in displayconfig-restore getting live screen size - trying screen 0."
|
|
||||||
(live_width,live_height,x,x) = xscreen.getAvailableSizes()[0]
|
|
||||||
|
|
||||||
if (hdisplay,vdisplay) != (live_width,live_height):
|
|
||||||
# The screen resolution doesn't match the virtual screen size.
|
|
||||||
screen_sizes = xscreen.getAvailableSizes()
|
|
||||||
for size_id in range(len(screen_sizes)):
|
|
||||||
screen_size = screen_sizes[size_id]
|
|
||||||
if screen_size[0]==hdisplay and screen_size[1]==vdisplay:
|
|
||||||
|
|
||||||
# Find the closest matching refresh rate.
|
|
||||||
best_refresh = 0
|
|
||||||
best_score = 1000000
|
|
||||||
for rate in xscreen.getAvailableRefreshRates(size_id):
|
|
||||||
score = abs(rate-live_refresh_rate)
|
|
||||||
if score < best_score:
|
|
||||||
best_refresh = rate
|
|
||||||
best_score = score
|
|
||||||
|
|
||||||
# Reset the screen mode and virtual screen size.
|
|
||||||
xscreen.setScreenConfigAndRate(size_id,xscreen.getRotation(),best_refresh)
|
|
||||||
break
|
|
||||||
FixXorgDPI(dpi)
|
|
||||||
except (xf86misc.XF86Error,TypeError),err:
|
|
||||||
print err
|
|
||||||
|
|
||||||
main()
|
|
@ -1,51 +0,0 @@
|
|||||||
[Desktop Entry]
|
|
||||||
Name=Monitor & Display
|
|
||||||
Name[el]=Οθόνη & εμφάνιση
|
|
||||||
Name[es]=Monitor y pantalla
|
|
||||||
Name[et]=Monitor ja kuva
|
|
||||||
Name[it]=Schermo
|
|
||||||
Name[ja]=モニタとディスプレイ
|
|
||||||
Name[nl]=Monitor en beeldscherm
|
|
||||||
Name[pt]=Monitor & Ecrã
|
|
||||||
Name[pt_BR]=Monitor & Visualização
|
|
||||||
Name[sr]=Монитор и приказ
|
|
||||||
Name[sr@Latn]=Monitor i prikaz
|
|
||||||
Name[sv]=Bildskärm och skärm
|
|
||||||
Name[xx]=xxMonitor & Displayxx
|
|
||||||
Comment=Display and Monitor Configuration
|
|
||||||
Comment[el]=Ρυθμίσεις εμφάνισης και οθόνης
|
|
||||||
Comment[es]=Configuración de la pantalla y el monitor
|
|
||||||
Comment[et]=Monitori ja kuva seadistamine
|
|
||||||
Comment[it]=Configurazione dello schermo
|
|
||||||
Comment[ja]=モニタとディスプレイの設定
|
|
||||||
Comment[nl]=Configuratie van beeldscherm en monitor
|
|
||||||
Comment[pt]=Configuração do Monitor e Ecrã
|
|
||||||
Comment[pt_BR]=Configuração do Monitor e da Visualização
|
|
||||||
Comment[sr]=Подешавање приказа и монитора
|
|
||||||
Comment[sr@Latn]=Podešavanje prikaza i monitora
|
|
||||||
Comment[sv]=Skärm- och bildskärmsinställning
|
|
||||||
Comment[xx]=xxDisplay and Monitor Configurationxx
|
|
||||||
Icon=displayconfig.png
|
|
||||||
Encoding=UTF-8
|
|
||||||
X-TDE-ModuleType=Library
|
|
||||||
X-TDE-Library=displayconfig
|
|
||||||
X-TDE-FactoryName=displayconfig
|
|
||||||
X-TDE-RootOnly=true
|
|
||||||
Type=Application
|
|
||||||
Exec=tdecmshell Peripherals/displayconfig
|
|
||||||
Categories=Qt;TDE;X-TDE-settings-hardware;
|
|
||||||
GenericName=Screen Configuration Editor
|
|
||||||
GenericName[el]=Επεξεργαστής ρυθμίσεων οθόνης
|
|
||||||
GenericName[es]=Editor de la configuración de la pantalla
|
|
||||||
GenericName[et]=Ekraani seadistamise redaktor
|
|
||||||
GenericName[it]=Editor della configurazione dello schermo
|
|
||||||
GenericName[ja]=スクリーン設定エディタ
|
|
||||||
GenericName[nl]=Scherminstellingen bewerken
|
|
||||||
GenericName[pt]=Editor da Configuração do Ecrã
|
|
||||||
GenericName[pt_BR]=Editor de Configuração da Tela
|
|
||||||
GenericName[sr]=Уређивач подешавања екрана
|
|
||||||
GenericName[sr@Latn]=Uređivač podešavanja ekrana
|
|
||||||
GenericName[sv]=Editor för skärminställning
|
|
||||||
GenericName[xx]=xxScreen Configuration Editorxx
|
|
||||||
|
|
||||||
NoDisplay=true
|
|
@ -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()
|
|
@ -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("<Unknown>"))
|
|
||||||
self.gfxcardlabel.setText(i18n("<Unknown>"))
|
|
||||||
self.driverlabel.setText(i18n("<none>"))
|
|
||||||
|
|
||||||
# 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("<unknown>")
|
|
||||||
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"), () )
|
|
@ -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)
|
|
Before Width: | Height: | Size: 24 KiB |
@ -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
|
|
@ -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
|
|
@ -1,297 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
#
|
|
||||||
# Based on inf2mondb.py from RedHat
|
|
||||||
#
|
|
||||||
# originally by Matt Wilson <msw@redhat.com>
|
|
||||||
# option parsing and database comparison by Fred New
|
|
||||||
# ini parsing completely rewritten by Matt Domsch <Matt_Domsch@dell.com> 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<option>[^:=\s][^:=]*)' # very permissive!
|
|
||||||
r'\s*(?P<vi>[:=]{0,1})\s*' # any number of space/tab,
|
|
||||||
# optionally followed by
|
|
||||||
# separator (either : or =)
|
|
||||||
# optionally followed
|
|
||||||
# by any # space/tab
|
|
||||||
r'(?P<value>.*)$' # everything up to eol
|
|
||||||
)
|
|
||||||
|
|
||||||
percentSplit = re.compile(r'%(?P<field>.*)%')
|
|
||||||
def _percent_to_string(ini, strings, name):
|
|
||||||
mo = percentSplit.match(name)
|
|
||||||
if (mo):
|
|
||||||
field = mo.group('field')
|
|
||||||
try:
|
|
||||||
val = strings[field.lower()]
|
|
||||||
except KeyError:
|
|
||||||
return ""
|
|
||||||
return val.strip(" '\"")
|
|
||||||
return ""
|
|
||||||
|
|
||||||
def get_monitors_from_database(path):
|
|
||||||
"""Returns a dictonary of the found monitor models in the given
|
|
||||||
monitor models database"""
|
|
||||||
monitors = {}
|
|
||||||
try:
|
|
||||||
mdb = open(path, 'r')
|
|
||||||
except IOError, (errno, str):
|
|
||||||
log.error("Unable to open %s: %s" % (path, str))
|
|
||||||
return {}
|
|
||||||
for line in mdb.readlines():
|
|
||||||
if len(line.strip()) == 0 or line.startswith('#'):
|
|
||||||
continue
|
|
||||||
line_split = line.split(";")
|
|
||||||
vendor = line_split[0].strip()
|
|
||||||
name = line_split[1].strip()
|
|
||||||
id = line_split[2].strip()
|
|
||||||
if monitors.has_key((vendor, name, id)):
|
|
||||||
log.warn("Duplicated entry: %s" % line)
|
|
||||||
else:
|
|
||||||
monitors[(vendor, name, id)] = line
|
|
||||||
mdb.close()
|
|
||||||
return monitors
|
|
||||||
|
|
||||||
def get_monitors_from_inf(path):
|
|
||||||
"""Returns a dictonary of the found monitor models in the given .inf file"""
|
|
||||||
monitors = {}
|
|
||||||
ini = ConfigParser.ConfigParser()
|
|
||||||
# FIXME: perhaps could be done in a nicer way, but __builtins__ is a dict
|
|
||||||
# for imported modules
|
|
||||||
#ini.optionxform = __builtins__.str
|
|
||||||
ini.optionxform = type("")
|
|
||||||
ini.OPTCRE = OPTCRE
|
|
||||||
try:
|
|
||||||
f = myFile(path)
|
|
||||||
ini.readfp(f)
|
|
||||||
f.close()
|
|
||||||
except IOError, (errno, str):
|
|
||||||
log.error("Unable to open %s: %s" % (path, str))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# a dictionary of manufacturers we're looking at
|
|
||||||
manufacturers = {}
|
|
||||||
# a big fat dictionary of strings to use later on.
|
|
||||||
strings = {}
|
|
||||||
|
|
||||||
# This RE is for EISA info lines
|
|
||||||
# %D5259A%=D5259A, Monitor\HWP0487
|
|
||||||
monitor1Re = re.compile(r'.*,.*Monitor\\(?P<id>[^\s]*)')
|
|
||||||
# This one is for legacy entries
|
|
||||||
# %3020% =PB3020, MonID_PB3020
|
|
||||||
monitor2Re = re.compile(r'.*,.*MonID_(?P<id>[^\s]*)')
|
|
||||||
|
|
||||||
for section in ini.sections():
|
|
||||||
if section.lower() == "manufacturer":
|
|
||||||
for mfr in ini.options(section):
|
|
||||||
# generate the vendor.arch funny entries
|
|
||||||
manufacturer_values = string.split(ini.get(section, mfr),
|
|
||||||
',')
|
|
||||||
manufacturers[manufacturer_values[0]] = mfr
|
|
||||||
while len(manufacturer_values) > 1:
|
|
||||||
manufacturers["%s.%s" % (manufacturer_values[0],
|
|
||||||
manufacturer_values[-1])] = mfr
|
|
||||||
manufacturer_values = manufacturer_values[0:-1]
|
|
||||||
|
|
||||||
elif section.lower() == "strings":
|
|
||||||
for key in ini.options(section):
|
|
||||||
strings[key.lower()] = string.strip(ini.get(section, key))
|
|
||||||
|
|
||||||
for mfr in manufacturers.keys():
|
|
||||||
if ini.has_section(mfr):
|
|
||||||
monitor_vendor_name = manufacturers[mfr]
|
|
||||||
for monitor_name in ini.options(mfr):
|
|
||||||
v = ini.get(mfr, monitor_name)
|
|
||||||
v = v.split(',')
|
|
||||||
install_key = v[0].strip()
|
|
||||||
|
|
||||||
line = ini.get(mfr, monitor_name)
|
|
||||||
# Find monitor inf IDs and EISA ids
|
|
||||||
|
|
||||||
edid = "0"
|
|
||||||
mo = monitor1Re.match(line)
|
|
||||||
if mo:
|
|
||||||
edid = mo.group('id')
|
|
||||||
else:
|
|
||||||
mo = monitor2Re.match(line)
|
|
||||||
if mo:
|
|
||||||
edid = mo.group('id').strip()
|
|
||||||
|
|
||||||
#if self.monitors.has_key(edid.lower()):
|
|
||||||
# continue
|
|
||||||
|
|
||||||
if ini.has_section(install_key):
|
|
||||||
line = ini.get(install_key, "AddReg")
|
|
||||||
if line:
|
|
||||||
sline = line.split(',')
|
|
||||||
registry = sline[0]
|
|
||||||
try:
|
|
||||||
resolution = sline[1]
|
|
||||||
except IndexError:
|
|
||||||
resolution = ""
|
|
||||||
try:
|
|
||||||
dpms = sline[2]
|
|
||||||
except IndexError:
|
|
||||||
dpms = ""
|
|
||||||
|
|
||||||
if ini.has_section(registry):
|
|
||||||
for line in ini.options(registry):
|
|
||||||
if string.find(line, 'HKR,"MODES') >= 0:
|
|
||||||
sline = line.split('"')
|
|
||||||
try:
|
|
||||||
syncline = sline[3]
|
|
||||||
except IndexError:
|
|
||||||
syncline = ","
|
|
||||||
syncline = syncline.split(',')
|
|
||||||
hsync = syncline[0].strip()
|
|
||||||
vsync = syncline[1].strip()
|
|
||||||
|
|
||||||
vendor_clear = _percent_to_string(ini,
|
|
||||||
strings, monitor_vendor_name)
|
|
||||||
monitor_clear = _percent_to_string(ini,
|
|
||||||
strings, monitor_name)
|
|
||||||
|
|
||||||
output = "%s; %s; %s; %s; %s" % \
|
|
||||||
(vendor_clear, monitor_clear,
|
|
||||||
edid, hsync, vsync)
|
|
||||||
if dpms.lower().strip() == "dpms":
|
|
||||||
output = output + "; 1"
|
|
||||||
|
|
||||||
if not monitors.has_key((vendor_clear,
|
|
||||||
monitor_clear, edid.lower())):
|
|
||||||
log.debug("added %s" % output)
|
|
||||||
monitors[(vendor_clear,
|
|
||||||
monitor_clear,
|
|
||||||
edid.lower())] = output
|
|
||||||
else:
|
|
||||||
log.warn("duplicated entry %s" % output)
|
|
||||||
return monitors
|
|
||||||
|
|
||||||
def write_monitors_to_file(monitors, path):
|
|
||||||
"""Writes monitors as a monitor models database"""
|
|
||||||
try:
|
|
||||||
if os.path.exists(path):
|
|
||||||
os.remove(path)
|
|
||||||
mdb = open(path, 'w')
|
|
||||||
mdb.writelines(map(lambda l: "%s\n" % l, monitors.values()))
|
|
||||||
mdb.close()
|
|
||||||
except IOError, (errno, str):
|
|
||||||
log.error("Unable to write %s: %s" % (path, str))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def append_monitors_to_file(monitors, path):
|
|
||||||
"""Appends monitors to a monitor models database"""
|
|
||||||
try:
|
|
||||||
if os.path.exists(path):
|
|
||||||
os.remove(path)
|
|
||||||
mdb = open(path, 'a')
|
|
||||||
mdb.writelines(map(lambda l: "%s\n" % l, monitors.values()))
|
|
||||||
mdb.close()
|
|
||||||
except IOError, (errno, str):
|
|
||||||
log.error("Unable to write %s: %s" % (path, str))
|
|
||||||
return False
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
from optparse import OptionParser
|
|
||||||
import sys
|
|
||||||
|
|
||||||
parser = OptionParser()
|
|
||||||
parser.add_option("-a", "--append",
|
|
||||||
action="store_true", dest="append",
|
|
||||||
help="Append new models to the database")
|
|
||||||
parser.add_option("-o", "--output",
|
|
||||||
default=None,
|
|
||||||
action="store", type="string", dest="output",
|
|
||||||
help="Write changes to an alternative file")
|
|
||||||
parser.usage = "%prog [options] INF_FILE [MONITOR_DATABASE]"
|
|
||||||
(options, args) = parser.parse_args()
|
|
||||||
|
|
||||||
if len(args) == 2:
|
|
||||||
# continue with normal operation
|
|
||||||
pass
|
|
||||||
elif len(args) == 1:
|
|
||||||
# jsut print the monitors from the given inf file
|
|
||||||
monitors_inf = get_monitors_from_inf(args[0])
|
|
||||||
for mon in monitors_inf.values():
|
|
||||||
print "%s" % mon
|
|
||||||
sys.exit()
|
|
||||||
else:
|
|
||||||
parser.error("You have to specify an .inf file that contains the "
|
|
||||||
"monitor models that you want to add and a "
|
|
||||||
"monitor model database")
|
|
||||||
|
|
||||||
monitors_inf = get_monitors_from_inf(args[0])
|
|
||||||
monitors_db = get_monitors_from_database(args[1])
|
|
||||||
|
|
||||||
monitors_new = {}
|
|
||||||
for mon in monitors_inf.keys():
|
|
||||||
if not monitors_db.has_key(mon):
|
|
||||||
log.info("New monitor: %s" % monitors_inf[mon])
|
|
||||||
monitors_new[mon] = monitors_inf[mon]
|
|
||||||
|
|
||||||
if options.append:
|
|
||||||
if options.output:
|
|
||||||
append_monitors_to_file(monitors_new, options.output)
|
|
||||||
else:
|
|
||||||
append_monitors_to_file(new_monitors, args[1])
|
|
@ -1,155 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
###########################################################################
|
|
||||||
# ktimerdialog.py - description #
|
|
||||||
# ------------------------------ #
|
|
||||||
# begin : Mon Jul 26 2004 #
|
|
||||||
# copyright : (C) 2004 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. #
|
|
||||||
# #
|
|
||||||
###########################################################################
|
|
||||||
# Based on Hamish Rodda's ktimerdialog.cpp.
|
|
||||||
|
|
||||||
from qt import *
|
|
||||||
from tdecore import *
|
|
||||||
from tdeui import *
|
|
||||||
|
|
||||||
class KTimerDialog(KDialogBase):
|
|
||||||
CountDown = 0
|
|
||||||
CountUp = 1
|
|
||||||
Manual = 2
|
|
||||||
|
|
||||||
def __init__(self, msec, style, parent, name, modal, caption="", \
|
|
||||||
buttonmask=KDialogBase.Ok|KDialogBase.Cancel|KDialogBase.Apply, \
|
|
||||||
defaultbutton=KDialogBase.Cancel, separator=False, \
|
|
||||||
user1=KGuiItem(), user2=KGuiItem(), user3=KGuiItem()):
|
|
||||||
"""Parameters:
|
|
||||||
|
|
||||||
msec - integer, timeout in milliseconds
|
|
||||||
style - TimerStyle object.
|
|
||||||
parent - parent QWidget
|
|
||||||
name - String
|
|
||||||
model - boolean.
|
|
||||||
caption - String
|
|
||||||
buttonmask - integer
|
|
||||||
defaultbutton - ButtonCode
|
|
||||||
separator - boolean
|
|
||||||
user1 - KGuiItem
|
|
||||||
user2 - KGuiItem
|
|
||||||
user3 - KGuiItem
|
|
||||||
"""
|
|
||||||
|
|
||||||
KDialogBase.__init__(self,parent, name, modal, caption, buttonmask, defaultbutton, \
|
|
||||||
separator, user1, user2, user3 )
|
|
||||||
|
|
||||||
self.totaltimer = QTimer(self)
|
|
||||||
self.updatetimer = QTimer(self)
|
|
||||||
self.msectotal = self.msecremaining = msec
|
|
||||||
self.updateinterval = 1000
|
|
||||||
self.tstyle = style
|
|
||||||
|
|
||||||
# default to cancelling the dialog on timeout
|
|
||||||
if buttonmask & self.Cancel:
|
|
||||||
self.buttonontimeout = self.Cancel
|
|
||||||
|
|
||||||
self.connect(self.totaltimer, SIGNAL("timeout()"), self.slotInternalTimeout)
|
|
||||||
self.connect(self.updatetimer, SIGNAL("timeout()"), self.slotUpdateTime)
|
|
||||||
|
|
||||||
# create the widgets
|
|
||||||
self.mainwidget = QVBox(self, "mainWidget")
|
|
||||||
self.timerwidget = QHBox(self.mainwidget, "timerWidget")
|
|
||||||
self.timerlabel = QLabel(self.timerwidget)
|
|
||||||
self.timerprogress = QProgressBar(self.timerwidget)
|
|
||||||
self.timerprogress.setTotalSteps(self.msectotal)
|
|
||||||
self.timerprogress.setPercentageVisible(False)
|
|
||||||
self.setMainWidget(self.mainwidget)
|
|
||||||
self.slotUpdateTime(False)
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
self.msecremaining = self.msectotal
|
|
||||||
self.slotUpdateTime(False)
|
|
||||||
KDialogBase.show(self)
|
|
||||||
self.totaltimer.start(self.msectotal, True)
|
|
||||||
self.updatetimer.start(self.updateinterval, False)
|
|
||||||
|
|
||||||
def exec_loop(self):
|
|
||||||
self.totaltimer.start(self.msectotal, True)
|
|
||||||
self.updatetimer.start(self.updateinterval, False)
|
|
||||||
return KDialogBase.exec_loop(self)
|
|
||||||
|
|
||||||
def setMainWidget(self, newmainwidget):
|
|
||||||
# yuck, here goes.
|
|
||||||
newwidget = QVBox(self)
|
|
||||||
|
|
||||||
if newmainwidget.parentWidget()!=self.mainwidget:
|
|
||||||
newmainwidget.reparent(newwidget, 0, QPoint(0,0))
|
|
||||||
else:
|
|
||||||
newwidget.insertChild(newmainwidget)
|
|
||||||
|
|
||||||
self.timerwidget.reparent(newwidget, 0, QPoint(0, 0))
|
|
||||||
|
|
||||||
self.mainwidget = newwidget
|
|
||||||
KDialogBase.setMainWidget(self, self.mainwidget)
|
|
||||||
|
|
||||||
def setRefreshInterval(self, msec):
|
|
||||||
self.updateinterval = msec;
|
|
||||||
if self.updatetimer.isActive():
|
|
||||||
self.updatetimer.changeInterval(self.updateinterval)
|
|
||||||
|
|
||||||
def timeoutButton(self):
|
|
||||||
return self.buttonontimeout
|
|
||||||
|
|
||||||
def setTimeoutButton(self, newbutton):
|
|
||||||
self.buttonontimeout = newbutton
|
|
||||||
|
|
||||||
def timerStyle(self):
|
|
||||||
return self.tstyle
|
|
||||||
|
|
||||||
def setTimerStyle(self, newstyle):
|
|
||||||
self.tstyle = newstyle
|
|
||||||
|
|
||||||
def slotUpdateTime(self, update=True):
|
|
||||||
if update:
|
|
||||||
if self.tstyle==self.CountDown:
|
|
||||||
self.msecremaining -= self.updateinterval
|
|
||||||
elif self.tstyle==self.CountUp:
|
|
||||||
self.msecremaining += self.updateinterval
|
|
||||||
|
|
||||||
self.timerprogress.setProgress(self.msecremaining)
|
|
||||||
self.timerlabel.setText( i18n("%1 seconds remaining:").arg(self.msecremaining/1000.0) )
|
|
||||||
|
|
||||||
def slotInternalTimeout(self):
|
|
||||||
#self.emit(SIGNAL("timerTimeout()"), () )
|
|
||||||
if self.buttonontimeout==self.Help:
|
|
||||||
self.slotHelp()
|
|
||||||
elif self.buttonontimeout==self.Default:
|
|
||||||
self.slotDefault()
|
|
||||||
elif self.buttonontimeout==self.Ok:
|
|
||||||
self.slotOk()
|
|
||||||
elif self.buttonontimeout==self.Apply:
|
|
||||||
self.applyPressed()
|
|
||||||
elif self.buttonontimeout==self.Try:
|
|
||||||
self.slotTry()
|
|
||||||
elif self.buttonontimeout==self.Cancel:
|
|
||||||
self.slotCancel()
|
|
||||||
elif self.buttonontimeout==self.Close:
|
|
||||||
self.slotClose()
|
|
||||||
#case User1:
|
|
||||||
# slotUser1();
|
|
||||||
#case User2:
|
|
||||||
# slotUser2();
|
|
||||||
# break;
|
|
||||||
elif self.buttonontimeout==self.User3:
|
|
||||||
self.slotUser3()
|
|
||||||
elif self.buttonontimeout==self.No:
|
|
||||||
self.slotNo()
|
|
||||||
elif self.buttonontimeout==self.Yes:
|
|
||||||
self.slotCancel()
|
|
||||||
elif self.buttonontimeout==self.Details:
|
|
||||||
self.slotDetails()
|
|
Before Width: | Height: | Size: 3.5 KiB |
@ -1,113 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
###########################################################################
|
|
||||||
# servertestdialog.py - #
|
|
||||||
# ------------------------------ #
|
|
||||||
# copyright : (C) 2004 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. #
|
|
||||||
# #
|
|
||||||
###########################################################################
|
|
||||||
from qt import * # Just use Qt for this.
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ServerTestDialog(QDialog):
|
|
||||||
def __init__(self):
|
|
||||||
QDialog.__init__(self)
|
|
||||||
|
|
||||||
msec = 10000
|
|
||||||
margin = 4
|
|
||||||
spacing = 4
|
|
||||||
|
|
||||||
self.totaltimer = QTimer(self)
|
|
||||||
self.updatetimer = QTimer(self)
|
|
||||||
self.msectotal = self.msecremaining = msec
|
|
||||||
self.updateinterval = 1000
|
|
||||||
|
|
||||||
self.connect(self.totaltimer, SIGNAL("timeout()"), self.slotInternalTimeout)
|
|
||||||
self.connect(self.updatetimer, SIGNAL("timeout()"), self.slotUpdateTime)
|
|
||||||
|
|
||||||
layout = QHBoxLayout(self)
|
|
||||||
# create the widgets
|
|
||||||
self.mainwidget = QVBox(self, "mainWidget")
|
|
||||||
self.mainwidget.setMargin(margin)
|
|
||||||
self.mainwidget.setSpacing(spacing)
|
|
||||||
|
|
||||||
layout.addWidget(self.mainwidget,1)
|
|
||||||
|
|
||||||
label = QLabel(self.mainwidget)
|
|
||||||
label.setText(i18n("Are these settings acceptable?"))
|
|
||||||
QWidget(self.mainwidget)
|
|
||||||
|
|
||||||
self.timerwidget = QHBox(self.mainwidget, "timerWidget")
|
|
||||||
self.timerlabel = QLabel(self.timerwidget)
|
|
||||||
self.timerprogress = QProgressBar(self.timerwidget)
|
|
||||||
self.timerprogress.setTotalSteps(self.msectotal)
|
|
||||||
self.timerprogress.setPercentageVisible(False)
|
|
||||||
|
|
||||||
hbox = QHBox(self.mainwidget)
|
|
||||||
self.okbutton = QPushButton(i18n("Yes"),hbox)
|
|
||||||
QWidget(hbox)
|
|
||||||
self.cancelbutton = QPushButton(i18n("No"),hbox)
|
|
||||||
self.connect(self.okbutton, SIGNAL("clicked()"), self.slotOk)
|
|
||||||
self.connect(self.cancelbutton, SIGNAL("clicked()"), self.slotCancel)
|
|
||||||
|
|
||||||
self.slotUpdateTime(False)
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
QDialog.show(self)
|
|
||||||
self.totaltimer.start(self.msectotal, True)
|
|
||||||
self.updatetimer.start(self.updateinterval, False)
|
|
||||||
|
|
||||||
def exec_loop(self):
|
|
||||||
self.totaltimer.start(self.msectotal, True)
|
|
||||||
self.updatetimer.start(self.updateinterval, False)
|
|
||||||
return QDialog.exec_loop(self)
|
|
||||||
|
|
||||||
def setRefreshInterval(self, msec):
|
|
||||||
self.updateinterval = msec;
|
|
||||||
if self.updatetimer.isActive():
|
|
||||||
self.updatetimer.changeInterval(self.updateinterval)
|
|
||||||
|
|
||||||
def timeoutButton(self):
|
|
||||||
return self.buttonontimeout
|
|
||||||
|
|
||||||
def setTimeoutButton(self, newbutton):
|
|
||||||
self.buttonontimeout = newbutton
|
|
||||||
|
|
||||||
def slotUpdateTime(self, update=True):
|
|
||||||
self.msecremaining -= self.updateinterval
|
|
||||||
|
|
||||||
self.timerprogress.setProgress(self.msecremaining)
|
|
||||||
self.timerlabel.setText( i18n("Automatically cancelling in %1 seconds:").arg(self.msecremaining/1000.0) )
|
|
||||||
|
|
||||||
def slotInternalTimeout(self):
|
|
||||||
self.reject()
|
|
||||||
|
|
||||||
def slotOk(self):
|
|
||||||
self.accept()
|
|
||||||
|
|
||||||
def slotCancel(self):
|
|
||||||
self.reject()
|
|
||||||
############################################################################
|
|
||||||
|
|
||||||
os.environ["DISPLAY"] = ":9"
|
|
||||||
os.environ["XAUTHORITY"] = sys.argv[1]
|
|
||||||
|
|
||||||
# FIXME set the application name / string catalog, for i18n().
|
|
||||||
qapp = QApplication(sys.argv)
|
|
||||||
dialog = ServerTestDialog()
|
|
||||||
dialog.show()
|
|
||||||
dialog.exec_loop()
|
|
||||||
|
|
||||||
if dialog.result()==QDialog.Accepted:
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
sys.exit(1)
|
|
@ -1,110 +0,0 @@
|
|||||||
//
|
|
||||||
// Default modes distilled from
|
|
||||||
// "VESA and Industry Standards and Guide for Computer Display Monitor
|
|
||||||
// Timing", version 1.0, revision 0.8, adopted September 17, 1998.
|
|
||||||
//
|
|
||||||
// Based on Xorg's xc/programs/Xserver/hw/xfree86/etc/vesamodes file.
|
|
||||||
// The mode names have been changed to include the refresh rate.
|
|
||||||
|
|
||||||
|
|
||||||
# 640x350 @ 85Hz (VESA) hsync: 37.9kHz
|
|
||||||
ModeLine "640x350@85" 31.5 640 672 736 832 350 382 385 445 +hsync -vsync
|
|
||||||
|
|
||||||
# 640x400 @ 85Hz (VESA) hsync: 37.9kHz
|
|
||||||
ModeLine "640x400@85" 31.5 640 672 736 832 400 401 404 445 -hsync +vsync
|
|
||||||
|
|
||||||
# 720x400 @ 85Hz (VESA) hsync: 37.9kHz
|
|
||||||
ModeLine "720x400@85" 35.5 720 756 828 936 400 401 404 446 -hsync +vsync
|
|
||||||
|
|
||||||
# 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz
|
|
||||||
ModeLine "640x480@60" 25.2 640 656 752 800 480 490 492 525 -hsync -vsync
|
|
||||||
|
|
||||||
# 640x480 @ 72Hz (VESA) hsync: 37.9kHz
|
|
||||||
ModeLine "640x480@72" 31.5 640 664 704 832 480 489 491 520 -hsync -vsync
|
|
||||||
|
|
||||||
# 640x480 @ 75Hz (VESA) hsync: 37.5kHz
|
|
||||||
ModeLine "640x480@75" 31.5 640 656 720 840 480 481 484 500 -hsync -vsync
|
|
||||||
|
|
||||||
# 640x480 @ 85Hz (VESA) hsync: 43.3kHz
|
|
||||||
ModeLine "640x480@85" 36.0 640 696 752 832 480 481 484 509 -hsync -vsync
|
|
||||||
|
|
||||||
# 800x600 @ 56Hz (VESA) hsync: 35.2kHz
|
|
||||||
ModeLine "800x600@56" 36.0 800 824 896 1024 600 601 603 625 +hsync +vsync
|
|
||||||
|
|
||||||
# 800x600 @ 60Hz (VESA) hsync: 37.9kHz
|
|
||||||
ModeLine "800x600@60" 40.0 800 840 968 1056 600 601 605 628 +hsync +vsync
|
|
||||||
|
|
||||||
# 800x600 @ 72Hz (VESA) hsync: 48.1kHz
|
|
||||||
ModeLine "800x600@72" 50.0 800 856 976 1040 600 637 643 666 +hsync +vsync
|
|
||||||
|
|
||||||
# 800x600 @ 75Hz (VESA) hsync: 46.9kHz
|
|
||||||
ModeLine "800x600@75" 49.5 800 816 896 1056 600 601 604 625 +hsync +vsync
|
|
||||||
|
|
||||||
# 800x600 @ 85Hz (VESA) hsync: 53.7kHz
|
|
||||||
ModeLine "800x600@85" 56.3 800 832 896 1048 600 601 604 631 +hsync +vsync
|
|
||||||
|
|
||||||
# 1024x768i @ 43Hz (industry standard) hsync: 35.5kHz
|
|
||||||
ModeLine "1024x768@43" 44.9 1024 1032 1208 1264 768 768 776 817 +hsync +vsync Interlace
|
|
||||||
|
|
||||||
# 1024x768 @ 60Hz (VESA) hsync: 48.4kHz
|
|
||||||
ModeLine "1024x768@60" 65.0 1024 1048 1184 1344 768 771 777 806 -hsync -vsync
|
|
||||||
|
|
||||||
# 1024x768 @ 70Hz (VESA) hsync: 56.5kHz
|
|
||||||
ModeLine "1024x768@70" 75.0 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
|
|
||||||
|
|
||||||
# 1024x768 @ 75Hz (VESA) hsync: 60.0kHz
|
|
||||||
ModeLine "1024x768@75" 78.8 1024 1040 1136 1312 768 769 772 800 +hsync +vsync
|
|
||||||
|
|
||||||
# 1024x768 @ 85Hz (VESA) hsync: 68.7kHz
|
|
||||||
ModeLine "1024x768@85" 94.5 1024 1072 1168 1376 768 769 772 808 +hsync +vsync
|
|
||||||
|
|
||||||
# 1152x864 @ 75Hz (VESA) hsync: 67.5kHz
|
|
||||||
ModeLine "1152x864@75" 108.0 1152 1216 1344 1600 864 865 868 900 +hsync +vsync
|
|
||||||
|
|
||||||
# 1280x960 @ 60Hz (VESA) hsync: 60.0kHz
|
|
||||||
ModeLine "1280x960@60" 108.0 1280 1376 1488 1800 960 961 964 1000 +hsync +vsync
|
|
||||||
|
|
||||||
# 1280x960 @ 85Hz (VESA) hsync: 85.9kHz
|
|
||||||
ModeLine "1280x960@85" 148.5 1280 1344 1504 1728 960 961 964 1011 +hsync +vsync
|
|
||||||
|
|
||||||
# 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz
|
|
||||||
ModeLine "1280x1024@60" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
|
|
||||||
|
|
||||||
# 1280x1024 @ 75Hz (VESA) hsync: 80.0kHz
|
|
||||||
ModeLine "1280x1024@75" 135.0 1280 1296 1440 1688 1024 1025 1028 1066 +hsync +vsync
|
|
||||||
|
|
||||||
# 1280x1024 @ 85Hz (VESA) hsync: 91.1kHz
|
|
||||||
ModeLine "1280x1024@85" 157.5 1280 1344 1504 1728 1024 1025 1028 1072 +hsync +vsync
|
|
||||||
|
|
||||||
# 1600x1200 @ 60Hz (VESA) hsync: 75.0kHz
|
|
||||||
ModeLine "1600x1200@60" 162.0 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
|
||||||
|
|
||||||
# 1600x1200 @ 65Hz (VESA) hsync: 81.3kHz
|
|
||||||
ModeLine "1600x1200@65" 175.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
|
||||||
|
|
||||||
# 1600x1200 @ 70Hz (VESA) hsync: 87.5kHz
|
|
||||||
ModeLine "1600x1200@70" 189.0 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
|
||||||
|
|
||||||
# 1600x1200 @ 75Hz (VESA) hsync: 93.8kHz
|
|
||||||
ModeLine "1600x1200@75" 202.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
|
||||||
|
|
||||||
# 1600x1200 @ 85Hz (VESA) hsync: 106.3kHz
|
|
||||||
ModeLine "1600x1200@85" 229.5 1600 1664 1856 2160 1200 1201 1204 1250 +hsync +vsync
|
|
||||||
|
|
||||||
# 1792x1344 @ 60Hz (VESA) hsync: 83.6kHz
|
|
||||||
ModeLine "1792x1344@60" 204.8 1792 1920 2120 2448 1344 1345 1348 1394 -hsync +vsync
|
|
||||||
|
|
||||||
# 1792x1344 @ 75Hz (VESA) hsync: 106.3kHz
|
|
||||||
ModeLine "1792x1344@75" 261.0 1792 1888 2104 2456 1344 1345 1348 1417 -hsync +vsync
|
|
||||||
|
|
||||||
# 1856x1392 @ 60Hz (VESA) hsync: 86.3kHz
|
|
||||||
ModeLine "1856x1392@60" 218.3 1856 1952 2176 2528 1392 1393 1396 1439 -hsync +vsync
|
|
||||||
|
|
||||||
# 1856x1392 @ 75Hz (VESA) hsync: 112.5kHz
|
|
||||||
ModeLine "1856x1392@75" 288.0 1856 1984 2208 2560 1392 1393 1396 1500 -hsync +vsync
|
|
||||||
|
|
||||||
# 1920x1440 @ 60Hz (VESA) hsync: 90.0kHz
|
|
||||||
ModeLine "1920x1440@60" 234.0 1920 2048 2256 2600 1440 1441 1444 1500 -hsync +vsync
|
|
||||||
|
|
||||||
# 1920x1440 @ 75Hz (VESA) hsync: 112.5kHz
|
|
||||||
ModeLine "1920x1440@75" 297.0 1920 2064 2288 2640 1440 1441 1444 1500 -hsync +vsync
|
|
Before Width: | Height: | Size: 2.0 KiB |
@ -1,66 +0,0 @@
|
|||||||
//
|
|
||||||
// Extra widescreen modes
|
|
||||||
//
|
|
||||||
|
|
||||||
# 1280x720 @ 50.00 Hz (GTF) hsync: 37.05 kHz; pclk: 60.47 MHz
|
|
||||||
Modeline "1280x720@50" 60.47 1280 1328 1456 1632 720 721 724 741 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1280x720 @ 60.00 Hz (GTF) hsync: 44.76 kHz; pclk: 74.48 MHz
|
|
||||||
Modeline "1280x720@60" 74.48 1280 1336 1472 1664 720 721 724 746 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1280x768 @ 60.00 Hz (GTF) hsync: 47.70 kHz; pclk: 80.14 MHz
|
|
||||||
Modeline "1280x768@60" 80.14 1280 1344 1480 1680 768 769 772 795 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1280x768 @ 75.00 Hz (GTF) hsync: 60.15 kHz; pclk: 102.98 MHz
|
|
||||||
Modeline "1280x768@75" 102.98 1280 1360 1496 1712 768 769 772 802 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1280x800 @ 60.00 Hz (GTF) hsync: 49.68 kHz; pclk: 83.46 MHz
|
|
||||||
Modeline "1280x800@60" 83.46 1280 1344 1480 1680 800 801 804 828 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1280x800 @ 75.00 Hz (GTF) hsync: 62.62 kHz; pclk: 107.21 MHz
|
|
||||||
Modeline "1280x800@75" 107.21 1280 1360 1496 1712 800 801 804 835 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1440x900 @ 60.00 Hz (GTF) hsync: 55.92 kHz; pclk: 106.47 MHz
|
|
||||||
Modeline "1440x900@60" 106.47 1440 1520 1672 1904 900 901 904 932 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1440x900 @ 75.00 Hz (GTF) hsync: 70.50 kHz; pclk: 136.49 MHz
|
|
||||||
Modeline "1440x900@75" 136.49 1440 1536 1688 1936 900 901 904 940 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1400x1050 @ 60.00 Hz (GTF) hsync: 65.22 kHz; pclk: 122.61 MHz
|
|
||||||
Modeline "1400x1050@60" 122.61 1400 1488 1640 1880 1050 1051 1054 1087 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1400x1050 @ 75.00 Hz (GTF) hsync: 82.20 kHz; pclk: 155.85 MHz
|
|
||||||
Modeline "1400x1050@75" 155.85 1400 1496 1648 1896 1050 1051 1054 1096 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1600x1024 @ 60.00 Hz (GTF) hsync: 63.60 kHz; pclk: 136.36 MHz
|
|
||||||
Modeline "1600x1024@60" 136.36 1600 1704 1872 2144 1024 1025 1028 1060 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1680x1050 @ 60.00 Hz (GTF) hsync: 65.22 kHz; pclk: 147.14 MHz
|
|
||||||
Modeline "1680x1050@60" 147.14 1680 1784 1968 2256 1050 1051 1054 1087 -HSync +Vsync
|
|
||||||
|
|
||||||
#Modeline "1680x1050@60" 154.20 1680 1712 2296 2328 1050 1071 1081 1103
|
|
||||||
|
|
||||||
# 1680x1050 @ 75.00 Hz (GTF) hsync: 82.20 kHz; pclk: 188.07 MHz
|
|
||||||
Modeline "1680x1050@75" 188.07 1680 1800 1984 2288 1050 1051 1054 1096 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1920x1200 @ 60.00 Hz (GTF) hsync: 74.52 kHz; pclk: 193.16 MHz
|
|
||||||
Modeline "1920x1200@60" 193.16 1920 2048 2256 2592 1200 1201 1204 1242 -HSync +Vsync
|
|
||||||
|
|
||||||
# 1920x1200 @ 75.00 Hz (GTF) hsync: 93.97 kHz; pclk: 246.59 MHz
|
|
||||||
Modeline "1920x1200@75" 246.59 1920 2064 2272 2624 1200 1201 1204 1253 -HSync +Vsync
|
|
||||||
|
|
||||||
# 2560x1600 @ 60.00 Hz (GTF) hsync: 99.36 kHz; pclk: 348.16 MHz
|
|
||||||
Modeline "2560x1600@60" 348.16 2560 2752 3032 3504 1600 1601 1604 1656 -HSync +Vsync
|
|
||||||
|
|
||||||
# 2560x1600 @ 75.00 Hz (GTF) hsync: 125.25 kHz; pclk: 442.88 MHz
|
|
||||||
Modeline "2560x1600@75" 442.88 2560 2768 3048 3536 1600 1601 1604 1670 -HSync +Vsync
|
|
||||||
|
|
||||||
|
|
||||||
# 3200x2048 @ 60.00 Hz (GTF) hsync: 127.14 kHz; pclk: 561.45 MHz
|
|
||||||
Modeline "3200x2048@60" 561.45 3200 3456 3808 4416 2048 2049 2052 2119 -HSync +Vsync
|
|
||||||
|
|
||||||
# 3200x2048 @ 75.00 Hz (GTF) hsync: 160.27 kHz; pclk: 712.90 MHz
|
|
||||||
Modeline "3200x2048@75" 712.90 3200 3472 3824 4448 2048 2049 2052 2137 -HSync +Vsync
|
|
||||||
|
|
||||||
# Powerbook G4 1280x854
|
|
||||||
Modeline "1280x854" 80 1280 1309 1460 1636 854 857 864 896 +HSync +VSync
|
|
@ -1,15 +0,0 @@
|
|||||||
import xorgconfig
|
|
||||||
|
|
||||||
xconfig = xorgconfig.readConfig("/etc/X11/xorg.conf")
|
|
||||||
|
|
||||||
for screensection in xconfig.getSections("screen"):
|
|
||||||
print screensection.identifier
|
|
||||||
print screensection.option
|
|
||||||
|
|
||||||
for screensection in xconfig.getSections("device"):
|
|
||||||
print screensection.option
|
|
||||||
print screensection.option[1]
|
|
||||||
print screensection.option[2]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,903 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
###########################################################################
|
|
||||||
# xorgconfig.py - description #
|
|
||||||
# ------------------------------ #
|
|
||||||
# begin : Wed Feb 9 2004 #
|
|
||||||
# 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. #
|
|
||||||
# #
|
|
||||||
###########################################################################
|
|
||||||
import csv
|
|
||||||
import codecs
|
|
||||||
import locale
|
|
||||||
"""
|
|
||||||
General usage:
|
|
||||||
|
|
||||||
import xorgconfig
|
|
||||||
config = readConfig("/etc/X11/xorg.conf")
|
|
||||||
|
|
||||||
input_devices = config.getSections("InputDevice")
|
|
||||||
print input_devices[0].driver
|
|
||||||
options = input_devices[0].options
|
|
||||||
for option in options:
|
|
||||||
# option is of type OptionLine.
|
|
||||||
print option._row[0],
|
|
||||||
if len(option._row)>=2:
|
|
||||||
print "=>",option._row[1]
|
|
||||||
|
|
||||||
# Add line: Option "XkbModel" "pc105"
|
|
||||||
options.append( options.makeLine("Comment text",["XkbModel" "pc105"]) )
|
|
||||||
|
|
||||||
|
|
||||||
Refactor plan
|
|
||||||
=============
|
|
||||||
New usage:
|
|
||||||
|
|
||||||
import xorgconfig
|
|
||||||
config = readConfig("/etc/X11/xorg.conf")
|
|
||||||
|
|
||||||
input_devices = config.section.InputDevice
|
|
||||||
print input_devices[0].driver
|
|
||||||
options = input_devices[0].options
|
|
||||||
for option in options:
|
|
||||||
# option is of type OptionLine.
|
|
||||||
print option[1],
|
|
||||||
if len(option)>=3:
|
|
||||||
print "=>",option[2]
|
|
||||||
|
|
||||||
module_section = config.section.module[0]
|
|
||||||
module_section.append(["load","i2c"])
|
|
||||||
assert module_section.existsLoad("i2c")
|
|
||||||
module_section.removeLoad("i2c")
|
|
||||||
|
|
||||||
device_section = config.section.device[0]
|
|
||||||
if device_section.busid is not None:
|
|
||||||
print "Found busid:",device_section.busid
|
|
||||||
|
|
||||||
* direct references to myline._row should be removed.
|
|
||||||
* A ConfigLine should be a subclass of List. With line[i] accessing the
|
|
||||||
parts of the line.
|
|
||||||
* the order of the makeLine() parameters should be reversed.
|
|
||||||
* it should be possible to directly append a list or tuple that represents
|
|
||||||
a line to a section.
|
|
||||||
"""
|
|
||||||
############################################################################
|
|
||||||
class ConfigLine(object):
|
|
||||||
"""Represents one line from the Xorg.conf file.
|
|
||||||
|
|
||||||
Each part of the line is printed without quotes.
|
|
||||||
"""
|
|
||||||
def __init__(self,comment,row):
|
|
||||||
self._row = [item for item in row if item!='']
|
|
||||||
self._comment = comment
|
|
||||||
|
|
||||||
def toString(self,depth=0):
|
|
||||||
caprow = self._row
|
|
||||||
if len(caprow) > 0:
|
|
||||||
caprow[0] = caprow[0].capitalize()
|
|
||||||
string = ('\t' * (depth/2)) + ' ' * (depth%1) + '\t'.join([unicode(item) for item in caprow])
|
|
||||||
if self._comment is not None:
|
|
||||||
string += '#' + self._comment
|
|
||||||
return string + '\n'
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ConfigLineQuote(ConfigLine):
|
|
||||||
"""Represents one line from the Xorg.conf file.
|
|
||||||
|
|
||||||
The first item in the line is not quoted, but the remaining items are.
|
|
||||||
"""
|
|
||||||
def toString(self,depth=0):
|
|
||||||
string = ('\t' * (depth/2) + ' ' * (depth%1))
|
|
||||||
if len(self._row)!=0:
|
|
||||||
string += self._row[0].capitalize()
|
|
||||||
if len(self._row)>1:
|
|
||||||
if len(self._row[0]) < 8:
|
|
||||||
string += '\t'
|
|
||||||
string += '\t"' + '"\t"'.join([unicode(item) for item in self._row[1:]]) + '"'
|
|
||||||
if self._comment is not None:
|
|
||||||
string += '#' + self._comment
|
|
||||||
return string + '\n'
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class OptionLine(ConfigLineQuote):
|
|
||||||
def __init__(self,comment,row):
|
|
||||||
arg = ['option']
|
|
||||||
arg.extend(row)
|
|
||||||
ConfigLineQuote.__init__(self,comment,arg)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ConfigList(list):
|
|
||||||
def toString(self,depth=0):
|
|
||||||
string = ""
|
|
||||||
for item in self:
|
|
||||||
string += item.toString(depth)
|
|
||||||
return string
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class OptionList(ConfigList):
|
|
||||||
name = "option"
|
|
||||||
def __setitem__(self,key,value):
|
|
||||||
list.__setitem__(self,key,value)
|
|
||||||
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
return OptionLine(comment,row)
|
|
||||||
|
|
||||||
def appendOptionRow(self,row):
|
|
||||||
self.append(self.makeLine(None,row))
|
|
||||||
|
|
||||||
def removeOptionByName(self,name):
|
|
||||||
name = name.lower()
|
|
||||||
i = 0
|
|
||||||
while i < len(self):
|
|
||||||
if self[i]._row[1].lower()==name:
|
|
||||||
del self[i]
|
|
||||||
else:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
def getOptionByName(self,name):
|
|
||||||
name = name.lower()
|
|
||||||
for item in self:
|
|
||||||
try:
|
|
||||||
if item._row[1].lower()==name:
|
|
||||||
return item
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ScreenConfigLine(ConfigLine):
|
|
||||||
def __init__(self,comment,row):
|
|
||||||
arg = ["screen"]
|
|
||||||
arg.extend(row)
|
|
||||||
ConfigLine.__init__(self,comment,arg)
|
|
||||||
|
|
||||||
def toString(self,depth=0):
|
|
||||||
string = (' ' * depth)
|
|
||||||
|
|
||||||
try: # Keep on building up the string until the IndexError is thrown.
|
|
||||||
string += self._row[0]
|
|
||||||
i = 1
|
|
||||||
if self._row[i].isdigit():
|
|
||||||
string += ' ' + self._row[i]
|
|
||||||
i += 1
|
|
||||||
string += ' "' + self._row[i] + '"'
|
|
||||||
i += 1
|
|
||||||
while True:
|
|
||||||
item = self._row[i].lower()
|
|
||||||
if item in ['rightof','leftof','above','below']:
|
|
||||||
string += ' %s "%s"' % (item, self._row[i+1])
|
|
||||||
i += 1
|
|
||||||
elif item=='absolute':
|
|
||||||
string += ' %s %d %d' % (item, self._row[i+1], self._row[i+2])
|
|
||||||
i += 2
|
|
||||||
elif item.isdigit():
|
|
||||||
i += 1
|
|
||||||
string += ' %s %s' % (item,self._row[i])
|
|
||||||
i += 1
|
|
||||||
except IndexError: pass
|
|
||||||
|
|
||||||
if self._comment is not None:
|
|
||||||
string += ' #' + self._comment
|
|
||||||
return string + '\n'
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ScreenConfigList(ConfigList):
|
|
||||||
name = "screen"
|
|
||||||
def __setitem__(self,key,value):
|
|
||||||
list.__setitem__(self,key,value)
|
|
||||||
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
return ScreenConfigLine(comment,row)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ConfigContainer(object):
|
|
||||||
"""Acts as a container for ConfigLines and other ConfigContainers.
|
|
||||||
Is used for representing things like the whole config file, sections
|
|
||||||
and subsections inside the file.
|
|
||||||
|
|
||||||
"""
|
|
||||||
def __init__(self):
|
|
||||||
self._contents = []
|
|
||||||
|
|
||||||
def append(self,item):
|
|
||||||
assert (item is not None)
|
|
||||||
self._contents.append(item)
|
|
||||||
|
|
||||||
def remove(self,item):
|
|
||||||
self._contents.remove(item)
|
|
||||||
|
|
||||||
def toString(self,depth=0):
|
|
||||||
string = ''
|
|
||||||
for item in self._contents:
|
|
||||||
string += item.toString(depth+1)
|
|
||||||
return string
|
|
||||||
|
|
||||||
def makeSection(self,comment,row):
|
|
||||||
return Section(comment,row)
|
|
||||||
|
|
||||||
def isSection(self,name):
|
|
||||||
lname = name.lower()
|
|
||||||
return lname=='section'
|
|
||||||
|
|
||||||
def isEndSection(self,name):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
return ConfigLine(comment,row)
|
|
||||||
|
|
||||||
def isListAttr(self,name):
|
|
||||||
lname = name.lower()
|
|
||||||
return lname in self._listattr
|
|
||||||
|
|
||||||
def makeListAttr(self,comment,row):
|
|
||||||
listobj = self.__getattr__(row[0].lower())
|
|
||||||
listobj.append( listobj.makeLine(comment,row[1:]) )
|
|
||||||
|
|
||||||
def getSections(self,name):
|
|
||||||
"""Get all sections having the given name.
|
|
||||||
|
|
||||||
Returns a list of ConfigContainer objects.
|
|
||||||
"""
|
|
||||||
name = name.lower()
|
|
||||||
sections = []
|
|
||||||
for item in self._contents:
|
|
||||||
try:
|
|
||||||
if isinstance(item,ConfigContainer) and item._name.lower()==name:
|
|
||||||
sections.append(item)
|
|
||||||
except IndexError: pass
|
|
||||||
return sections
|
|
||||||
|
|
||||||
def __getattr__(self,name):
|
|
||||||
if not name.startswith("_"):
|
|
||||||
lname = name.lower()
|
|
||||||
if lname in self._listattr:
|
|
||||||
# Lookup list attributes.
|
|
||||||
for item in self._contents:
|
|
||||||
if isinstance(item,ConfigList) and item.name==lname:
|
|
||||||
return item
|
|
||||||
else:
|
|
||||||
listitem = self._listattr[lname]()
|
|
||||||
self._contents.append(listitem)
|
|
||||||
return listitem
|
|
||||||
else:
|
|
||||||
for item in self._contents:
|
|
||||||
try:
|
|
||||||
if isinstance(item,ConfigLine) and item._row[0].lower()==lname:
|
|
||||||
return item._row[1]
|
|
||||||
except IndexError: pass
|
|
||||||
if lname in self._attr or lname in self._quoteattr:
|
|
||||||
return None
|
|
||||||
raise AttributeError, name
|
|
||||||
|
|
||||||
def __setattr__(self,name,value):
|
|
||||||
if name.startswith('_'):
|
|
||||||
return super(ConfigContainer,self).__setattr__(name,value)
|
|
||||||
|
|
||||||
lname = name.lower()
|
|
||||||
for item in self._contents:
|
|
||||||
try:
|
|
||||||
if isinstance(item,ConfigLine) and item._row[0].lower()==lname:
|
|
||||||
item._row[1] = value
|
|
||||||
break
|
|
||||||
except IndexError: pass
|
|
||||||
else:
|
|
||||||
if lname in self._attr or lname in self._quoteattr:
|
|
||||||
line = self.makeLine(None,[name,value])
|
|
||||||
self.append(line)
|
|
||||||
else:
|
|
||||||
raise AttributeError, name
|
|
||||||
|
|
||||||
def clear(self):
|
|
||||||
self._contents = []
|
|
||||||
|
|
||||||
def getRow(self,name):
|
|
||||||
if not name.startswith("_"):
|
|
||||||
lname = name.lower()
|
|
||||||
for item in self._contents:
|
|
||||||
try:
|
|
||||||
if isinstance(item,ConfigLine) and item._row[0].lower()==lname:
|
|
||||||
return item._row[1:]
|
|
||||||
except IndexError: pass
|
|
||||||
|
|
||||||
if name in self._attr or name in self._quoteattr:
|
|
||||||
# is a valid name, just has no real value right now.
|
|
||||||
return None
|
|
||||||
|
|
||||||
raise AttributeError, name
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class Section(ConfigContainer):
|
|
||||||
"""Represents a Section in the config file.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# List of config line types allowed inside this section.
|
|
||||||
# A list of strings naming lines that need to be stored in ConfigLine objects.
|
|
||||||
_attr = []
|
|
||||||
|
|
||||||
# A list of strings naming the lines that need to be stored in ConfigLineQuote objects.
|
|
||||||
# This is often overridden in subclasses.
|
|
||||||
_quoteattr = []
|
|
||||||
|
|
||||||
_listattr = {}
|
|
||||||
|
|
||||||
def __init__(self,comment,row):
|
|
||||||
ConfigContainer.__init__(self)
|
|
||||||
self._name = row[1]
|
|
||||||
self._comment = comment
|
|
||||||
|
|
||||||
def __show__(self):
|
|
||||||
""" For debugging """
|
|
||||||
for a in self._attr:
|
|
||||||
print self._name, "Attribute:", a
|
|
||||||
for a in self._quoteattr:
|
|
||||||
print self._name, "QuoteAttribute:", a
|
|
||||||
for a in self._listattr:
|
|
||||||
print self._name, "ListAttr:", a
|
|
||||||
|
|
||||||
def isSection(self,name):
|
|
||||||
return name.lower()=='subsection'
|
|
||||||
|
|
||||||
def isEndSection(self,name):
|
|
||||||
return name.lower()=='endsection'
|
|
||||||
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
try:
|
|
||||||
lname = row[0].lower()
|
|
||||||
if lname in self._quoteattr:
|
|
||||||
return ConfigLineQuote(comment,row)
|
|
||||||
if lname in self._attr:
|
|
||||||
return ConfigLine(comment,row)
|
|
||||||
return None
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
return ConfigContainer.makeLine(self,comment,row)
|
|
||||||
|
|
||||||
def toString(self,depth=0):
|
|
||||||
if self._comment is None:
|
|
||||||
return '%sSection "%s"\n%s%sEndSection\n' % \
|
|
||||||
(' ' * depth, self._name, ConfigContainer.toString(self,depth+1), ' ' * depth)
|
|
||||||
else:
|
|
||||||
return '%sSection "%s" # %s\n%s%sEndSection\n' % \
|
|
||||||
(' ' * depth, self._name, self._comment, ConfigContainer.toString(self,depth+1), ' ' * depth)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class SubSection(Section):
|
|
||||||
def isSection(self,name):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def isEndSection(self,name):
|
|
||||||
return name.lower()=='endsubsection'
|
|
||||||
|
|
||||||
def toString(self,depth=0):
|
|
||||||
return '%sSubSection "%s"\n%s%sEndSubSection\n' % \
|
|
||||||
('\t' * (depth/2) + ' ' * (depth%1), self._name, ConfigContainer.toString(self,depth+1), '\t' * (depth/2) + ' ' * (depth%1))
|
|
||||||
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class DeviceSection(Section):
|
|
||||||
_attr = ["endsection","dacspeed","clocks","videoram","biosbase","membase", \
|
|
||||||
"iobase","chipid","chiprev","textclockfreq","irq","screen"]
|
|
||||||
|
|
||||||
_quoteattr = ["identifier","vendorname","boardname","chipset","ramdac", \
|
|
||||||
"clockchip","card","driver","busid"]
|
|
||||||
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class DriSection(Section):
|
|
||||||
_attr = ["group","buffers","mode"]
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
try:
|
|
||||||
lname = row[0].lower()
|
|
||||||
if lname=="group" and not row[1].isdigit():
|
|
||||||
return ConfigLineQuote(comment,row)
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
return Section.makeLine(self,comment,row)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ExtensionsSection(Section):
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class FilesSection(Section):
|
|
||||||
_quoteattr = ["fontpath","rgbpath","modulepath","inputdevices","logfile"]
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
return ConfigLineQuote(comment,row)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ModuleSection(Section):
|
|
||||||
_quoteattr = ["load","loaddriver","disable"]
|
|
||||||
|
|
||||||
def makeSection(self,comment,row):
|
|
||||||
return ModuleSubSection(comment,row)
|
|
||||||
|
|
||||||
def allowModule(self,modname):
|
|
||||||
killlist = []
|
|
||||||
for item in self._contents:
|
|
||||||
try:
|
|
||||||
if isinstance(item,ConfigLineQuote) \
|
|
||||||
and item._row[0].lower()=='disable' \
|
|
||||||
and item._row[1]==modname:
|
|
||||||
killlist.append(item)
|
|
||||||
except IndexError: pass
|
|
||||||
|
|
||||||
for item in killlist:
|
|
||||||
self._contents.remove(item)
|
|
||||||
|
|
||||||
def removeModule(self,modname):
|
|
||||||
killlist = []
|
|
||||||
for item in self._contents:
|
|
||||||
try:
|
|
||||||
if isinstance(item,ConfigLineQuote) \
|
|
||||||
and item._row[0].lower()=='load' \
|
|
||||||
and item._row[1]==modname:
|
|
||||||
killlist.append(item)
|
|
||||||
except IndexError: pass
|
|
||||||
|
|
||||||
for item in killlist:
|
|
||||||
self._contents.remove(item)
|
|
||||||
|
|
||||||
def disableModule(self,modname):
|
|
||||||
self.removeModule(modname)
|
|
||||||
self._contents.append(ConfigLineQuote(None,['disable',modname]))
|
|
||||||
|
|
||||||
def addModule(self,modname):
|
|
||||||
self.removeModule(modname)
|
|
||||||
self._contents.append(ConfigLineQuote(None,['load',modname]))
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ModuleSubSection(SubSection):
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ModeSection(Section):
|
|
||||||
_attr = ["dotclock","htimings","vtimings","hskew","bcast","vscan"]
|
|
||||||
_quoteattr = ["flags"]
|
|
||||||
|
|
||||||
def __init__(self,comment,row):
|
|
||||||
Section.__init__(self,comment,row)
|
|
||||||
self._name = row[1]
|
|
||||||
|
|
||||||
def isEndSection(self,name):
|
|
||||||
return name.lower()=='endmode'
|
|
||||||
|
|
||||||
def toString(self,depth=0):
|
|
||||||
if self._comment is None:
|
|
||||||
return '%sMode "%s"\n%s%sEndMode\n' % \
|
|
||||||
(' ' * depth, self._name, ConfigContainer.toString(self,depth+1), ' ' * depth)
|
|
||||||
else:
|
|
||||||
return '%sMode "%s" # %s\n%s%sEndMode\n' % \
|
|
||||||
(' ' * depth, self._name, self._comment, ConfigContainer.toString(self,depth+1), ' ' * depth)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ModeList(ConfigList):
|
|
||||||
name = "mode"
|
|
||||||
def __setitem__(self,key,value):
|
|
||||||
list.__setitem__(self,key,value)
|
|
||||||
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
return ModeLine(comment,row)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ModeLineList(ConfigList):
|
|
||||||
name = "modeline"
|
|
||||||
def __setitem__(self,key,value):
|
|
||||||
list.__setitem__(self,key,value)
|
|
||||||
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
return ModeLineConfigLine(comment,row)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class MonitorSection(Section):
|
|
||||||
_attr = ["displaysize","horizsync","vertrefresh","gamma"]
|
|
||||||
_quoteattr = ["identifier","vendorname","modelname","usemodes"]
|
|
||||||
_listattr = {"option" : OptionList, "mode" : ModeList, "modeline" : ModeLineList}
|
|
||||||
|
|
||||||
def makeLine(self,comment,row):
|
|
||||||
return Section.makeLine(self,comment,row)
|
|
||||||
|
|
||||||
def isSection(self,name):
|
|
||||||
lname = name.lower()
|
|
||||||
return lname=='mode'
|
|
||||||
|
|
||||||
def isEndSection(self,name):
|
|
||||||
return name.lower()=='endsection'
|
|
||||||
|
|
||||||
def makeSection(self,comment,row):
|
|
||||||
if row[0].lower()=='mode':
|
|
||||||
return ModeSection(comment,row)
|
|
||||||
else:
|
|
||||||
return Section.makeSection(self,comment,row)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ModeLineConfigLine(ConfigLine):
|
|
||||||
def toString(self,depth=0):
|
|
||||||
string = (' ' * depth)+"modeline "
|
|
||||||
if len(self._row)>0:
|
|
||||||
string += ' "' + self._row[0] + '"'
|
|
||||||
if len(self._row)>1:
|
|
||||||
string += ' ' + ' '.join([unicode(item) for item in self._row[1:]])
|
|
||||||
if self._comment is not None:
|
|
||||||
string += '#' + self._comment
|
|
||||||
return string + '\n'
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ModesSection(MonitorSection):
|
|
||||||
# Like a MonitorSection, only smaller.
|
|
||||||
_attr = ["modeline"]
|
|
||||||
_quoteattr = ["identifier"]
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class PointerSection(Section):
|
|
||||||
_attr = ["emulate3timeout","baudrate","samplerate","resolution",\
|
|
||||||
"devicename","buttons"]
|
|
||||||
_quoteattr = ["protocol","device","port","emulate3buttons","chordmiddle",\
|
|
||||||
"cleardtr","clearrts","zaxismapping","alwayscore"]
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ScreenSection(Section):
|
|
||||||
_attr = ["screenno","defaultcolordepth","defaultdepth","defaultbpp","defaultfbbpp"]
|
|
||||||
_quoteattr = ["identifier","driver","device","monitor","videoadaptor","option"]
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
def makeSection(self,comment,row):
|
|
||||||
if row[1].lower()=='display':
|
|
||||||
return DisplaySubSection(comment,row)
|
|
||||||
return SubSection(comment,row)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class DisplaySubSection(SubSection):
|
|
||||||
_attr = ["viewport","virtual","black","white","depth","fbbpp","weight"]
|
|
||||||
_quoteattr = ["modes","visual","option"]
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
############################################################################
|
|
||||||
class ServerFlagsSection(Section):
|
|
||||||
_quoteattr = ["notrapsignals","dontzap","dontzoom","disablevidmodeextension",\
|
|
||||||
"allownonlocalxvidtune","disablemodindev","allownonlocalmodindev","allowmouseopenfail", \
|
|
||||||
"blanktime","standbytime","suspendtime","offtime","defaultserverlayout"]
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ServerLayoutSection(Section):
|
|
||||||
_attr = []
|
|
||||||
_quoteattr = ["identifier","inactive","inputdevice","option"]
|
|
||||||
_listattr = {"option" : OptionList, "screen" : ScreenConfigList}
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class InputDeviceSection(Section):
|
|
||||||
_quoteattr = ["identifier","driver"]
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
############################################################################
|
|
||||||
class KeyboardSection(Section):
|
|
||||||
_attr = ["autorepeat","xleds"]
|
|
||||||
_quoteattr = ["protocol","panix106","xkbkeymap","xkbcompat","xkbtypes",\
|
|
||||||
"xkbkeycodes","xkbgeometry","xkbsymbols","xkbdisable","xkbrules",\
|
|
||||||
"xkbmodel","xkblayout","xkbvariant","xkboptions","vtinit","vtsysreq",\
|
|
||||||
"servernumlock","leftalt","rightalt","altgr","scrolllock","rightctl"]
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class VendorSection(Section):
|
|
||||||
_attr = []
|
|
||||||
_quoteattr = ["identifier"]
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
def isSection(self,name): return False
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class VideoAdaptorSection(Section):
|
|
||||||
_attr = []
|
|
||||||
_quoteattr = ["identifier","vendorname","boardname","busid","driver"]
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
def makeSection(self,comment,row):
|
|
||||||
return VideoPortSection(comment,row)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class VideoPortSection(SubSection):
|
|
||||||
_attr = []
|
|
||||||
_quoteattr = ["identifier"]
|
|
||||||
_listattr = {"option" : OptionList}
|
|
||||||
############################################################################
|
|
||||||
class XorgConfig(ConfigContainer):
|
|
||||||
_sectiontypes = { \
|
|
||||||
'device': DeviceSection,
|
|
||||||
'dri': DriSection,
|
|
||||||
'extensions': ExtensionsSection,
|
|
||||||
'files': FilesSection,
|
|
||||||
'inputdevice': InputDeviceSection,
|
|
||||||
'keyboard': KeyboardSection,
|
|
||||||
'modes': ModesSection,
|
|
||||||
'monitor': MonitorSection,
|
|
||||||
'module': ModuleSection,
|
|
||||||
'pointer': PointerSection,
|
|
||||||
'serverflags': ServerFlagsSection,
|
|
||||||
'serverlayout': ServerLayoutSection,
|
|
||||||
'screen': ScreenSection,
|
|
||||||
'videoadaptor': VideoAdaptorSection}
|
|
||||||
|
|
||||||
def makeSection(self,comment,row):
|
|
||||||
lname = row[1].lower()
|
|
||||||
try:
|
|
||||||
return self._sectiontypes[lname](comment,row)
|
|
||||||
except KeyError:
|
|
||||||
return ConfigContainer.makeSection(self,comment,row)
|
|
||||||
|
|
||||||
def toString(self,depth=-1):
|
|
||||||
return ConfigContainer.toString(self,depth)
|
|
||||||
|
|
||||||
def writeConfig(self,filename):
|
|
||||||
try:
|
|
||||||
encoding = locale.getpreferredencoding()
|
|
||||||
except locale.Error:
|
|
||||||
encoding = 'ANSI_X3.4-1968'
|
|
||||||
fhandle = codecs.open(filename,'w',locale.getpreferredencoding())
|
|
||||||
fhandle.write(self.toString())
|
|
||||||
fhandle.close()
|
|
||||||
|
|
||||||
def createUniqueIdentifier(self,stem="id"):
|
|
||||||
"""Create a unique identifier for a section
|
|
||||||
|
|
||||||
"""
|
|
||||||
# Build a list of used identifiers
|
|
||||||
used_identifiers = []
|
|
||||||
for name in ['monitor','videoadaptor','inputdevice','serverlayout','device','screen']:
|
|
||||||
for section in self.getSections(name):
|
|
||||||
if section.identifier is not None:
|
|
||||||
used_identifiers.append(section.identifier)
|
|
||||||
|
|
||||||
# Generate a identifier that is not in use.
|
|
||||||
i = 1
|
|
||||||
while (stem+str(i)) in used_identifiers:
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
return stem+str(i)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
def addxorg(context, stack):
|
|
||||||
# Add minimal xorg.conf if it's missing
|
|
||||||
rows = [[None, [u'Section', u'Device']], [None, [u'Identifier', u'Configured Video Device']], \
|
|
||||||
[None, [u'EndSection']], [None, [u'Section', u'Monitor']], \
|
|
||||||
[None, [u'Identifier', u'Configured Monitor']], \
|
|
||||||
[None, [u'EndSection']], [None, [u'Section', u'Screen']], \
|
|
||||||
[None, [u'Identifier', u'Default Screen']], \
|
|
||||||
[None, [u'Monitor', u'Configured Monitor']], [None, [u'EndSection']], \
|
|
||||||
[None, [u'Section', u'ServerLayout']], \
|
|
||||||
[None, [u'Identifier', u'Default Layout']], \
|
|
||||||
[None, [u'screen', u'Default Screen']], \
|
|
||||||
[None, [u'EndSection']]]
|
|
||||||
|
|
||||||
for data in rows:
|
|
||||||
rowcomment = data[0]
|
|
||||||
row = data[1]
|
|
||||||
try:
|
|
||||||
first = row[0].lower()
|
|
||||||
if context.isSection(first):
|
|
||||||
section = context.makeSection(rowcomment,row)
|
|
||||||
context.append(section)
|
|
||||||
stack.append(context)
|
|
||||||
context = section
|
|
||||||
context_class = context.__class__
|
|
||||||
elif context.isEndSection(first):
|
|
||||||
context = stack.pop()
|
|
||||||
elif context.isListAttr(first):
|
|
||||||
context.makeListAttr(rowcomment,row)
|
|
||||||
else:
|
|
||||||
newline = context.makeLine(rowcomment,row)
|
|
||||||
if newline is None:
|
|
||||||
raise ParseException,"Unknown line type '%s' on line %i" % (first,line)
|
|
||||||
context.append(newline)
|
|
||||||
except IndexError:
|
|
||||||
context.append(ConfigLine(rowcomment,row))
|
|
||||||
|
|
||||||
return context, section, stack, first
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
def addServerLayout(context, section, stack, first):
|
|
||||||
# Add empty server layout section to xorg.conf if it's missing
|
|
||||||
rows = [[None, [u'Section', u'ServerLayout']], \
|
|
||||||
[None, [u'Identifier', u'Default Layout']], \
|
|
||||||
[None, [u'screen', u'0', u'Default Screen', u'0', u'0']], \
|
|
||||||
[None, [u'Inputdevice', u'Generic Keyboard']], \
|
|
||||||
[None, [u'Inputdevice', u'Configured Mouse']], \
|
|
||||||
[None, []], ["Uncomment if you have a wacom tablet", []], \
|
|
||||||
["InputDevice \"stylus\" \"SendCoreEvents\"", []], \
|
|
||||||
[" InputDevice \"cursor\" \"SendCoreEvents\"", []], \
|
|
||||||
[" InputDevice \"eraser\" \"SendCoreEvents\"", []], \
|
|
||||||
[None, [u'Inputdevice', u'Synaptics Touchpad']], [None, [u'EndSection']]]
|
|
||||||
for data in rows:
|
|
||||||
rowcomment = data[0]
|
|
||||||
row = data[1]
|
|
||||||
try:
|
|
||||||
first = row[0].lower()
|
|
||||||
if context.isSection(first):
|
|
||||||
section = context.makeSection(rowcomment,row)
|
|
||||||
context.append(section)
|
|
||||||
stack.append(context)
|
|
||||||
context = section
|
|
||||||
context_class = context.__class__
|
|
||||||
elif context.isEndSection(first):
|
|
||||||
context = stack.pop()
|
|
||||||
elif context.isListAttr(first):
|
|
||||||
context.makeListAttr(rowcomment,row)
|
|
||||||
else:
|
|
||||||
newline = context.makeLine(rowcomment,row)
|
|
||||||
if newline is None:
|
|
||||||
raise ParseException,"Unknown line type '%s' on line %i" % (first,line)
|
|
||||||
context.append(newline)
|
|
||||||
except IndexError:
|
|
||||||
context.append(ConfigLine(rowcomment,row))
|
|
||||||
|
|
||||||
return context, section, stack, first
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
def readConfig(filename, check_exists=False):
|
|
||||||
|
|
||||||
context = XorgConfig()
|
|
||||||
stack = []
|
|
||||||
line = 1
|
|
||||||
hasserverlayout = False
|
|
||||||
hasxorg = True
|
|
||||||
try:
|
|
||||||
import os
|
|
||||||
try:
|
|
||||||
if os.path.isfile('/etc/X11/xorg.conf'):
|
|
||||||
if os.path.getsize(filename) == 0:
|
|
||||||
raise IOError, "xorg.conf is empty - making up config"
|
|
||||||
else:
|
|
||||||
raise IOError, "xorg.conf is empty - making up config"
|
|
||||||
except OSError, errmsg:
|
|
||||||
raise IOError, errmsg
|
|
||||||
for row in XorgconfCVSReader(filename=filename).readlines():
|
|
||||||
try:
|
|
||||||
first = row[0].lower()
|
|
||||||
if context.isSection(first):
|
|
||||||
section = context.makeSection(row.comment,row)
|
|
||||||
if section._name == 'ServerLayout':
|
|
||||||
hasserverlayout = True
|
|
||||||
context.append(section)
|
|
||||||
stack.append(context)
|
|
||||||
context = section
|
|
||||||
context_class = context.__class__
|
|
||||||
elif context.isEndSection(first):
|
|
||||||
context = stack.pop()
|
|
||||||
elif context.isListAttr(first):
|
|
||||||
context.makeListAttr(row.comment,row)
|
|
||||||
else:
|
|
||||||
newline = context.makeLine(row.comment,row)
|
|
||||||
if newline is None:
|
|
||||||
raise ParseException,"Unknown line type '%s' on line %i" % (first,line)
|
|
||||||
context.append(newline)
|
|
||||||
except IndexError:
|
|
||||||
context.append(ConfigLine(row.comment,row))
|
|
||||||
line += 1
|
|
||||||
except IOError, errmsg:
|
|
||||||
ermsg = str(errmsg)
|
|
||||||
print "IOError", ermsg, " - will create xorg.conf if possible."
|
|
||||||
if ermsg[:9] == "[Errno 2]": # No such file or directory:
|
|
||||||
hasxorg = False
|
|
||||||
addxorg(context, stack)
|
|
||||||
try:
|
|
||||||
xorgfile = open(filename, 'a')
|
|
||||||
xorgfile.close()
|
|
||||||
except IOError, errmsg:
|
|
||||||
ermsg = str(errmsg)
|
|
||||||
if ermsg[:9] == "[Errno 13]": #Permission denied:
|
|
||||||
pass
|
|
||||||
# Since we aren't root, changes can't be made anyway.
|
|
||||||
elif ermsg[:9] == "xorg.conf": # xorg.conf exists, but is empty
|
|
||||||
hasxorg = False
|
|
||||||
addxorg(context, stack)
|
|
||||||
|
|
||||||
if len(stack)!=0:
|
|
||||||
raise ParseException,"Unexpected end of file on line %i" % line
|
|
||||||
if not hasserverlayout and hasxorg:
|
|
||||||
addServerLayout(context, section, stack, first)
|
|
||||||
if check_exists:
|
|
||||||
return context, hasxorg
|
|
||||||
else:
|
|
||||||
return context
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
class ParseException(Exception):
|
|
||||||
def __init__(self,*args):
|
|
||||||
Exception.__init__(self,*args)
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
def toBoolean(value):
|
|
||||||
return unicode(value).lower() in ['on','true','1','yes']
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
# Our own class for reading CSV file. This version supports unicode while
|
|
||||||
# standard Python (2.4) version doesn't. Hence the need for this class.
|
|
||||||
#
|
|
||||||
class XorgconfCVSReader(object):
|
|
||||||
def __init__(self,filename=None, text=None):
|
|
||||||
assert filename is not None or text is not None
|
|
||||||
|
|
||||||
STATE_DELIMITER = 0
|
|
||||||
STATE_ITEM = 1
|
|
||||||
STATE_QUOTE = 2
|
|
||||||
QUOTE = '"'
|
|
||||||
LINE_COMMENT = '#'
|
|
||||||
|
|
||||||
class CommentList(list):
|
|
||||||
def __init__(self):
|
|
||||||
list.__init__(self)
|
|
||||||
self.comment = None
|
|
||||||
|
|
||||||
if filename is not None:
|
|
||||||
try:
|
|
||||||
loc = locale.getpreferredencoding()
|
|
||||||
except locale.Error:
|
|
||||||
loc = 'ANSI_X3.4-1968'
|
|
||||||
fhandle = codecs.open(filename,'r',loc,'replace')
|
|
||||||
source_lines = fhandle.readlines()
|
|
||||||
fhandle.close()
|
|
||||||
else:
|
|
||||||
source_lines = text.split('\n')
|
|
||||||
|
|
||||||
self.lines = []
|
|
||||||
for line in source_lines:
|
|
||||||
if len(line)!=0 and line[-1]=='\n':
|
|
||||||
line = line[:-1]
|
|
||||||
|
|
||||||
state = STATE_DELIMITER
|
|
||||||
row = CommentList()
|
|
||||||
item = None
|
|
||||||
for i in range(len(line)):
|
|
||||||
c = line[i]
|
|
||||||
|
|
||||||
if state==STATE_DELIMITER:
|
|
||||||
if not c.isspace():
|
|
||||||
if c==QUOTE:
|
|
||||||
item = []
|
|
||||||
state = STATE_QUOTE
|
|
||||||
elif c==LINE_COMMENT:
|
|
||||||
row.comment = line[i+1:]
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
item = []
|
|
||||||
item.append(c)
|
|
||||||
state = STATE_ITEM
|
|
||||||
|
|
||||||
elif state==STATE_ITEM:
|
|
||||||
if c.isspace():
|
|
||||||
row.append(u''.join(item))
|
|
||||||
state = STATE_DELIMITER
|
|
||||||
item = None
|
|
||||||
else:
|
|
||||||
item.append(c)
|
|
||||||
|
|
||||||
elif state==STATE_QUOTE:
|
|
||||||
if c==QUOTE:
|
|
||||||
row.append(u''.join(item))
|
|
||||||
state = STATE_DELIMITER
|
|
||||||
item = None
|
|
||||||
else:
|
|
||||||
item.append(c)
|
|
||||||
|
|
||||||
if item is not None:
|
|
||||||
row.append(u''.join(item))
|
|
||||||
|
|
||||||
self.lines.append(row)
|
|
||||||
|
|
||||||
def readlines(self):
|
|
||||||
return self.lines
|
|
||||||
|
|
||||||
############################################################################
|
|
||||||
if __name__=='__main__':
|
|
||||||
import sys
|
|
||||||
if len(sys.argv)==2:
|
|
||||||
filename = sys.argv[1]
|
|
||||||
else:
|
|
||||||
filename = "/etc/X11/xorg.conf"
|
|
||||||
print "Reading",filename
|
|
||||||
c = readConfig(filename)
|
|
||||||
print c.toString()
|
|
||||||
|
|
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 275 B |
Before Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 490 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 486 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 481 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 488 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 493 B |
Before Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 489 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.5 KiB |
@ -1 +0,0 @@
|
|||||||
?package(guidance): needs="kde" kde_filename="displayconfig" section="System/Configuration/KDE/Peripherals" title="Display & Monitor" icon="displayconfig.png" command="/usr/bin/displayconfig" kde_command="tdecmshell displayconfig" longtitle="Display and monitor settings" kde_opt="\\nEncoding=UTF-8\\nX-TDE-ModuleType=Library\\nX-TDE-Library=displayconfig\\nX-TDE-FactoryName=displayconfig\\nX-TDE-ParentApp=kcontrol\\nX-TDE-RootOnly=true\\nX-TDE-SubstituteUID=true\\nKeywords=resolution;display;monitor;video;X11;xorg;gfx\\n"
|
|