2 # -*- coding: utf-8 -*-
6 # Purpose: wrapper for startx on grml [providing new xconfiguration tool]
7 # Authors: grml-team (grml.org), (c) Christian Hofstaedtler <ch@grml.org>
8 # Bug-Reports: see http://grml.org/bugs/
9 # License: This file is licensed under the GPL v2.
10 ###############################################################################
19 from optparse import OptionParser
22 class Section(object):
23 def __init__(self, name, identifier, data):
25 self.identifer = identifier
30 s = 'Section "%s"\n\tIdentifier "%s"\n' % (self.name, self.identifer)
33 if isinstance(v, list):
35 elif not isinstance(v, str): # int, others
37 elif "-" in v: # sync range
41 s += "\t%s %s\n" % (k, v)
47 def get_monitor_section(options, force):
48 if not options.hsync and not options.vsync and not force:
51 d["HorizSync"] = options.hsync or "28.0 - 96.0"
52 d["VertRefresh"] = options.vsync or "50.0 - 60.0"
53 return Section("Monitor", "Monitor0", d)
56 def get_device_section(options):
57 if not options.module:
60 d["Driver"] = options.module
61 d["VendorName"] = "All"
62 d["BoardName"] = "All"
63 return Section("Device", "Card0", d)
66 def build_bootparams():
69 def walk_bootparams_path(p):
71 if not os.path.exists(p):
73 for root, dirs, files in os.walk(p):
75 f = open(os.path.join(root, name))
76 lines.extend(f.readlines())
79 print("W: Error while getting bootparams from %s" % p)
81 f = open("/proc/cmdline")
82 lines.append(f.readline())
84 walk_bootparams_path("/lib/live/mount/medium/bootparams")
85 walk_bootparams_path("/run/live/medium/bootparams")
87 for p in " ".join(lines).split(" "):
89 (k, v) = p.split("=", 1)
97 f = open("/proc/cpuinfo")
98 x = "".join(f.readlines())
105 def get_program_output(args):
106 p = subprocess.Popen(
107 args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True
109 return p.communicate()[0]
112 def run_program(args):
113 subprocess.Popen(args, close_fds=True).wait()
118 return os.path.exists(fpath) and os.access(fpath, os.X_OK)
120 fpath, fname = os.path.split(program)
125 for path in os.environ["PATH"].split(os.pathsep):
126 exe_file = os.path.join(path, program)
133 XORG_CONF_HEADER = "# Automatically generated by grml-x.\n"
136 def check_old_xorg_conf(filename, overwrite):
137 # True: no problem, we can create/overwrite the config file
138 # False: pre-existing config file, and we are not to overwrite it
141 if not os.path.exists(filename):
144 f = open(filename, "r")
145 lines = f.readlines()
147 return not XORG_CONF_HEADER in lines
152 parser = OptionParser(usage="usage: %prog [options] [window-manager]")
155 action="store_false",
158 help="Don't start X server",
165 help="Start X server on display DISPLAY",
172 help="Force writing a HorizSync range",
179 help="Force writing a VertRefresh range",
186 help="Force a specific resolution",
193 help="Force driver MODULE instead of Xorg autodetection",
200 default="/etc/X11/xorg.conf",
201 help="Specify alternate xorg.conf file [default: %default]",
209 help="Overwrite xorg.conf if it exists [default: %default]",
214 (options, args) = parser.parse_args()
215 bootparams = build_bootparams()
217 if os.getuid() == 0 and options.start_server:
218 print("W: running as root is unsupported and may not work.")
221 if not check_old_xorg_conf(options.xorg_conf, options.overwrite):
222 print("E: Not overwriting existing %r without --force." % options.xorg_conf)
223 print("I: If you previously ran grml-x, use startx /usr/bin/x-window-manager")
226 if "xmode" in bootparams and not options.mode:
227 options.mode = bootparams["xmode"]
228 if "xmodule" in bootparams and not options.module:
229 options.module = bootparams["xmodule"]
231 force_monitor = False
232 # cirrus driver for QEMU doesn't do 1024x768 without HorizSync set
236 monitor = get_monitor_section(options, force_monitor)
237 device = get_device_section(options)
239 # build Screen section ourselves
242 d["Monitor"] = monitor.identifer
244 d["Device"] = device.identifer
245 screen = Section("Screen", "Screen0", d)
247 d["DefaultColorDepth"] = 16
248 for depth in [8, 15, 16, 24, 32]:
250 'SubSection "Display"\n\tDepth %d\n\tModes "%s"\t\nEndSubSection\n'
251 % (depth, options.mode)
254 xinitrc = "~/.xinitrc"
255 if "XINITRC" in os.environ:
256 xinitrc = os.environ["XINITRC"]
257 xinitrc = os.path.expanduser(xinitrc)
259 window_manager = "x-window-manager"
261 window_manager = args[0]
262 window_manager_path = which(window_manager)
263 if not window_manager_path:
264 print("E: Cannot find window manager %r, aborting." % window_manager)
267 wm_exec = "exec %s\n" % window_manager_path
268 if not os.path.exists(xinitrc):
269 f = open(xinitrc, "w")
270 f.write("#!/bin/sh\n")
274 f = open(xinitrc, "r")
275 lines = f.readlines()
277 f = open(xinitrc, "w")
279 if line.strip().startswith("exec "):
282 os.fchmod(f.fileno(), 0o750)
286 if monitor or device or len(screen.data) > 0 or screen.subsect != "":
288 f = tempfile.NamedTemporaryFile(mode="w+", delete=False)
289 f.write(XORG_CONF_HEADER)
291 "# DO NOT MODIFY, YOUR CHANGES WILL BE LOST - OR REMOVE ALL HEADER LINES\n"
293 f.write("# See man xorg.conf or /etc/X11/xorg.conf.example for more\n")
295 f.write(str(monitor))
300 os.fchmod(f.fileno(), 0o644)
301 run_program(["sudo", "mv", "-f", f.name, options.xorg_conf])
305 if options.start_server:
306 startx = ["startx", xinitrc, "--"]
308 startx.append(":" + options.display)
309 print("Starting X: %r" % startx)
315 if __name__ == "__main__":
320 print("E: Exception: ", end=" ")
321 traceback.print_exc()