Logo Search packages:      
Sourcecode: xdiagnose version File versions  Download package

XDiagnoseApplet.py

import os
import sys
import subprocess
import shutil
import gtk
import re
from string import split

from xdiagnose.config_update import (
    config_update,
    config_dict,
    safe_backup,
    )

00015 class XDiagnoseApplet:
    def __init__(self):
        self.__enable_debugging = None
        self.__disable_splash = None
        self.__disable_vesafb = None
        self.__disable_pat = None
        self.__disable_grub_graphics = None
        self.is_running = True
        self.dialog = gtk.Dialog("X Diagnostics Settings", None, 0, (
            gtk.STOCK_APPLY, gtk.RESPONSE_APPLY,
            gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
        self.dialog.set_default_size(300, 200)
        self.dialog.connect("delete_event", self.destroy)
   
        self.dialog.vbox.add(self.build_settings_list(
            title="Debug", settings=[
                {'text':'Extra graphics _debug messages',
                 'tip':'Makes dmesg logs more verbose with 3D-related details',
                 'active':self.has_enable_debugging(),
                 'handler':self.handle_enable_debugging},
                {'text':'Display boot messages',
                 'tip':'Removes splash and quiet from kernel options so you can see kernel details during boot',
                 'active':self.has_disable_splash(),
                 'handler':self.handle_disable_splash},
                ]))
        self.dialog.vbox.add(self.build_settings_list(
            title="Workarounds", settings=[
                {'text':'Disable bootloader _graphics',
                 'tip':'The grub bootloader has a graphics mode using the VESA framebuffer driver which can sometimes interfere with later loading of the proper video driver.  Checking this forces grub to use text mode only.',
                 'active':self.has_disable_grub_graphics(),
                 'handler':self.handle_disable_grub_graphics},
                {'text':'Disable _VESA framebuffer driver',
                 'tip':'vesafb is loaded early during boot so the boot logo can display, but can cause issues when switching to a real graphics driver.  Checking this prevents vesafb from loading so these issues do not occur.',
                 'active':self.has_disable_vesafb(),
                 'handler':self.handle_disable_vesafb},
                {'text':'Disable _PAT memory',
                 'tip':"This pagetable extension can interfere with the memory management of proprietary drivers under certain situations and cause lagging or failures to allocate video memory, so turning it off can prevent those problems.",
                 'active':self.has_disable_pat(),
                 'handler':self.handle_disable_pat},
                ]))
        self.dialog.show_all()

    def destroy(self, widget=None, param=None):
        self.is_running = False
        self.dialog.destroy()

    def build_settings_list(self, title, settings=None):
        frame = gtk.Frame()
        frame.set_shadow_type(gtk.SHADOW_NONE)

        label = gtk.Label("<b>%s</b>" %(title))
        label.set_use_markup(True)
        frame.set_label_widget(label)

        alignment = gtk.Alignment()
        alignment.set_padding(5, 0, 12, 0)
        alignment.set(0.5, 0.5, 1.0, 1.0)

        vbox = gtk.VBox()
        for s in settings:
            checkbutton = gtk.CheckButton(s['text'], use_underline=True)
            checkbutton.connect("toggled", s['handler'])
            if 'tip' in s and s['tip']:
                checkbutton.set_tooltip_text(s['tip'])
            if 'active' in s:
                if s['active']:
                    checkbutton.set_active(1)
                else:
                    checkbutton.set_active(0)
            if 'inconsistent' in s and s['inconsistent']:
                checkbutton.set_inconsistent(s['inconsistent'])
            vbox.pack_start(checkbutton, False, False, 0)

        alignment.add(vbox)
        frame.add(alignment)
        return frame

    def load_config(self):
        d = config_dict('/etc/default/grub')
        kparams = {}
        if 'GRUB_CMDLINE_LINUX_DEFAULT' in d:
            re_kparam = re.compile("^([\w\.]+)=(.*)")
            kparam_str = d['GRUB_CMDLINE_LINUX_DEFAULT'].replace('"', '')
            for param in kparam_str.split(' '):
                value = 1
                m = re_kparam.match(param)
                if m:
                    param = m.group(1)
                    value = m.group(2)
                kparams[param] = value
        if 'GRUB_GFXPAYLOAD_LINUX' in d:
            re_kparam = re.compile("^([\w\.]+)=(.*)")
            value = d['GRUB_GFXPAYLOAD_LINUX'].replace('"', '')
            self.__grub_gfxpayload_linux = value
            if value == 'text':
                self.has_disable_grub_graphics(True)
            else:
                self.has_disable_grub_graphics(False)
        else:
            self.has_disable_grub_graphics(False)

        if 'drm.debug' in kparams:
            self.has_enable_debugging(True)
        else:
            self.has_enable_debugging(False)

        if 'splash' not in kparams:
            self.has_disable_splash(True)
        else:
            self.has_disable_splash(False)

        if 'vesafb.invalid' in kparams:
            self.has_disable_vesafb(True)
        else:
            self.has_disable_vesafb(False)

        if 'nopat' in kparams:
            self.has_disable_pat(True)
        else:
            self.has_disable_pat(False)

    def has_enable_debugging(self, value=None):
        if value is not None:
            self.__enable_debugging = value
        elif self.__enable_debugging is None:
            self.load_config()
        return self.__enable_debugging
    def handle_enable_debugging(self, widget):
        self.has_enable_debugging(widget.get_active())

    def has_disable_splash(self, value=None):
        if value is not None:
            self.__disable_splash = value
        elif self.__disable_splash is None:
            self.load_config()
        return self.__disable_splash
    def handle_disable_splash(self, widget):
        self.has_disable_splash(widget.get_active())

    def has_disable_vesafb(self, value=None):
        if value is not None:
            self.__disable_vesafb = value
        elif self.__disable_vesafb is None:
            self.load_config()
        return self.__disable_vesafb
    def handle_disable_vesafb(self, widget):
        self.has_disable_vesafb(widget.get_active())

    def has_disable_pat(self, value=None):
        if value is not None:
            self.__disable_pat = value
        elif self.__disable_pat is None:
            self.load_config()
        return self.__disable_pat
    def handle_disable_pat(self, widget):
        self.has_disable_pat(widget.get_active())

    def has_disable_grub_graphics(self, value=None):
        if value is not None:
            self.__disable_grub_graphics = value
        elif self.__disable_grub_graphics is None:
            self.load_config()
        return self.__disable_grub_graphics
    def handle_disable_grub_graphics(self, widget):
        self.has_disable_grub_graphics(widget.get_active())

    def update_grub(self):
        try:
            subprocess.call(['/usr/sbin/update-grub'])
            return True
        except:
            # TODO: Indicate error occurred
            return False
        
    def run(self):
        response = self.dialog.run()
        if response == gtk.RESPONSE_APPLY:
            grub = {}
            params = []
            grub_path = "/etc/default/grub"
            # TODO: Write to a temp file ala mktemp
            temp_grub_path = "/tmp/foo.txt"

            fd = os.open(temp_grub_path, os.O_RDWR|os.O_CREAT)
            fo = os.fdopen(fd, "w+")
            if self.__disable_pat:
                params.append('nopat')
            if self.__disable_vesafb:
                params.append('vesafb.invalid=1')
            if self.__enable_debugging:
                # TODO: Enable debug for Xorg.0.log
                params.append('drm.debug=0xe')
            if self.__disable_grub_graphics is not None:
                if self.__disable_grub_graphics:
                    grub['GRUB_GFXPAYLOAD_LINUX'] = 'text'
                elif self.__grub_gfxpayload_linux != 'text':
                    grub['GRUB_GFXPAYLOAD_LINUX'] = self.__grub_gfxpayload_linux
                else:
                    grub['GRUB_GFXPAYLOAD_LINUX'] = 'keep'

            grub['GRUB_CMDLINE_LINUX_DEFAULT'] = '"%s"' %(' '.join(params))

            if self.__disable_splash:
                config_update(grub_path, override_params=grub, merge_params=None, fileio=fo)
            else:
                config_update(grub_path, override_params=None, merge_params=grub, fileio=fo)

            fo.close()

            # Backup the old file
            try:
                bak_path = safe_backup(grub_path)
                if not bak_path:
                    # TODO: Display error message dialog
                    print "Error:  Could not backup file %s.  Changes not applied." %(grub_path)
                    return
            except IOError, err:
                # TODO: Display error message dialog
                print "Error:  Failure creating backup file for %s.  Changes not applied." %(grub_path)
                print err
                return

            # Move new file into place
            shutil.move(temp_grub_path, grub_path)

            # Finally, update grub
            self.update_grub()

            # TODO: Mark Apply button insensitive
             
        elif response == gtk.RESPONSE_CLOSE:
            self.destroy()

# TODO: cmdline option to display grub file contents (--dryrun?)

Generated by  Doxygen 1.6.0   Back to index