home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
modules
/
Keyboard.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
41KB
|
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 -