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

xorg_driver.py

# (c) 2007 Canonical Ltd.
#
# 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 is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

'''Abstract handler for a restricted X.org graphics driver.'''

import os.path, logging

import xorgconfig # from kde-guidance

from handlers import ModulePackageHandler
from oslib import OSLib

#--------------------------------------------------------------------#

00028 class XorgDriverHandler(ModulePackageHandler):
    '''Abstract class for a restricted X.org graphics driver.'''

00031     def __init__(self, ui, module, driver_package, xorg_driver,
        alt_free_driver, extra_conf_options={}, add_modules=[],
            remove_modules=[], name=None, description=None, rationale=None):
        '''Create handler for a particular X.org graphics driver.
        
        This usually consists of a kernel module and a driver package, plus
        some xorg.conf configuration.

        - ui, module, driver_package, name, description, rationale: as in
          ModulePackageHandler
        - xorg_driver: name of the X.org driver as it appears in xorg.conf
        - alt_free_driver: free fallback driver if this one gets disabled
        - extra_conf_options: dictionary of extra "Option"s that go into the
          Device section of xorg.conf
        - add_modules: list of modules that get added to the "Module" section
          of xorg.conf when enabling this driver (and removed when disabling)
        - remove_modules: list of modules that get removed from the "Module"
          section of xorg.conf when enabling this driver (and added when disabling)
        '''
        ModulePackageHandler.__init__(self, ui, module, driver_package, name,
            description, rationale)
        self.xorg_driver = xorg_driver
        self.alt_free_driver = alt_free_driver
        self.extra_conf_options = extra_conf_options
        self.add_modules = add_modules
        self.remove_modules = remove_modules

        if os.path.exists(OSLib.inst.xorg_conf_path):
            try:
                self.xorg_conf = xorgconfig.readConfig(OSLib.inst.xorg_conf_path)
            except (IOError, xorgconfig.ParseException, AttributeError):
                self.xorg_conf = None
        else:
            self.xorg_conf = xorgconfig.XorgConfig()

    def can_change(self):
        if self.xorg_conf:
            return None
        else:
            # translators: %s is the path to xorg.conf
            return self.ui._('Reconfiguring X.org video drivers is not '
                'possible: %s is invalid.') % \
                OSLib.inst.xorg_conf_path

    def enabled(self):
        if self.xorg_conf:
            devices = self.xorg_conf.getSections('device') 
            if len(devices) > 0 and devices[0].driver != self.xorg_driver:
                logging.debug('XorgDriverHandler(%s, %s, %s): xorg.conf driver %s, considering disabled' % (
                    self.module, self.package, self.xorg_driver, devices[0].driver))
                return False

            logging.debug('XorgDriverHandler(%s, %s, %s): xorg.conf driver matches' % (
                    self.module, self.package, self.xorg_driver))
        return ModulePackageHandler.enabled(self)

00087     def _mod_enabled(self, module):
        '''Check if current xorg configuration enables a module.'''

        module_sections = self.xorg_conf.getSections('module')
        if len(module_sections) < 1:
            return False
        for m in module_sections[0]._contents:
            if hasattr(m, '_row') and len(m._row) >= 2 and m._row[1] == module:
                return True
        return False

    def enable(self):
        ModulePackageHandler.enable(self)

        # do not mangle xorg.conf if package installation has been aborted
        if not OSLib.inst.package_installed(self.package):
            return

        # backup the current xorg.conf
        if os.path.exists(OSLib.inst.xorg_conf_path):
            open(os.path.join(OSLib.inst.backup_dir, self.xorg_driver + '.oldconf'), 'w').write(
                open(OSLib.inst.xorg_conf_path).read())
        else:
            open(os.path.join(OSLib.inst.backup_dir, self.xorg_driver + '.noconf'), 'w')

        if len(self.xorg_conf.getSections('device')) == 0:
            self.xorg_conf.append(self.xorg_conf.makeSection(None, 
                ['Section', 'Device']))
        device = self.xorg_conf.getSections('device')[0]
        device.driver = self.xorg_driver

        have_modules = len(self.xorg_conf.getSections('module')) > 0
        if have_modules:
            for m in self.remove_modules:
                self.xorg_conf.getSections('module')[0].removeModule(m)
        if self.add_modules:
            if not have_modules:
                self.xorg_conf.append(self.xorg_conf.makeSection(None, ['Section',
                    'Module']))
            for m in self.add_modules:
                if not self._mod_enabled(m):
                    self.xorg_conf.getSections('module')[0].addModule(m)

        for k, v in self.extra_conf_options.iteritems():
            device.option.removeOptionByName(k)
            device.option.appendOptionRow([k, v])

        self.enable_config_hook()

        self.xorg_conf.writeConfig(OSLib.inst.xorg_conf_path)
        
        OSLib.inst.ui_notify_reboot(self.ui)

    def disable(self):
        ModulePackageHandler.disable(self)

        # do not mangle xorg.conf if package uninstallation has been aborted
        if OSLib.inst.package_installed(self.package):
            return

        noconf = os.path.join(OSLib.inst.backup_dir, self.xorg_driver + '.noconf')
        oldconf = os.path.join(OSLib.inst.backup_dir, self.xorg_driver + '.oldconf')

        # if we previously didn't have an xorg.conf, delete it
        if os.path.exists(noconf):
            os.unlink(noconf)
            if os.path.exists(OSLib.inst.xorg_conf_path):
                os.unlink(OSLib.inst.xorg_conf_path)
        # if we have the previous xorg.conf, restore that
        elif os.path.exists(oldconf):
            open(OSLib.inst.xorg_conf_path, 'w').write(open(oldconf).read())
            os.unlink(oldconf)
            self.xorg_conf = xorgconfig.readConfig(OSLib.inst.xorg_conf_path)
        else: # no backup, so mangle current config manually
            device = self.xorg_conf.getSections('device')[0]
            device.driver = self.alt_free_driver

            have_modules = len(self.xorg_conf.getSections('module')) > 0
            if have_modules:
                for m in self.add_modules:
                    self.xorg_conf.getSections('module')[0].removeModule(m)
            if self.remove_modules:
                if not have_modules:
                    self.xorg_conf.append(self.xorg_conf.makeSection(None, ['Section',
                        'Module']))
                for m in self.remove_modules:
                    if not self._mod_enabled(m):
                        self.xorg_conf.getSections('module')[0].addModule(m)

            for k in self.extra_conf_options:
                device.option.removeOptionByName(k)

            self.disable_config_hook()

            self.xorg_conf.writeConfig(OSLib.inst.xorg_conf_path)

        OSLib.inst.ui_notify_reboot(self.ui)

00185     def enable_config_hook(self):
        '''Custom self.xorg_config changes after driver, modules, and extra
        driver options have been changed.
        '''
        pass

00191     def disable_config_hook(self):
        '''Custom self.xorg_config changes after driver, modules, and extra
        driver options have been changed.
        '''
        pass

00197     def supports_composite(self):
        '''Return whether this driver supports the composite extension.'''

        return False


Generated by  Doxygen 1.6.0   Back to index