Edit file File name : keyboard.py Content :# # Copyright (C) 2012 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties 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. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # """ This module provides functions for dealing with keyboard layouts/keymaps in Anaconda. """ import re import langtable from pyanaconda.core.configuration.anaconda import conf from pyanaconda import localization from pyanaconda.core.constants import DEFAULT_KEYBOARD from pyanaconda.modules.common.task import sync_run_task from pyanaconda.modules.common.constants.services import LOCALIZATION from pyanaconda.anaconda_loggers import get_module_logger log = get_module_logger(__name__) # should match and parse strings like 'cz' or 'cz (qwerty)' regardless of white # space LAYOUT_VARIANT_RE = re.compile(r'^\s*([/\w]+)\s*' # layout plus r'(?:(?:\(\s*([-\w]+)\s*\))' # variant in parentheses r'|(?:$))\s*') # or nothing class KeyboardConfigError(Exception): """Exception class for keyboard configuration related problems""" pass class InvalidLayoutVariantSpec(Exception): """ Exception class for errors related to parsing layout and variant specification strings. """ pass def parse_layout_variant(layout_variant_str): """ Parse layout and variant from the string that may look like 'layout' or 'layout (variant)'. :param layout_variant_str: keyboard layout and variant string specification :type layout_variant_str: str :return: the (layout, variant) pair, where variant can be "" :rtype: tuple :raise InvalidLayoutVariantSpec: if the given string isn't a valid layout and variant specification string """ match = LAYOUT_VARIANT_RE.match(layout_variant_str) if not match: msg = "'%s' is not a valid keyboard layout and variant specification" % layout_variant_str raise InvalidLayoutVariantSpec(msg) layout, variant = match.groups() # groups may be (layout, None) if no variant was specified return (layout, variant or "") def join_layout_variant(layout, variant=""): """ Join layout and variant to form the commonly used 'layout (variant)' or 'layout' (if variant is missing) format. :type layout: string :type variant: string :return: 'layout (variant)' or 'layout' string :rtype: string """ if variant: return "%s (%s)" % (layout, variant) else: return layout def normalize_layout_variant(layout_str): """ Normalize keyboard layout and variant specification given as a single string. E.g. for a 'layout(variant) string missing the space between the left parenthesis return 'layout (variant)' which is a proper layout and variant specification we use. :param layout_str: a string specifying keyboard layout and its variant :type layout_str: string """ layout, variant = parse_layout_variant(layout_str) return join_layout_variant(layout, variant) def populate_missing_items(localization_proxy=None): """ Function that populates virtual console keymap and X layouts if they are missing. By invoking systemd-localed methods this function READS AND WRITES CONFIGURATION FILES (but tries to keep their content unchanged). :param localization_proxy: DBus proxy of the localization module or None """ task_path = localization_proxy.PopulateMissingKeyboardConfigurationWithTask() task_proxy = LOCALIZATION.get_proxy(task_path) sync_run_task(task_proxy) def activate_keyboard(localization_proxy): """ Try to setup VConsole keymap and X11 layouts as specified in kickstart. :param localization_proxy: DBus proxy of the localization module or None """ task_path = localization_proxy.ApplyKeyboardWithTask() task_proxy = LOCALIZATION.get_proxy(task_path) sync_run_task(task_proxy) def set_x_keyboard_defaults(localization_proxy, xkl_wrapper): """ Set default keyboard settings (layouts, layout switching). :param localization_proxy: DBus proxy of the localization module or None :type ksdata: object instance :param xkl_wrapper: XklWrapper instance :type xkl_wrapper: object instance :raise InvalidLocaleSpec: if an invalid locale is given (see localization.is_valid_langcode) """ x_layouts = localization_proxy.XLayouts # remove all X layouts that are not valid X layouts (unsupported) valid_layouts = [] for layout in x_layouts: if xkl_wrapper.is_valid_layout(layout): valid_layouts.append(layout) localization_proxy.SetXLayouts(valid_layouts) if valid_layouts: # do not add layouts if there are any specified in the kickstart # (the x_layouts list comes from kickstart) return locale = localization_proxy.Language layouts = localization.get_locale_keyboards(locale) if layouts: # take the first locale (with highest rank) from the list and # store it normalized new_layouts = [normalize_layout_variant(layouts[0])] if not langtable.supports_ascii(layouts[0]): # does not support typing ASCII chars, append the default layout new_layouts.append(DEFAULT_KEYBOARD) else: log.error("Failed to get layout for chosen locale '%s'", locale) new_layouts = [DEFAULT_KEYBOARD] localization_proxy.SetXLayouts(new_layouts) if conf.system.can_configure_keyboard: xkl_wrapper.replace_layouts(new_layouts) if len(new_layouts) >= 2 and not localization_proxy.LayoutSwitchOptions: # initialize layout switching if needed localization_proxy.SetLayoutSwitchOptions(["grp:alt_shift_toggle"]) if conf.system.can_configure_keyboard: xkl_wrapper.set_switching_options(["grp:alt_shift_toggle"]) # activate the language-default layout instead of the additional # one xkl_wrapper.activate_default_layout() Save