[PATCH] Use systemd-localed for writing out xorg conf file (#958714)
Vratislav Podzimek
vpodzime at redhat.com
Mon May 6 16:02:59 UTC 2013
Also use its file to write out configuration to the target system instead of our
own file nobody reads. The systemd-localed's configuration file is read by Gnome
and hopefully the other desktop environments as well.
Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
pyanaconda/keyboard.py | 245 ++++++++++++++++++++++++++++++-------------------
1 file changed, 153 insertions(+), 92 deletions(-)
diff --git a/pyanaconda/keyboard.py b/pyanaconda/keyboard.py
index be33314..004fa97 100755
--- a/pyanaconda/keyboard.py
+++ b/pyanaconda/keyboard.py
@@ -34,6 +34,8 @@ keymaps.
import types
import os
+import shutil
+
from pyanaconda import iutil
from pyanaconda.safe_dbus import dbus_call_safe_sync, dbus_get_property_safe_sync
from pyanaconda.safe_dbus import DBUS_SYSTEM_BUS_ADDR
@@ -90,50 +92,6 @@ def _join_layout_variant(layout, variant=""):
else:
return layout
-def get_layouts_xorg_conf(keyboard):
- """
- Get the xorg.conf content setting up layouts in the ksdata.
-
- :param keyboard: ksdata.keyboard object
- :rtype: str
-
- """
-
- layouts = list()
- variants = list()
-
- for layout_variant in keyboard.x_layouts:
- (layout, variant) = _parse_layout_variant(layout_variant)
- layouts.append(layout)
- variants.append(variant)
-
- ret = "#This file was generated by the Anaconda installer\n"
-
- #section header
- ret += 'Section "InputClass"\n'\
- '\tIdentifier\t"anaconda-keyboard"\n'\
- '\tMatchIsKeyboard\t"on"\n'
-
- #layouts
- ret += '\tOption\t"XkbLayout"\t'
- ret += '"' + ','.join(layouts) + '"\n'
-
- #variants
- if any(variants):
- #write out this line only if some variants are specified
- ret += '\tOption\t"XkbVariant"\t'
- ret += '"' + ','.join(variants) + '"\n'
-
- #switching
- if any(keyboard.switch_options):
- ret += '\tOption\t"XkbOptions"\t'
- ret += '"' + ','.join(keyboard.switch_options) + '"\n'
-
- #section footer
- ret += 'EndSection\n'
-
- return ret
-
def populate_missing_items(keyboard):
"""
Function that populates keyboard.vc_keymap and keyboard.x_layouts if
@@ -156,7 +114,7 @@ def populate_missing_items(keyboard):
c_lay_var = localed.set_and_convert_keymap(keyboard.vc_keymap)
keyboard.x_layouts.append(c_lay_var)
-def write_keyboard_config(keyboard, root, convert=True, weight=0):
+def write_keyboard_config(keyboard, root, convert=True):
"""
Function that writes files with layouts configuration to
$root/etc/X11/xorg.conf.d/01-anaconda-layouts.conf and
@@ -173,8 +131,9 @@ def write_keyboard_config(keyboard, root, convert=True, weight=0):
if convert:
populate_missing_items(keyboard)
- xconf_dir = os.path.normpath(root + "/etc/X11/xorg.conf.d")
- xconf_file = "%0.2d-anaconda-keyboard.conf" % weight
+ xconf_dir = "/etc/X11/xorg.conf.d"
+ xconf_file = "00-keyboard.conf"
+ xconf_file_path = os.path.normpath(xconf_dir + "/" + xconf_file)
vcconf_dir = os.path.normpath(root + "/etc")
vcconf_file = "vconsole.conf"
@@ -189,11 +148,30 @@ def write_keyboard_config(keyboard, root, convert=True, weight=0):
errors.append("Cannot create directory xorg.conf.d")
if keyboard.x_layouts:
- try:
- with open(os.path.join(xconf_dir, xconf_file), "w") as fobj:
- fobj.write(get_layouts_xorg_conf(keyboard))
- except IOError as ioerr:
- errors.append("Cannot write X keyboard configuration file")
+ localed_wrapper = LocaledWrapper()
+
+ if root != "/":
+ # writing to a different root, we need to save these values, so that
+ # we can restore them when we have the file written out
+ layouts_variants = localed_wrapper.layouts_variants
+ options = localed_wrapper.options
+
+ # set systemd-localed's layouts, variants and switch options, which
+ # also generates a new conf file
+ localed_wrapper.set_layouts(keyboard.x_layouts,
+ keyboard.switch_options)
+
+ # copy the file to the chroot
+ shutil.copy2(xconf_file_path,
+ os.path.normpath(root + "/" + xconf_file_path))
+
+ # restore the original values
+ localed_wrapper.set_layouts(layouts_variants,
+ options)
+ else:
+ # just let systemd-localed write out the conf file
+ localed_wrapper.set_layouts(keyboard.x_layouts,
+ keyboard.switch_options)
if keyboard.vc_keymap:
try:
@@ -289,9 +267,8 @@ def activate_keyboard(keyboard):
if not keyboard.vc_keymap:
keyboard.vc_keymap = c_keymap
- # write out full configuration that will be loaded by X server
- # (systemd-localed writes configuration with only one layout)
- write_keyboard_config(keyboard, root="/", convert=False, weight=99)
+ # write out keyboard configuration for the X session
+ write_keyboard_config(keyboard, root="/", convert=False)
def item_str(s):
"""Convert a zero-terminated byte array to a proper str"""
@@ -664,14 +641,63 @@ class LocaledWrapper(object):
Gio.DBusConnectionFlags.MESSAGE_BUS_CONNECTION,
None, None)
- def set_and_convert_keymap(self, keymap):
+ @property
+ def keymap(self):
+ keymap = dbus_get_property_safe_sync(LOCALED_SERVICE,
+ LOCALED_OBJECT_PATH,
+ LOCALED_IFACE,
+ "VConsoleKeymap",
+ self._connection)
+
+ # returned GVariant is unpacked to a tuple with a single element
+ return keymap[0]
+
+ @property
+ def layouts_variants(self):
+ layouts = dbus_get_property_safe_sync(LOCALED_SERVICE,
+ LOCALED_OBJECT_PATH,
+ LOCALED_IFACE,
+ "X11Layout",
+ self._connection)
+
+ variants = dbus_get_property_safe_sync(LOCALED_SERVICE,
+ LOCALED_OBJECT_PATH,
+ LOCALED_IFACE,
+ "X11Variant",
+ self._connection)
+
+ # returned GVariants are unpacked to tuples with single elements
+ # containing comma-separated values
+ layouts = layouts[0].split(",")
+ variants = variants[0].split(",")
+
+ # if there are more layouts than variants, empty strings should be appended
+ diff = len(layouts) - len(variants)
+ variants.extend(diff * [""])
+
+ # map can be used with multiple lists and works like zipWith (Haskell)
+ return map(_join_layout_variant, layouts, variants)
+
+ @property
+ def options(self):
+ options = dbus_get_property_safe_sync(LOCALED_SERVICE,
+ LOCALED_OBJECT_PATH,
+ LOCALED_IFACE,
+ "X11Options",
+ self._connection)
+
+ # returned GVariant is unpacked to a tuple with a single element
+ return options[0]
+
+ def set_keymap(self, keymap, convert=False):
"""
- Method that sets VConsole keymap and returns X11 layout and
- variant that (systemd-localed thinks) match given keymap best.
+ Method that sets VConsole keymap via systemd-localed's DBus API.
- :return: string containing "layout (variant)" or "layout" if variant
- is missing
- :rtype: string
+ :param keymap: VConsole keymap that should be set
+ :type keymap: str
+ :param convert: whether the keymap should be converted to a X11 layout
+ (see set_and_convert_keymap)
+ :type convert: bool
"""
@@ -679,55 +705,90 @@ class LocaledWrapper(object):
# where convert indicates whether the keymap should be converted
# to X11 layout and user_interaction indicates whether PolicyKit
# should ask for credentials or not
- args = GLib.Variant('(ssbb)', (keymap, "", True, False))
+ args = GLib.Variant('(ssbb)', (keymap, "", convert, False))
dbus_call_safe_sync(LOCALED_SERVICE, LOCALED_OBJECT_PATH, LOCALED_IFACE,
"SetVConsoleKeyboard", args, self._connection)
- layout = dbus_get_property_safe_sync(LOCALED_SERVICE,
- LOCALED_OBJECT_PATH,
- LOCALED_IFACE,
- "X11Layout",
- self._connection)
+ def set_and_convert_keymap(self, keymap):
+ """
+ Method that sets VConsole keymap and returns X11 layouts and
+ variants that (systemd-localed thinks) match given keymap best.
- variant = dbus_get_property_safe_sync(LOCALED_SERVICE,
- LOCALED_OBJECT_PATH,
- LOCALED_IFACE,
- "X11Variant",
- self._connection)
+ :return: string containing comma-separated "layout (variant)" or
+ "layout" layout specifications
+ :rtype: string
+
+ """
- # returned GVariants are unpacked to a tuple with single element
- layout = layout[0]
- variant = variant[0]
+ self.set_keymap(keymap, convert=True)
- return _join_layout_variant(layout, variant)
+ layouts_str, variants_str = self.layouts_variants
- def set_and_convert_layout(self, layout_variant):
- """
- Method that sets X11 layout and variant (for later X sessions)
- and returns VConsole keymap that (systemd-localed thinks) matches
- given layout and variant best.
+ layouts = layouts_str.split(",")
+ variants = variants_str.split(",")
- :return: a keymap matching layout and variant best
- :rtype: string
+ # if there are less variants than layouts, empty strings need to be
+ # appended
+ diff = len(layouts) - len(variants)
+ variants = variants + diff * [""]
+
+ layouts_variants = []
+ layouts_variants.extend(map(_join_layout_variant, layouts, variants))
+
+ return ",".join(layouts_variants)
+
+ def set_layouts(self, layouts_variants, options=None, convert=False):
+ """
+ Method that sets X11 layouts and variants (for later X sessions) via
+ systemd-localed's DBus API.
+
+ :param layout_variant: list of 'layout (variant)' or 'layout'
+ specifications of layouts and variants
+ :type layout_variant: list of strings
+ :param options: list of X11 options that should be set
+ :type options: list of strings
+ :param convert: whether the keymap should be converted to a X11 layout
+ (see set_and_convert_keymap)
+ :type convert: bool
"""
- (layout, variant) = _parse_layout_variant(layout_variant)
+ layouts = []
+ variants = []
+
+ for layout_variant in layouts_variants:
+ (layout, variant) = _parse_layout_variant(layout_variant)
+ layouts.append(layout)
+ variants.append(variant)
+
+ layouts_str = ",".join(layouts)
+ variants_str = ",".join(variants)
+ if options:
+ opts_str = ",".join(options)
+ else:
+ opts_str = ""
# args: layout, model, variant, options, convert, user_interaction
# where convert indicates whether the keymap should be converted
# to X11 layout and user_interaction indicates whether PolicyKit
# should ask for credentials or not
- args = GLib.Variant("(ssssbb)", (layout, "", variant, "", True, False))
+ args = GLib.Variant("(ssssbb)", (layouts_str, "", variants_str, opts_str,
+ convert, False))
dbus_call_safe_sync(LOCALED_SERVICE, LOCALED_OBJECT_PATH, LOCALED_IFACE,
"SetX11Keyboard", args, self._connection)
- keymap = dbus_get_property_safe_sync(LOCALED_SERVICE,
- LOCALED_OBJECT_PATH,
- LOCALED_IFACE,
- "VConsoleKeymap",
- self._connection)
+ def set_and_convert_layout(self, layout_variant):
+ """
+ Method that sets X11 layout and variant (for later X sessions)
+ and returns VConsole keymap that (systemd-localed thinks) matches
+ given layout and variant best.
- # returned GVariant is unpacked to a tuple with single element
- return keymap[0]
+ :return: a keymap matching layout and variant best
+ :rtype: string
+
+ """
+
+ self.set_layouts([layout_variant], convert=True)
+
+ return self.keymap
--
1.7.11.7
More information about the anaconda-patches
mailing list