@ -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"
|