home *** CD-ROM | disk | FTP | other *** search
Text File | 2006-11-29 | 39.6 KB | 1,519 lines |
- /**
- * File:
- * Keyboard.ycp
- *
- * Module:
- * Keyboard
- *
- * Summary:
- * Provide information regarding the keyboard.
- *
- * Authors:
- * Thomas Roelz <tom@suse.de>
- *
- * Maintainer: Jiri Suchomel <jsuchome@suse.cz>
- *
- * $Id: Keyboard.ycp 32769 2006-09-08 09:29:15Z jsuchome $
- *
- * Usage:
- * ------
- * This module provides the following data for public access via Keyboard::<var-name>.
- *
- * !!! These are to be used READ_ONLY !!!
- *
- * Set in the constructor after the first import (only after probing):
- *
- * kb_model
- * XkbLayout
- * unique_key
- *
- * Set after having called SetLanguage( keyboard ).
- *
- * XkbModel
- * XkbVariant
- * XkbOptions
- * LeftAlt
- * RightAlt
- * ScrollLock
- * RightCtl
- * Apply
- * keymap
- * compose_table
- * current_kbd
- * ckb_cmd
- * xkb_cmd
- *
- *
- * This module provides the following functions for public access via Keyboard::<func-name>(...)
- *
- * Keyboard() - Module constructor.
- * If saved module data exists in continue mode, these are read in.
- * Otherwise Hardware is probed.
- *
- * MakeProposal() - return user-readable description of keyboard
- *
- * Probe() - Force new hardware probing and set public data accordingly.
- *
- * Save() - Save module data to /var/lib/YaST2/Keyboard_data.ycp
- *
- * Restore() - Load module data from /var/lib/YaST2/Keyboard_data.ycp
- *
- * SetLanguage() - Set public data to values corresponding to the given language.
- *
- * GetKeyboardForLanguage() - Get the keyboard language for a given language code.
- *
- * Set() - Set the keyboard to the given keyboard language.
- * SetConsole() - Set the console keyboard to the given keyboard language.
- *
- * SetX11() - Set the X11 keyboard to the given keyboard language.
- *
- * Selection() - Get map of translated keyboards to be displayed in the GUI.
- *
- */
-
- {
-
- module "Keyboard";
- textdomain "country";
-
- import "Arch";
- import "AsciiFile";
- import "Directory";
- import "Label";
- import "Language";
- import "Linuxrc";
- import "Misc";
- import "Mode";
- import "Package";
- import "ProductFeatures";
- import "Stage";
- import "XLibAPI";
- import "XVersion";
-
- // ------------------------------------------------------------------------
- // START: Globally defined data to be accessed via Keyboard::<variable>
- // ------------------------------------------------------------------------
-
- // kb_model string
- //
- global string kb_model = "pc104";
-
- // XkbModel string
- //
- global string XkbModel = "";
-
- // XkbLayout string
- // Only some keyboards do report this information (e.g. sparc).
- //
- global string XkbLayout = "";
-
- // XkbVariant string
- //
- global string XkbVariant = "";
-
- // keymap string for ncurses
- //
- global string keymap = "us.map.gz";
-
- // compose_table entry
- //
- global string compose_table = "clear winkeys shiftctrl latin1.add";
-
- // X11 Options string
- //
- global string XkbOptions = "";
-
- // X11 LeftAlt
- //
- global string LeftAlt = "";
-
- // X11 RightAlt
- //
- global string RightAlt = "";
-
- // X11 RightCtl
- //
- global string RightCtl = "";
-
- // X11 ScrollLock
- //
- global string ScrollLock = "";
-
- // Apply string fuer xbcmd
- //
- global string Apply = "";
-
- // The console keyboard command
- //
- global string ckb_cmd = "";
-
- // The X11 keyboard command
- //
- global string xkb_cmd = "";
-
- // The keyboard currently set.
- //
- global string current_kbd = "";
-
- /**
- * keyboard set on start
- */
- global string keyboard_on_entry = "";
-
- /**
- * expert values on start
- */
- global map expert_on_entry = $[];
-
- // The default keyboard if set.
- //
- global string default_kbd = "";
-
- // Flag indicating if the user has chosen a keyboard.
- // To be set from outside.
- //
- global boolean user_decision = false;
-
- // unique key
- //
- global string unique_key = "";
-
- // state of Expert settings
- global boolean ExpertSettingsChanged = false;
-
- // --------------------------------------------------------------
- // END: Globally defined data to be accessed via Keyboard::<variable>
- // --------------------------------------------------------------
-
-
- // --------------------------------------------------------------
- // START: Locally defined data
- // --------------------------------------------------------------
-
- // if Keyboard::Restore() was called
- boolean restore_called = false;
-
- // User readable description, access via Keyboard::MakeProposal()
- //
- string name = "";
-
- // Keyboard description from DB
- //
- list kbd_descr = [];
-
- string kbd_tty = "tty1 tty2 tty3 tty4 tty5 tty6 tty8 tty9 tty10 tty11 tty12 tty13 tty14 tty15 tty16 tty17 tty18 tty19 tty20";
-
- string kbd_rate = "";
- string kbd_delay = "";
- string kbd_numlock = "";
- string kbd_capslock = "";
- string kbd_scrlock = "";
- string kbd_disable_capslock = "";
-
- list keyboardprobelist = []; // List of all probed keyboards
-
- // parameters for dumpkeys command - see bug #116143
- map charsets = $[
- "Pl02.map.gz" : "iso-8859-2",
- "br-abnt2.map.gz" : "iso-8859-15",
- "cz-us-qwertz.map.gz" : "iso-8859-2",
- "cz-lat2-us.map.gz" : "iso-8859-2",
- "de-lat1-nd.map.gz" : "iso-8859-15",
- "de-latin1-nodeadkeys.map.gz" : "iso-8859-15",
- "es.map.gz" : "iso-8859-15",
- "fr-latin1.map.gz" : "iso-8859-15",
- "gr.map.gz" : "iso-8859-7",
- "hu.map.gz" : "iso-8859-2",
- "it.map.gz" : "iso-8859-15",
- "no-latin1.map.gz" : "iso-8859-15",
- "pt-latin1.map.gz" : "iso-8859-15",
- "ru1.map.gz" : "koi8-r",
- "sk-qwertz.map.gz" : "iso-8859-2",
- "sk-qwerty.map.gz" : "iso-8859-2",
- "slovene.map.gz" : "iso-8859-2"
- ];
-
- // ----------------------------------------------------------------------
- // END: Locally defined data
- // ----------------------------------------------------------------------
-
- // function prototypes
- global define void Set (string keyboard);
-
- // ------------------------------------------------------------------
- // START: Globally defined functions
- // ------------------------------------------------------------------
-
- /**
- * GetKbdSysconfig()
- *
- * Restore the the non-keyboard values from sysconfig.
- */
-
- define void GetKbdSysconfig()
- ``{
- // Read the the variables not touched by the module to be able to
- // store them again on Save().
- //
- kbd_tty = Misc::SysconfigRead( .sysconfig.keyboard.KBD_TTY, kbd_tty );
- kbd_rate = Misc::SysconfigRead( .sysconfig.keyboard.KBD_RATE, kbd_rate );
- kbd_delay = Misc::SysconfigRead( .sysconfig.keyboard.KBD_DELAY, kbd_delay );
- kbd_numlock = Misc::SysconfigRead( .sysconfig.keyboard.KBD_NUMLOCK,
- kbd_numlock );
- kbd_capslock = Misc::SysconfigRead( .sysconfig.keyboard.KBD_CAPSLOCK,
- kbd_capslock );
- kbd_scrlock = Misc::SysconfigRead( .sysconfig.keyboard.KBD_SCRLOCK,
- kbd_scrlock );
- kbd_disable_capslock =
- Misc::SysconfigRead( .sysconfig.keyboard.KBD_DISABLE_CAPS_LOCK,
- kbd_disable_capslock );
-
- y2milestone( "rate:%1 delay:%2 numlock:%3 capslock:%4 scrlock:%5 disclock:%6",
- kbd_rate, kbd_delay, kbd_numlock, kbd_capslock,
- kbd_scrlock, kbd_disable_capslock );
- y2milestone( "tty:%1", kbd_tty );
- }
-
- /*
- * get_reduced_keyboard_db()
- *
- * Read the Keyboard DB and select entries for current XkbModel and architecture.
- *
- * @return Reduced keyboard DB (map)
- */
-
- define map<string,list> get_reduced_keyboard_db() {
- /*
- * The keyboard DB is a very big map containing entries for all known keyboard
- * languages. Each of these entries contains a map of the different known
- * architectures and each of these architectures contains a map for the different
- * kb_models possible on the given architecture. This innermost map finally contains
- * data relevant for ncurses.
- *
- * $[
- * "english-us":
- * [
- * ...language stuff...
- * $[ "i386" :
- * $[ "pc104":
- * $[ "ncurses": "us.map.gz" ]],
- *
- * What now follows is code that cuts out from this map the unnecessary
- * architectures and XkbModels. The different languages are kept.
- *
- * Load the keyboard DB.
- * Do not hold this database in a permanent module variable (it's very large).
- */
-
- // eval is necessary for translating the texts needed to be translated
- map<string,list> all_keyboards = (map<string,list>)
- eval(SCR::Read( .target.yast2, "keyboard_raw.ycp" ));
-
- if (all_keyboards == nil) all_keyboards = $[];
-
- // The new reduced map of keyboard data.
- //
- map<string,list> keyboards = $[];
- string arch = Arch::architecture ();
- if( arch == "ppc64" )
- {
- arch = "ppc";
- }
- y2milestone( "get_reduced_keyboard_db: Arch::architecture () %1 used %2",
- Arch::architecture (), arch );
-
- // loop over all languages
- foreach (string kb_lang, list description, all_keyboards, {
-
- if (size (description) == 2)
- {
- // Skip langage specific naming of keyboard languages.
- // Select the keyboard data.
- //
- map keyboards_archi = description[1]:$[]; // all architectures
-
- // Select current architecture.
- //
- map keyboard_archi = keyboards_archi[arch]:$[];
-
- // Get the data for the current kb_model in the current architecture.
- //
- map keyboard_model = keyboard_archi[kb_model]:$[];
-
- if( size( keyboard_model ) > 0 ) // found an entry
- {
- // Add the data found (as list) to the new map under the current
- // language key.
- //
- list keyboard_selected = []; // temporary list
-
- // Add the language stuff.
- //
- keyboard_selected = add( keyboard_selected, description[0]:"" );
-
- // Add the Qt- and ncurses-data.
- //
- keyboard_selected = add( keyboard_selected, keyboard_model );
-
- // Add this list to the reduced keyboard map under the current language key.
- //
- keyboards[kb_lang] = keyboard_selected;
- }
- }
- });
-
- return keyboards;
- }; // get_reduced_keyboard_db()
-
- /**
- * Return a map for conversion from keymap to YaST2 keyboard code()
- * Get the map of translated keyboard names.
- * @param -
- * @return map of $[ keyboard_code : keyboard_name, ...] for all known
- * keyboards. 'keyboard_code' is used internally in Set and Get
- * functions. 'keyboard_name' is a user-readable string.
- * Uses Language::language for translation.
- *
- */
- global define map<string, string> keymap2yast() {
-
- return mapmap (string code, list kbd_value, get_reduced_keyboard_db(), {
- map code_map = kbd_value[1]:$[];
- list codel = splitstring (code_map["ncurses"]:"", ".");
- return $[ codel[0]:"": code ];
- });
- }
-
- /**
- * GetX11KeyData()
- *
- * Get the keyboard info for X11 for the given keymap
- *
- * @param name of the keymap
- *
- * @return map containing the x11 config data
- *
- */
- global define map GetX11KeyData (string keymap) {
-
- string cmd = "/usr/sbin/xkbctrl";
- map x11data = $[];
-
- if (SCR::Read(.target.size, cmd) > 0 )
- {
- string file = Directory::tmpdir + "/xkbctrl.out";
- cmd = cmd + " " + keymap;
- SCR::Execute (.target.bash, cmd + " > " + file );
- x11data = (map)SCR::Read(.target.ycp, file );
- }
- else
- {
- y2warning ("/usr/sbin/xkbctrl not found");
- }
- return x11data;
- }
-
- /**
- * Return human readable (and translated) name of the given keyboard map
- * @param kbd keyboard map
- * @return string
- */
- define string GetKeyboardName (string kbd) {
-
- map keyboards = get_reduced_keyboard_db ();
- list descr = keyboards[kbd]:[];
- string ret = kbd;
-
- if (descr != [])
- {
- locale translate = descr[0]:kbd;
- ret = (string)eval(translate);
- }
- return ret;
- }
-
- /**
- * GetExpertValues()
- *
- * Return the values for the various expert settings in a map
- *
- * @return map with values filled in
- *
- */
- global define map GetExpertValues() {
- map ret = $[ "rate" : kbd_rate,
- "delay" : kbd_delay,
- "numlock" : kbd_numlock,
- "capslock" : kbd_capslock=="yes" ? true : false,
- "scrlock" : kbd_scrlock=="yes" ? true : false,
- "tty" : kbd_tty,
- "discaps" : kbd_disable_capslock=="yes" ? true : false ];
- return( ret );
- }
-
- /**
- * Get the system_language --> keyboard_language conversion map.
- *
- * @return conversion map
- *
- * @see get_xkblayout2keyboard()
- */
-
- define map get_lang2keyboard() {
-
- map base_lang2keyboard = (map)SCR::Read(.target.yast2, "lang2keyboard.ycp");
- if (base_lang2keyboard == nil) base_lang2keyboard = $[];
-
- return union (base_lang2keyboard, Language::GetLang2KeyboardMap ());
- }
-
-
-
- /**
- * GetKeyboardForLanguage()
- *
- * Get the keyboard language for the given system language.
- *
- * @param System language code, e.g. "en_US".
- * Default keyboard language to be returned if nothing found.
- *
- * @return The keyboard language for this language, e.g. "english-us"
- * or the default value if nothing found.
- *
- */
- global define string GetKeyboardForLanguage( string sys_language,
- string default_keyboard) {
-
- map lang2keyboard = get_lang2keyboard();
- string kb = lang2keyboard[sys_language]:"";
-
- if (kb == "")
- {
- sys_language = substring (sys_language, 0,2);
- kb = lang2keyboard[sys_language]:default_keyboard;
- }
- y2milestone( "GetKeyboardForLanguage lang:%1 def:%2 ret:%3",
- sys_language, default_keyboard, kb);
- return kb;
- }
-
-
-
- /**
- * run X11 configuration after inital boot
- */
- define boolean x11_setup_needed () {
-
- return
- Arch::x11_setup_needed () &&
- ! (Linuxrc::serial_console() || Linuxrc::vnc() || Linuxrc::usessh()) &&
- ((Stage::initial () && !Linuxrc::text ()) ||
- Package::Installed ("yast2-x11"));
- }
-
- /**
- * SetLanguage()
- *
- * Set language specific module data to reflect the given language.
- *
- * @param Keyboard language e.g. "english-us"
- *
- * @return true - Success. Language set in public data.
- * false - Error. Language not set.
- *
- */
-
- global define boolean SetLanguage (string keyboard) {
-
- y2milestone ("Setting keyboard to: <%1>", keyboard );
-
- // Get the reduced keyboard DB.
- //
- map keyboards = get_reduced_keyboard_db();
-
- y2debug( "reduced kbd db %1", keyboards );
- // Get the entry from the reduced local map for the given language.
- //
- kbd_descr = keyboards[keyboard]:[];
-
- y2milestone ("Description for keyboard <%1>: <%2>",keyboard, kbd_descr);
-
- if ( kbd_descr != [] ) // keyboard found
- {
- // Get keymap for ncurses
- //
- keymap = kbd_descr[1, "ncurses"]:"us.map.gz";
- locale translate = kbd_descr[0]:keyboard;
- name = (string)eval(translate);
-
- map x11data = GetX11KeyData( keymap );
- y2milestone( "x11data=%1", x11data );
-
- XkbModel = x11data["XkbModel"]:"pc104";
- XkbLayout = x11data["XkbLayout"]:"";
- XkbVariant = x11data["XkbVariant"]:"basic";
- XkbOptions = x11data["XkbOptions"]:"";
- LeftAlt = x11data["LeftAlt"]:"";
- RightAlt = x11data["RightAlt"]:"";
- ScrollLock = x11data["ScrollLock"]:"";
- RightCtl = x11data["RightCtl"]:"";
- Apply = x11data["Apply"]:"";
-
- // Build the compose table entry.
- //
- compose_table = "clear ";
-
- if ( XkbModel == "pc104" || XkbModel == "pc105" )
- {
- compose_table = compose_table + "winkeys shiftctrl ";
- }
-
- // Check for "compose" entry in keytable, might define
- // a different encoding (i.e. "latin2").
- //
- string compose = kbd_descr[1,"compose"]:"latin1.add";
-
- compose_table = compose_table + compose;
- }
- else // Language not found.
- {
- return false; // Error
- }
-
- // Console command...
- //
- // dumpkeys may need -c parameter (see #116143)
- string dumpkeys = " ; dumpkeys";
- if (haskey (charsets, keymap))
- {
- dumpkeys = sformat ("%1 -c %2 ", dumpkeys, charsets[keymap]:"");
- }
- ckb_cmd = "/bin/loadkeys " + keymap + dumpkeys + " | loadkeys -u";
- // FIXME should be "/bin/loadkeys -u " + keymap (see bug 44223)
-
- // X11 command...
- // do not try to run this with remote X display
- if (size (Apply) >0 && x11_setup_needed ())
- {
- xkb_cmd = XVersion::binPath () + "/setxkbmap " + Apply;
- }
- else
- {
- xkb_cmd = "";
- }
-
- // Store keyboard just set.
- //
- current_kbd = keyboard;
-
- // On first assignment store default keyboard.
- //
- if ( default_kbd == "" ) // not yet assigned
- {
- default_kbd = current_kbd;
- }
-
- return true; // OK
- } // SetLanguage()
-
-
- /**
- * Restore()
- *
- * Restore the the data from sysconfig.
- *
- * @return true - Data could be restored
- * false - Restore not successful
- *
- * @see Save()
- */
- global define boolean Restore () {
-
- boolean ret = false;
- restore_called = true;
- GetKbdSysconfig();
-
- if (!Stage::initial ())
- {
- // Read YaST2 keyboard var.
- //
- current_kbd = Misc::SysconfigRead(.sysconfig.keyboard.YAST_KEYBOARD,"");
- integer pos = find (current_kbd, ",");
- if (pos != nil && pos > 0)
- {
- kb_model = substring (current_kbd, pos + 1);
- current_kbd = substring (current_kbd, 0, pos);
- }
-
- y2milestone ("current_kbd %1 model %2", current_kbd, kb_model);
- if (current_kbd == "")
- {
- y2milestone("Restoring data failed");
- ret = false;
- }
- else
- {
- if (!Mode::config ())
- {
- // Restore module data.
- //
- SetLanguage( current_kbd );
- y2milestone("Restored data (sysconfig) for keyboard: <%1>",current_kbd);
- }
- else
- {
- // for cloning, to be shown in Summary
- name = GetKeyboardName (current_kbd);
- }
-
- ret = true;
- }
- }
- else
- {
- ret = true;
- }
- return ret;
- } // Restore()
-
- /*
- * get_xkblayout2keyboard()
- *
- * Get the xkblayout --> keyboard_language conversion map.
- *
- * @return conversion map
- *
- * @see get_lang2keyboard()
- */
-
- define map get_xkblayout2keyboard()
- ``{
- // The xkblayout --> keyboard_language conversion map.
- //
- map xkblayout2keyboard = (map)SCR::Read( .target.yast2,
- "xkblayout2keyboard.ycp" );
-
- if ( xkblayout2keyboard == nil ) xkblayout2keyboard = $[];
-
- return( xkblayout2keyboard );
- } // get_xkblayout2keyboard()
-
-
- /**
- * XkblayoutToKeyboard()
- *
- * Convert X11 keyboard layout name to yast2 name for keyboard description.
- * e.g. "de" --> "german"
- *
- * @param string x11_layout
- *
- * @return string yast2 name for keyboard description
- */
-
- define string XkblayoutToKeyboard( string x11_layout )
- ``{
- map xkblayout2keyboard = get_xkblayout2keyboard();
-
- // Now get the YaST2 internal representation of this keyboard layout.
- //
- string ret = xkblayout2keyboard[x11_layout]:"";
- y2milestone(" XkblayoutToKeyboard x11:%1 ret:%2", x11_layout, ret );
- return( ret );
- }
-
- /**
- * Probe keyboard and set local module data.
- */
-
- define void probe_settings()
- ``{
- /*
- * First assign the kb_model. This is e.g. "pc104".
- * Aside from being used directly for writing the XF86Config file this is later on
- * used to search the YaST2 keyboards database (it's a key in a map).
- */
-
- // Probe the keyboard.
- //
- if (!Mode::config ())
- {
- keyboardprobelist = (list)SCR::Read( .probe.keyboard );
-
- y2milestone("Probed keyboard: <%1>", keyboardprobelist );
-
- // Get the first keyboard from the list (it should exist).
- //
- map keyboardmap1 = keyboardprobelist[0]:$[];
-
- // Get the unique_key
- //
- unique_key = keyboardmap1["unique_key"]:"";
-
- // Get the keyboard data for this first keyboard.
- //
- map keyboardmap2 = keyboardmap1["keyboard", 0]:$[];
-
- // Assign the XkbModel.
- //
- kb_model = keyboardmap2["xkbmodel"]:"pc104";
-
- y2milestone("kb_model: <%1>", kb_model );
-
- // Assign the XkbLayout.
- // Only some keyboards do report this information (e.g. sparc).
- //
- XkbLayout = keyboardmap2["xkblayout"]:"";
-
- y2milestone("Xkblayout: <%1>", XkbLayout );
- }
- else
- {
- kb_model = "pc104";
- }
-
- return;
- }; // probe_settings()
-
- /**
- * Probe()
- *
- * Allow for intentional probing by applications.
- *
- * @see Keyboard()
- */
- global define void Probe() {
-
- y2milestone( "Keyboard::Probe" );
- probe_settings();
-
- // Set the module to the current system language to achieve a consistent
- // state. This may be superfluous because a client may do it also but
- // just in case...
- //
- string default_keyboard = "";
-
- // Some keyboards (i.e. sparc) report their layout, try to use this information here
- //
- if( XkbLayout != "" ) // we do have hardware info
- {
- default_keyboard = GetKeyboardForLanguage( XkbLayout, default_keyboard);
- }
- else // no hardware info ==> select default keyboard dependent on system language
- {
- default_keyboard = GetKeyboardForLanguage( Language::language, "english-us" );
- }
-
- // Set the module state.
- //
- SetLanguage( default_keyboard );
-
- if (Stage::initial ())
- {
- string keytable = Linuxrc::InstallInf ("Keytable");
- // set the keyboard from linuxrc
- if (keytable != nil)
- {
- y2milestone ("linuxrc keyboard: %1", keytable);
- map map2yast = (map) union (keymap2yast (), $[
- "dk" : "danish",
- "de-lat1-nd" : "german",
- ]);
- if (issubstring (keytable, ".map.gz"))
- keytable = substring (keytable, 0, find (keytable, ".map.gz"));
- if (map2yast[keytable]:"" != "")
- {
- Set (map2yast[keytable]:"");
- // do not reset it in proposal
- user_decision = true;
- }
- }
- // set keyboard now (before proposal - see bug #113664)
- else if (Language::preselected != "en_US")
- {
- y2milestone ("language (%1) was preselected -> setting keyboard to %2",
- Language::preselected, default_keyboard);
- Set (default_keyboard);
- }
- }
- y2milestone( "End Probe %1", default_keyboard );
- } // Probe()
-
-
- /**
- * Keyboard()
- *
- * The module constructor.
- * Sets the proprietary module data defined globally for public access.
- * This is done only once (and automatically) when the module is loaded for the first time.
- *
- * @see Probe()
- */
- global define void Keyboard() {
-
- if (Mode::config ())
- return;
-
- // We have three possible sources of information:
- //
- // Newly probed data: - installation initial mode --> probing
- // sysconfig: - installation continue mode or normal mode
- // XF86Config: - restoring from sysconfig failed and running system
- //
- y2milestone( "Keyboard::Keyboard init:%1 update:%2", Stage::initial (),
- Mode::update () );
- boolean success = false;
-
- // If not in initial mode try to restore from sysconfig.
- //
- if (!Stage::initial ())
- {
- success = Restore();
-
- // If this failed and we are in a running system try to restore from XF86Config.
- //
- if (!success && Mode::normal () && x11_setup_needed ())
- {
- // Get the current layout from XF86Config and
- // set keyboard module accordingly.
-
- string current_layout = XLibAPI::getXkbLayout ();
-
- y2milestone("keyboard layout YaST2: %1", current_layout );
-
- // Set the keyboard variables to this value if possible.
- //
- if ( current_layout != "" )
- {
- SetLanguage( current_layout );
- y2milestone("Restored data (XF86Config) for keyboard: <%1>", current_kbd );
- success = true;
- }
- }
- }
- else
- {
- GetKbdSysconfig();
- }
-
- // In initial mode or if restoring failed do probe.
- //
- if( Stage::initial () || !success ) // initial mode or no restore success
- {
- // On module entry probe the hardware and set all those data
- // needed for public access.
- //
- Probe();
- }
-
- return;
- } // Keyboard()
-
- /**
- * Just store inital values - read was done in constructor
- */
- global define boolean Read () {
-
- keyboard_on_entry = current_kbd;
- expert_on_entry = GetExpertValues ();
- ExpertSettingsChanged = false;
- y2debug ("keyboard_on_entry: %1", keyboard_on_entry);
- return true;
- }
-
- /**
- * was anything modified?
- */
- global define boolean Modified () {
- return (current_kbd != keyboard_on_entry || ExpertSettingsChanged);
- }
-
-
- /**
- * Updates the X11 keyboard settings (using SaX library)
- * @return boolean - success
- */
-
- global define boolean xf86_update() {
-
- y2milestone ("Storing current keyboard settings into X11 config file...");
-
- map xkbctrl2SaX = $[
- "ModeShift" : "SaX::XKB_MAP_MODESHIFT",
- "Compose" : "SaX::XKB_MAP_COMPOSE",
- "ModeLock" : "SaX::XKB_MAP_MODELOCK",
- "ScrollLock" : "SaX::XKB_MAP_SCROLLLOCK",
- "Meta" : "SaX::XKB_MAP_META",
- "Control" : "SaX::XKB_MAP_CONTROL"
- ];
-
- XLibAPI::setXkbLayout (XkbLayout);
- XLibAPI::setXkbModel (XkbModel);
- XLibAPI::setXkbVariant (XkbLayout, XkbVariant);
- XLibAPI::setXkbMappings ($[
- "SaX::XKB_LEFT_ALT" : xkbctrl2SaX[LeftAlt]:LeftAlt,
- "SaX::XKB_RIGHT_ALT" : xkbctrl2SaX[RightAlt]:RightAlt,
- "SaX::XKB_SCROLL_LOCK" : xkbctrl2SaX[ScrollLock]:ScrollLock,
- "SaX::XKB_RIGHT_CTL" : xkbctrl2SaX[RightCtl]:RightCtl
- ]);
- if (XkbOptions != "")
- XLibAPI::setXkbOptions (splitstring (XkbOptions, ","));
- return XLibAPI::Write ();
- }
-
-
- /**
- * Save the current data into a file to be read after a reboot.
- *
- * @param boolean update_x11: true if X11 config should be updated
- */
- global define void Save (boolean update_x11) {
-
- if (Mode::update ())
- {
- string kbd = Misc::SysconfigRead (.sysconfig.keyboard.YAST_KEYBOARD,"");
- if (size(kbd)==0)
- {
- string kmap = Misc::SysconfigRead(.sysconfig.keyboard.KEYTABLE, "");
- if (size(kmap)>0)
- {
- map data = GetX11KeyData( kmap );
- if (size(data["XkbLayout"]:"")>0)
- {
- kbd = XkblayoutToKeyboard( data["XkbLayout"]:"" );
- kbd = kbd + "," + data["XkbModel"]:"pc104";
- SCR::Write (.sysconfig.keyboard.YAST_KEYBOARD, kbd );
- SCR::Write (.sysconfig.keyboard.YAST_KEYBOARD.comment,
- "\n# The YaST-internal identifier of the attached keyboard.\n#\n");
- SCR::Write (.sysconfig.keyboard, nil ); // flush
- }
- }
- }
- return;
- }
-
- // Write some sysconfig variables.
- // Set keytable, compose_table and tty list.
- //
- SCR::Write(.sysconfig.keyboard.YAST_KEYBOARD, current_kbd+","+kb_model );
- SCR::Write(.sysconfig.keyboard.YAST_KEYBOARD.comment,
- "\n# The YaST-internal identifier of the attached keyboard.\n#\n");
-
- SCR::Write(.sysconfig.keyboard.KEYTABLE, keymap );
- SCR::Write(.sysconfig.keyboard.COMPOSETABLE, compose_table );
- SCR::Write(.sysconfig.keyboard.KBD_TTY, kbd_tty );
- SCR::Write(.sysconfig.keyboard.KBD_RATE, kbd_rate );
- SCR::Write(.sysconfig.keyboard.KBD_DELAY, kbd_delay );
- SCR::Write(.sysconfig.keyboard.KBD_NUMLOCK, kbd_numlock );
- SCR::Write(.sysconfig.keyboard.KBD_CAPSLOCK, kbd_capslock );
- SCR::Write(.sysconfig.keyboard.KBD_SCRLOCK, kbd_scrlock );
- SCR::Write(.sysconfig.keyboard.KBD_DISABLE_CAPS_LOCK, kbd_disable_capslock);
- SCR::Write(.sysconfig.keyboard, nil ); // flush
-
- // As a preliminary step mark all keyboards except the one to be configured
- // as configured = no and needed = no. Afterwards this one keyboard will be
- // marked as configured = yes and needed = yes. This has to be done to
- // prevent any problems that may occur if the user plugs in and out different
- // keyboards or if a keyboard is selected from the database despite the fact
- // that a keyboard has been probed. Otherwise the config popup may nag the user
- // again and again.
- //
- // In order to get a list of *ALL* keyboards that have ever been conected to
- // the system we must do a *manual* probing (accessing the libhd database).
- // Doing only a "normal" probing would deliver only the *currently* attached
- // keyboards which in turn would not allow to "unmark" all keyboards that may
- // have been removed.
- //
- // Do *NOT* use probe_settings() here because this would newly assign the global
- // "unique_key" which is not what we want here. It may have been cleared
- // intentionally due to the users selection of a keyboard from the YaST database.
- // Furthermore this would assign a unique_key even if there is no keyboard attached
- // (if there _was_ a keyboard attached).
- //
- // Manual probing
- keyboardprobelist = (list)SCR::Read(.probe.keyboard.manual);
-
- integer list_size = size( keyboardprobelist );
-
- if (list_size > 0)
- {
- integer i = 0;
-
- while ( i < list_size ) // Loop over all keyboards
- {
- map current_keyboard = keyboardprobelist[i]:$[];
- string current_key = current_keyboard["unique_key"]:"";
-
- if ( current_key != "" )
- {
- // OK, there is a key to mark...
- //
- if ( current_key != unique_key )
- {
- // OK, this key is _not_ the key of the keyboard to be configured.
- // If the user selected a keyboard from the database Keyboard::unique_key
- // has been set to "" there which also applies here.
- // ==> Mark with "no".
- //
- SCR::Write( .probe.status.configured, current_key, `no );
- y2milestone("Marked keyboard <%1> as configured = no", current_key );
-
- SCR::Write( .probe.status.needed, current_key, `no );
- y2milestone("Marked keyboard <%1> as needed = no", current_key );
- }
- else
- {
- y2milestone("Skipping active key <%1> --> to be configured", current_key );
- }
- }
-
- i = i + 1; // next keyboard
- }
- }
- else
- {
- y2milestone("No probed keyboards. Not unconfiguring any keyboards");
- }
-
- // Only if the keyboard has been probed in this run the unique_key
- // is not empty. Only in this case mark the device as "configured".
- // In any other case the device should already be configured and
- // the marking can't be done because the unique_key is missing.
- // ==> Only mark after probing!
- //
- if( unique_key != "" )
- {
- SCR::Write( .probe.status.configured, unique_key, `yes );
- y2milestone("Marked keyboard <%1> as configured", unique_key );
-
- if( ! Linuxrc::serial_console () )
- {
- SCR::Write( .probe.status.needed, unique_key, `yes );
- y2milestone("Marked keyboard <%1> as needed", unique_key );
- }
- }
- else
- {
- y2milestone("NOT marking keyboard as configured (no unique_key)");
- }
-
- // Adapt the X11 config file content to match the current settings
- if (x11_setup_needed() && update_x11 &&(Mode::normal() || Stage::reprobe()))
- {
- xf86_update();
- }
-
- y2milestone("Saved data for keyboard: <%1>", current_kbd );
-
- return;
- } // Save()
-
-
- /**
- * Name()
- * Just return the keyboard name, without setting anything.
- * @return string user readable description.
- */
-
- global define string Name() {
- return name;
- }
-
- /**
- * Set the console keyboard to the given keyboard language.
- *
- * @param Keyboard language e.g. "english-us"
- *
- * @return The loadkeys command that has been executed to do it.
- * (also stored in Keyboard::ckb_cmd)
- */
- global define string SetConsole (string keyboard) {
-
- if (Mode::test ())
- {
- y2milestone("Test mode - NOT setting keyboard" );
- }
- else if (Arch::board_iseries () || Arch::s390())// workaround for bug #39025
- {
- y2milestone ("not calling loadkeys on iseries");
- }
- else
- {
- SetLanguage (keyboard); // (retranslation)
-
- y2milestone("Setting console keyboard to: <%1>", current_kbd );
- y2milestone("loadkeys command: <%1>", ckb_cmd );
-
- SCR::Execute (.target.bash, ckb_cmd);
- UI::SetKeyboard ();
- }
- return ckb_cmd;
- }; // SetConsole()
-
-
-
- /**
- * Set the X11 keyboard to the given keyboard language.
- *
- * @param Keyboard language e.g. "english-us"
- *
- * @return The xkbset command that has been executed to do it.
- * (also stored in Keyboard::xkb_cmd)
- */
- global define string SetX11 (string keyboard) {
-
- if (Mode::test ())
- {
- y2milestone ("Test mode - would have called:\n %1", xkb_cmd);
- }
- else
- {
- // Actually do it only if we are in graphical mode.
- //
- boolean textmode = Linuxrc::text ();
- if (!Stage::initial ())
- {
- map display_info = UI::GetDisplayInfo ();
- textmode = display_info["TextMode"]:false;
- }
- if (textmode)
- {
- y2milestone("Not setting X keyboard due to text mode");
- }
- else if (size (xkb_cmd)>0)
- {
- SetLanguage (keyboard); // (retranslation)
- y2milestone ("Setting X11 keyboard to: <%1>", current_kbd );
- y2milestone ("Setting X11 keyboard:\n %1", xkb_cmd );
- SCR::Execute (.target.bash, xkb_cmd);
- }
- }
- return xkb_cmd;
- }; // SetX11()
-
-
-
- /**
- * Set()
- *
- * Set the keyboard to the given keyboard language.
- *
- * @param Keyboard language e.g. "english-us"
- *
- * @return void
- *
- * @see SetX11(), SetConsole()
- */
-
- global define void Set (string keyboard) {
-
- y2milestone ("set to %1", keyboard);
- if (Mode::config ())
- {
- current_kbd = keyboard;
- name = GetKeyboardName (current_kbd);
- return;
- }
-
- SetConsole (keyboard);
- SetX11 (keyboard);
- if (Stage::initial ())
- {
- map yinf = $[];
- AsciiFile::SetDelimiter( yinf, " " );
- AsciiFile::ReadFile( yinf, "/etc/yast.inf" );
- list lines = AsciiFile::FindLineField( yinf, 0, "Keytable:" );
- if( size(lines)>0 )
- AsciiFile::ChangeLineField( yinf, lines[0]:-1, 1, keymap );
- else
- AsciiFile::AppendLine( yinf, ["Keytable:", keymap] );
- AsciiFile::RewriteFile( yinf, "/etc/yast.inf" );
- }
- }
-
-
- /**
- * MakeProposal()
- *
- * Return proposal string and set system keyboard.
- *
- * @param boolean force_reset
- * boolean language_changed
- *
- * @return string user readable description.
- * If force_reset is true reset the module to the keyboard
- * stored in default_kbd.
- */
-
- global define string MakeProposal (boolean force_reset,boolean language_changed)
- {
- y2milestone("force_reset: %1", force_reset);
- y2milestone("language_changed: %1", language_changed);
-
- if (force_reset)
- {
- // If user wants to reset do it if a default is available.
- if (default_kbd != "")
- {
- Set (default_kbd); // reset
- }
-
- // Reset user_decision flag.
- user_decision = false;
- restore_called = false;
- }
- else // no reset
- {
- // Only follow the language if the user has never actively chosen
- // a keyboard. The indicator for this is user_decision which is
- // set from outside the module.
- if (user_decision ||
- (Mode::update () && !Stage::initial ()) ||
- Mode::autoinst () ||
- ProductFeatures::GetStringFeature ("globals", "keyboard") != "")
- {
- if (language_changed)
- {
- y2milestone("User has chosen a keyboard; not following language - only retranslation.");
-
- Set (current_kbd);
- }
- }
- else
- {
- // User has not yet chosen a keyboard ==> follow language.
- string local_kbd =
- GetKeyboardForLanguage ( Language::language, "english-us" );
- if (local_kbd != "")
- {
- Set (local_kbd);
- }
- else if (language_changed)
- {
- y2error ("Can't follow language - only retranslation");
- Set (current_kbd);
- }
- }
- }
- return name;
- } // MakeProposal()
-
-
- /**
- * CalledRestore()
- *
- * Return if the kbd values have already been read from
- * /etc/sysconfig/keyboard
- *
- */
- global define boolean CalledRestore() {
- return( restore_called );
- };
-
- /**
- * Selection()
- *
- * Get the map of translated keyboard names.
- *
- * @return map of $[ keyboard_code : keyboard_name, ...] for all known
- * keyboards. 'keyboard_code' is used internally in Set and Get
- * functions. 'keyboard_name' is a user-readable string.
- *
- */
- global define map<string, string> Selection() {
- // Get the reduced keyboard DB.
- //
- map<string, list> keyboards = get_reduced_keyboard_db();
- locale translate = "";
- string trans_str = "";
-
- return mapmap( string keyboard_code, list keyboard_value, keyboards,
- ``{
- translate = keyboard_value[0]:"";
- trans_str = (string)eval(translate);
- return $[ keyboard_code: trans_str ];
- });
- }
-
-
-
- /**
- * SetExpertValues()
- *
- * Set the values of the various expert setting
- *
- * @param val map with new values of expert settings
- */
- global define void SetExpertValues( map val ) {
-
- map orig_values = GetExpertValues ();
-
- if( haskey(val,"rate") && size(val["rate"]:"")>0 )
- {
- kbd_rate = val["rate"]:"";
- }
- if( haskey(val,"delay") && size(val["delay"]:"")>0 )
- {
- kbd_delay = val["delay"]:"";
- }
- if( haskey(val,"numlock") )
- {
- kbd_numlock = val["numlock"]:"";
- }
- if( haskey(val,"capslock") )
- {
- kbd_capslock = (val["capslock"]:false) ? "yes" : "no";
- }
- if( haskey(val,"scrlock") )
- {
- kbd_scrlock = (val["scrlock"]:false) ? "yes" : "no";
- }
- if( haskey(val,"tty") && size(val["tty"]:"")>0 )
- {
- kbd_tty = val["tty"]:"";
- }
- if( haskey(val,"discaps") )
- {
- kbd_disable_capslock = (val["discaps"]:false) ? "yes" : "no";
- }
-
- if (!ExpertSettingsChanged && orig_values != GetExpertValues ())
- ExpertSettingsChanged = true;
- }
-
- // set the keayboard layout according to given language
- global define void SetKeyboardForLanguage (string lang) {
-
- string lkbd = GetKeyboardForLanguage (lang, "english-us");
- y2milestone ("language %1 proposed keyboard %2", lang, lkbd);
- if (lkbd != "")
- {
- Set( lkbd );
- }
- };
-
- global define void SetKeyboardForLang (string lang) {
- return SetKeyboardForLanguage (lang);
- }
-
- global define void SetKeyboardDefault() {
-
- y2milestone( "SetKeyboardDefault to %1", current_kbd );
- default_kbd = current_kbd;
- };
-
-
- /**
- * Special function for update mode only.
- * Checks for the keyboard layout on the system which should be updated and if it
- * differs from current one, opens a popup with the offer to change the layout.
- * See discussion in bug #71069
- * @param destdir path to the mounted system to update (e.g. "/mnt")
- */
- global define void CheckKeyboardDuringUpdate (string destdir) {
-
- string target_kbd = Misc::CustomSysconfigRead (
- "YAST_KEYBOARD", current_kbd, destdir + "/etc/sysconfig/keyboard");
- integer pos = find (target_kbd, ",");
- if (pos != nil && pos > 0)
- {
- target_kbd = substring (target_kbd, 0, pos);
- }
-
- map keyboards = get_reduced_keyboard_db();
-
- if (target_kbd != current_kbd && keyboards[target_kbd]:[] != [])
- {
- y2milestone ("current_kbd: %1, target_kbd: %2", current_kbd, target_kbd);
-
- string target_name = GetKeyboardName (target_kbd);
-
- UI::OpenDialog(`opt(`decorated), `HBox(`HSpacing(1.5),
- `VBox(
- `HSpacing(40),
- `VSpacing(0.5),
- // label text: user can choose the keyboard from the updated system
- // or continue with the one defined by his language.
- // 2 radio-buttons follow this label.
- // Such keyboard layout is used only for the time of the update,
- // it is not saved to the system.
- `Left (`Label (_("You are currently using a keyboard layout
- different from the one in the system to update.
- Select the layout to use during update:"))),
- `VSpacing(0.5),
- `RadioButtonGroup (`VBox (
- `Left (`RadioButton (`id (`current), name)),
- `Left (`RadioButton (`id (`target), target_name, true))
- )),
- `VSpacing(0.5),
- `HBox(
- `PushButton(`id(`ok),`opt(`default,`key_F10), Label::OKButton()),
- `PushButton(`id(`cancel), `opt(`key_F9), Label::CancelButton())
- ),
- `VSpacing(0.5)),
- `HSpacing(1.5)
- ));
- any ret = UI::UserInput();
-
- if (ret == `ok && (boolean) UI::QueryWidget (`id(`target), `Value))
- {
- Set (target_kbd);
- user_decision = true;
- }
-
- UI::CloseDialog();
- }
- }
-
- /**
- * AutoYaST interface function: Get the Keyboard configuration from a map.
- * @param settings imported map
- * @return success
- */
- global define boolean Import (map settings) {
-
- // Read was not called -> do the init
- if (expert_on_entry == $[])
- Read ();
-
- Set (settings["keymap"]:current_kbd);
- SetExpertValues (settings["keyboard_values"]:$[]);
- return true;
- }
-
- /**
- * AutoYaST interface function: Return the Keyboard configuration as a map.
- * @return map with the settings
- */
- global define map Export () {
-
- map diff_values = $[];
- foreach (string key, any val, (map<string,any>) GetExpertValues (), {
- if (expert_on_entry[key]:nil != val)
- diff_values[key] = val;
- });
- map ret = $[
- "keymap" : current_kbd,
- ];
- if (diff_values != $[])
- ret["keyboard_values"] = diff_values;
- return ret;
- }
-
- /**
- * AutoYaST interface function: Return the summary of Keyboard configuration as a map.
- * @return summary string (html)
- */
- global define string Summary () {
-
- import "HTML";
-
- list<string> ret = [
- // summary label
- sformat (_("Current Keyboard Layout: %1"), name)
- ];
- return HTML::List (ret);
- }
-
-
- } // - EOF -
-