home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2000-03-30 | 49.2 KB | 1,721 lines
/** * * $Id: sound.ycp,v 1.59.4.2 2000/03/24 10:51:55 gs Exp $ * * Module: sound.ycp * * Author: Dan VeselĀ² * * * Purpose: Installation of the sound card. If the sound card was not auto-detected ask user. * * * user_settings: * * ro: "audio_file" full path to "au" audio file for testing * ro: "conf_modules" full path to "/etc/conf.modules" file ("/etc/modules.conf") * ro: "snd-pcm-oss" name of Alsa module for OSS compatibility (in older versions "snd-pcm1-oss") * ro: "snd_index" first number of snd_index option (alsa 0.4.0 == 1; alsa 0.5.1 == 0) * * "rw" read/write * "ro" readonly * */ { // Menuentry for the YaST2 menu if (Args() == [ "get_menuentry" ]) return [ "sound", $[ `menuentry : UI(_("Hardware/Sound")), `arguments : [ ], `widget : `RichText( UI(_("Launch this module to configure your sound card.")) + UI(_("<p>You need to be logged in as <i>root</i> in order to do this.</p>"))), `codefragment : nil ] ]; map user_settings = $["audio_file" : "/usr/share/sounds/alsa/whistle.au", "conf_modules" : "/etc/modules.conf", "snd-pcm-oss" : "snd-pcm-oss", "snd_index" : 0]; SCR(``{ // reads/writes lines from file, deletes blank lines MountAgent (`anyagent( ``Description ( ``File("/etc/modules.conf"), // real file name "\n", // Comment false, // read-only ``List ( String ("^\n"), "\n" ) ) ), .lines); }); UI(``{ // The main dialog. Copied from installation.ycp. OpenDialog(`opt(`defaultsize), `VBox(`Image(`suseheader, "SuSE"), `HBox(`HWeight(30, `RichText(`id(`help), "")), `HWeight(70, `VBox( `Left(`Heading(`id(`title), _("YaST2\nInitializing ..."))), `HVCenter(`ReplacePoint(`id(`contents), `Empty())), `HBox( // back pushbutton: the user input is ignored and the last dialog is called `PushButton(`id(`back), `opt(`disabled), _("&Back")), `HStretch(), // next pushbutton: the user input is checked and the next dialog is called `PushButton(`id(`next), `opt(`disabled), _("&Next")))))))); define SetContents(string title, term contents, string helptext, boolean has_back, boolean has_next) ``{ ChangeWidget(`id(`next), `Enabled, has_next); ChangeWidget(`id(`back), `Enabled, has_back); ChangeWidget(`id(`help), `Value, helptext); ChangeWidget(`id(`title), `Value, title); ReplaceWidget(`id(`contents), contents); // ControlWidget(TheWizardDialog(), `id(`next), `SetFocus()); }; // This is a popup dialog for displaying (usually) error messages define DisplayMessage(string message, integer code, string stack) ``{ // ok pushbutton: confirm the dialog term t = `VBox(); t = add(t, `Left(`Label(message))); if (code != 0) // optional warning dialog text t = add(t, `Left(`Label(sformat(_("Error code %1"), code)))); if (stack != "") t = add(t, `Left(`Label(stack))); OpenDialog(`opt(`decorated), add(t, `PushButton(_("&OK")))); UserInput(); CloseDialog(); }; // This is a popup dialog with Yes/No question define DisplayYesNo(string message) ``{ term t = `VBox(); t = add(t, `Left(`Label(message))); term b = `HBox ( `PushButton(`id(`yes), _("&Yes")), `PushButton(`id(`no), `opt (`default), _("&No")) ); OpenDialog(`opt(`decorated), add(t, b)); any ret = UserInput(); CloseDialog(); if (ret == `yes) return 1; else return 0; //return (ret == `yes); }; }); // creates list [`item (`id(0), <element>), `item (`id (1), <element>), ...] where sel is marked with true // these items are usable in the selection boxes define index_list (list l, integer sel) ``{ integer i = 0; list new_l = []; integer s = size (l); while (i < s) { new_l = add (new_l,`item (`id(i), select (l, i), (i == sel))); i = i + 1; } return new_l; }; // contatenates two lists (both contains strings) this way: // creates new list, where the item concatenation of string contained in the lists // these list should be the same length define concat_list (list l1, list l2) ``{ integer i = 0; list new_l = []; integer s = size (l1); string des = ""; while (i < s) { des = (select (l1, i) + select (l2, i)); new_l = add (new_l,`item (`id(i), des, (i == 0))); i = i + 1; } return new_l; }; // creates new list from list l // but cards with the same device/vendor id are added just once define remove_duplicates (list l) ``{ list n = []; foreach (`c, l, ``{ integer vid = lookup (c, "vendor_id"); integer did = lookup (c, "device_id"); boolean to_add = true; foreach (`nc, n, ``{ if ((lookup (nc, "device_id") == did) && (lookup (nc, "vendor_id") == vid)) to_add = false; }); if (to_add) n = add (n, c); }); return n; }; // sets the volume, with amixer check // if an error occurs popup error is displayed define set_volume (integer v) ``{ integer ret = Shell ("/usr/bin/amixer set Master $VOL unmute", $["VOL" : v]); if (ret == 127){ // To translators: This is just popup message, shouldn't be too long UI (`DisplayMessage (_("Cannot find program 'amixer'"), 0, // To translators: This is just popup message, shouldn't be too long _("Please install the package 'ALSA' from the 'snd' series"))); } return ret; }; // converts hex num to integer // keeps decimal number as is define hextoi (string num) ``{ if (filterchars (num, "0123456789") == num) return tointeger (num); if (tolower(substring (num, 0, 2)) != "0x") return 0; integer ret = 0; integer pos = size (num) - 1; integer times = 1; while (pos > 1) { string num_char = tolower (substring (num, pos, 1)); if (num_char == "f") ret = ret + 15 * times; else if (num_char == "e") ret = ret + 14 * times; else if (num_char == "d") ret = ret + 13 * times; else if (num_char == "c") ret = ret + 12 * times; else if (num_char == "b") ret = ret + 11 * times; else if (num_char == "a") ret = ret + 10 * times; else ret = ret + tointeger (num_char) * times; times = times * 16; pos = pos - 1; } return ret; }; // tries to extract list of values from description // these value are generated from alsa modules // and can be in form // [list=value,value,..] or // [range=1-19] or something not // recognized define get_values (string des) ``{ list ret = []; integer pos = 0; integer len = size (des); while ((pos < len) && (substring (des, pos, 1) != "[")) { pos = pos + 1; } pos = pos + 1; if (pos < len) { // found "[" if (tolower(substring (des, pos, 5)) == "list=") { pos = pos + 5; integer s = pos; while ((pos < len) && substring (des, pos, 1) != "]") { if (substring (des, pos, 1) == ",") { ret = add (ret, hextoi (substring (des, s, pos - s))); s = pos + 1; } pos = pos + 1; } ret = add (ret, hextoi (substring (des, s, pos - s))); } else if (tolower(substring (des, pos, 6)) == "range=") { pos = pos + 6; integer s = pos; integer range_start = 0; while ((pos < len) && substring (des, pos, 1) != "]") { if (substring (des, pos, 1) == "-") { range_start = tointeger(substring (des, s, pos - s)); s = pos + 1; } pos = pos + 1; } integer range_stop = tointeger(substring (des, s, pos - s)); // now create the range list while (range_start <= range_stop) { ret = add (ret, range_start); range_start = range_start + 1; } } else if (tolower(substring (des, pos, 4)) == "bool") { ret = [0, 1]; } } return ret; }; // this dialog is displayed, when its // not possible to remove some alsa // modules, it happens, when user not // a root or the modules are used define CanNotReset () ``{ map after = SCR(`Read(.proc.modules)); string not_removed = ""; foreach (`k, `v, after, ``{ string temp = substring (k, 0, 3); if (temp == "snd") { // this is alsa module not_removed = not_removed + k + "\n"; } }); if (haskey (after, "soundcore")) not_removed = not_removed + "soundcore" + "\n"; if (size (not_removed) > 0) { string msg = ""; if (size (not_removed) > 1) // To translators: This is just popup message, shouldn't be too long msg = sformat (UI(_("Cannot remove modules:\n%1")), not_removed); else // To translators: This is just popup message, shouldn't be too long msg = sformat (UI(_("Cannot remove module:\n%1")), not_removed); UI (`DisplayMessage (msg, 0, // To translators: This is just popup message, shouldn't be too long _("Please check that you are logged in as root and\n no sound programs (i.e. players, mixers, etc...) are running "))); } }; // this routine tests if the ALSA // package is installed, it is // necessary to have installed this // package in order to continue with // the configuration define IsAlsaInstalled () ``{ integer ret = Shell ("/bin/rpm -q alsa"); if (ret == 127) { // To translators: This is just popup message, shouldn't be too long UI (`DisplayMessage (_("Cannot execute the program \"rpm\"."), 0, // To translators: This is just popup message, shouldn't be too long _("Please check if the 'rpm' package from the series 'a1' is installed."))); } // if this package not installed, we have to use alsa au file if (Shell ("/bin/rpm -q snd_au") == 0) user_settings = add (user_settings, "audio_file", "/usr/share/sounds/au/linus-english.au"); return (ret == 0); }; // here the test sound is played, by // default ist alsa whistle sound, but // if snd_au package is installed, // than it's Linus Torvals voice, the // if the test file cannot be found, // the message is displayed define PlayTest () ``{ if ((Shell ("/bin/ls $FILE", $["FILE" : lookup (user_settings, "audio_file")]) != 0)) { string file = lookup (user_settings, "audio_file"); // To translators: just one file will be displayed // To translators: if the test audio file can not be found this message is displayed // To translators: This is just popup message, shouldn't be too long string msg = sformat (UI (_("Cannot find file:\n %1\n\n(test audio file)")), file); UI (`DisplayMessage (msg, 0, "")); } else Shell ("/bin/cat $AUDIO > /dev/audio &", $["AUDIO" : lookup (user_settings, "audio_file")]); }; // here we get some additional params // from isapnp // this function is NOT used now, // because too many isapnp options // vary too much define GetIsaParm (map cc) ``{ string ret = ""; /* if (lookup (cc, "cardtype", "") != "PnP") return ret; map cr = lookup (cc, "resource"); if (haskey (cr, "io")) ret = ret + " " + sformat ("snd_port=%1", lookup(select (lookup (cr, "io"), 0), "start")); if (haskey (cr, "irq")) ret = ret + " " + sformat ("snd_irq=%1", lookup(lookup (cr, "irq"), "irq")); if (haskey (cr, "dma")) { integer n = 1; foreach (`dma, lookup (cr, "dma"), ``{ ret = ret + " " + sformat ("snd_dma%1=%2", n, lookup(dma, "channel")); n = n + 1; }); } */ return ret; }; // Chooses one message according to // the language, used for translating // sndcard options define Trans (map|void msgs, string lang) ``{ string|void message = ""; if (msgs != nil) { message = lookup(msgs, lang); if (message == nil) message = lookup(msgs, "default"); if (message == nil) message = ""; // Everything has failed. } return message; }; // dialog for setting the options for // the sound card driver, now it uses // global cur_options_map and // cur_options for setting options for // a current_driver // It checks if the values entered by // the user are correct define OptionsSetup (map driver) ``{ // Help text for options 1/4 string help_text = UI(_("Here you can modify the options for the sound modules. ")); // Help text for options 2/4 help_text = help_text + UI(_("If you are not <b>absolutely sure</b> what are you doing, please leave this dialog untouched.")); // Help text for options 3/4 help_text = help_text + UI (_("<p>Choose the option you want to set and use the <i>Set</i> button to enable the new value. You can reset all values by pressing <i>Reset</i>. Number values can be entered as decimal or hexadecimal (hexadecimal with a <b>0x</b> prefix).</p> ")); // Help text for options 4/4 help_text = help_text + UI (_("Please refer to the <b>SuSE</b> help system, section 'package description', series 'snd', <b>alsa</b> package for more information.")); // This is unused ;-( //help_text = help_text + UI (_("Please refer to the <i>INSTALL</i> file in <small>/usr/doc/packages/alsa</small> directory for appropriate information about options for your card.")); any ret = nil; list params = lookup (driver, "params"); // these options are irelevant, // because just one card can be configured // at this time params = filter (`p, params, ``(lookup (p, "name") != "snd_index")); params = filter (`p, params, ``(lookup (p, "name") != "snd_id")); string language = UI(`GetLanguage()); list description = maplist (`p, params, ``(Trans(lookup (p, "description"), language))); list pname = maplist (`p, params, ``(lookup (p, "name"))); list types = maplist (`p, params, ``(lookup (p, "type"))); list possible_values = maplist (`p, params, ``(lookup (p, "values", ""))); map options = cur_options_map; integer n = 0; list index_description = concat_list (description, possible_values); string name = select (description, n); string desc = select (pname, n); term con = `VBox ( `Top(`Label (card_title)), `SelectionBox (`id(`op), `opt(`notify), "Options", index_description), `VBox ( `TextEntry (`id (`des), desc, lookup (options, desc, "")), `HBox ( // To translators: This is button label, shouldn't be too long `PushButton (`id (`set), `opt(`default), _("&Set")), // To translators: This is button label, shouldn't be too long `PushButton (`id (`reset), _("&Reset")) ) ) ); UI(`SetContents (_("Sound cards"), con, help_text, true, true)); repeat { ret = UI(`UserInput ()); if (ret == `op) { n = UI (`QueryWidget (`id(`op), `CurrentItem)); name = select (description, n); desc = select (pname, n); UI(`ChangeWidget(`id(`des), `Label, desc)); UI(`ChangeWidget(`id(`des), `Value, lookup (options, desc, ""))); } else if (ret == `set) { // set button pressed string value = UI(`QueryWidget(`id(`des), `Value)); if (select(types, n) == "int") { if (tolower(substring (value, 0, 2)) == "0x") { // hex number string rest = tolower(substring (value, 2)); if (filterchars(rest, "0123456789abcdef") != rest) { // To translators: This is a warning message, shouldn't be too long UI(`ChangeWidget(`id(`des), `Value, _("This value must be a number !!!"))); sleep(1000); UI(`ChangeWidget(`id(`des), `Value, "")); value = ""; } } else if (filterchars(value, "0123456789") != value) { // To translators: This is a warning message, shouldn't be too long UI(`ChangeWidget(`id(`des), `Value, _("This value must be a number !!!"))); sleep(1000); UI(`ChangeWidget(`id(`des), `Value, "")); value = ""; } if (false) { if (size (value) > 0) { // get possible values list possible_values = get_values (select (possible_values, n)); if (possible_values != []) { if (!contains (possible_values, hextoi (value))) { // // To translators: This is just popup message, shouldn't be too long string msg = sformat (UI(_("This value must be one of %1\nor its hexadecimal equivalent.")), possible_values); UI(`DisplayMessage (msg, 0, "")); UI(`ChangeWidget(`id(`des), `Value, "")); value = ""; } } } } } else { // string if (filterchars (tolower (value), "abcdefghijklmnopqrstuvwxyz_0123456789") != value) { integer wrong_pos = findfirstnotof (tolower (value), "abcdefghijklmnopqrstuvwxyz_0123456789"); string wrong_char = substring (value, wrong_pos, 1); if (wrong_char == " ") { // To translators: "space" means blank character wrong_char = wrong_char + " " + UI(_("(space)")); } // To translators: This is just popup message, shouldn't be too long string msg = sformat (UI(_("String cannot contain: %1")), wrong_char); UI(`DisplayMessage (msg, 0, "")); UI(`ChangeWidget(`id(`des), `Value, "")); value = ""; } if (size (value) > 8) { // To translators: This is just popup message, shouldn't be too long UI(`ChangeWidget(`id(`des), `Value, _("String too long (maximal lenght 8) !!!"))); sleep(1000); UI(`ChangeWidget(`id(`des), `Value, "")); value = ""; } } if (size (value) > 0) options = add (options, desc, value); } else if (ret == `reset) { options = $[]; UI(`ChangeWidget(`id(`des), `Value, "")); } } until ((ret == `back) || (ret == `next) || ret == `cancel); if (ret == `next) { map m = lookup (current_driver, "module"); string args = ""; foreach (`k, `v, options, ``{ // we DO!!! ignore empty options if (size (v) > 0) args = args + sformat ("%1=%2 ", k, v); }); current_options = args; cur_options_map = options; m = add (m, "args", args); m = add (m, "conf", args); current_driver = add (current_driver, "module", m); } return ret; }; // writes modules.conf, it makes a // backup and appends to the end of // modules.conf aliases and options // for the configured sound card define ConfModules (string file) ``{ // first comment out all lines containing snd|sound Shell ("/bin/cp -f $FILE $FILE.old; /usr/bin/sed 's/^\\([^#].*snd.*$\\|[^#].*sound.*$\\)/# \\1/' $FILE > /tmp/$FILE.sed; /bin/mv -f /tmp/$FILE.sed $FILE", $["FILE" : file]); list l = SCR(`Read(.lines)); if (l == nil) // To translators: just one file will be displayed return sformat (UI(_("Cannot find file: %1")), file); list newl = []; integer length = size (l); integer n = 0; string|void line = select (l, n); // read until ALSA section while ((line != nil) && (n < length) && (line != "# ALSA section {$#@begin@#$} [don't remove or move this line] vvvvv")) { newl = add (newl, line); line = select (l, n); n = n + 1; } // skip ALSA section while ((line != nil) && (n < length) && (line != "# ALSA section {$#@_end_@#$} [don't remove or move this line] ^^^^^")) { line = select (l, n); n = n + 1; } n = n + 1; if (n < length) line = select (l, n); // read the rest while ((line != nil) && (n < length)) { newl = add (newl, line); line = select (l, n); n = n + 1; } // and write configured card newl = add (newl, "# ALSA section {$#@begin@#$} [don't remove or move this line] vvvvv"); newl = add (newl, "#"); newl = add (newl, "# ALSA native device support, generated by YaST2"); newl = add (newl, "#"); newl = add (newl, "alias char-major-116 snd"); newl = add (newl, "options snd snd_major=116 snd_cards_limit=1"); newl = add (newl, sformat ("alias snd-card-0 %1", lookup (lookup(current_driver, "module"), "name"))); newl = add (newl, sformat ("options %1 snd_index=%2 snd_id=card1 %3 %4", lookup (lookup(current_driver, "module"), "name"), lookup (user_settings, "snd_index"), current_options, GetIsaParm (current_card) )); newl = add (newl, "#"); newl = add (newl, "# OSS/Free emulation"); newl = add (newl, "#"); newl = add (newl, "alias sound-slot-0 snd-card-0"); newl = add (newl, "alias sound-service-0-0 snd-mixer-oss"); newl = add (newl, "alias sound-service-0-1 snd-seq-oss"); newl = add (newl, sformat("alias sound-service-0-3 %1", lookup (user_settings, "snd-pcm-oss"))); newl = add (newl, "alias sound-service-0-8 snd-seq-oss"); newl = add (newl, sformat("alias sound-service-0-12 %1", lookup (user_settings, "snd-pcm-oss"))); newl = add (newl, "#"); newl = add (newl, "# ALSA section {$#@_end_@#$} [don't remove or move this line] ^^^^^"); if (SCR(`Write(.lines, newl)) != 0) // To translators: just one file will be displayed in instead parameter %1 return sformat (UI(_("Cannot write file: %1.\nThe sound will not be started after next reboot.\nThe sound is not configured well.")), file); }; // shortcuts for maplists define GetDrivers (list db) ``{ return maplist (`v, db, ``(lookup(v, "name"))); }; define GetCards (string|void mod, list db) ``{ if (mod == nil) return []; list|void mdl = filter (`s, db, ``(lookup (s, "name") == mod)); list c = []; if (mdl != []) { c = lookup (select (mdl, 0), "cards"); if (c == []) c = add (c, mod); } else // To translators: Name of 'unknown card', shouldn't be too long c = add (c, _("Unknown card")); return c; }; // main autodetection is done through // SCR and libhd define GetAudio () ``{ list ret = SCR(`Read(.probe.byclass.multimedia.audio)); ret = remove_duplicates (ret); return ret; }; define GetName (map cc) ``{ if (haskey (cc, "name")) return lookup (cc, "name"); return "Unknown module"; }; // lookups in the sndcards database // for card name, when gets bus, // device_id and vendor_id as parameters define GetCardName (string bus, integer vendor_id, integer device_id) ``{ // To translators: Name of 'unknown driver', shouldn't be too long string ret = UI (_("Unknown driver")); integer offset = 0; if (tolower (bus) == "pci") offset = 0x10000; else if (tolower (bus) == "isa") offset = 0x20000; else return ret; list|void fc = nil; if (tolower (bus) == "pci") fc = filter (`d, snd_database, ``(filter(`c, lookup (d, "libhd"), ``((lookup (c, "vendor_id") == vendor_id - offset) && (contains(lookup(c, "device_id"), device_id - offset)))) != [])); else { fc = filter (`d, snd_database, ``(filter(`c, lookup (d, "libhd"), ``((lookup (c, "vendor_id") == vendor_id - offset) && (lookup (c, "device_id") == device_id - offset))) != [])); } if (fc != nil) ret = lookup (select (fc, 0), "name"); return ret; }; // let's try modprobe, all is done // through SCR agents define ProbeModule () ``{ map module = $[]; module = lookup(current_driver, "module", $[]); if (size (module) == 0) // To translators: label message return sformat (UI(_("The appropriate module for the soundcard %1 could not be found.\n")), GetName (current_driver)); boolean mod_active = lookup (module, "active", false); // if we have some additional options string mod_parm = lookup(module, "name") + " " + current_options; mod_parm = mod_parm + " " + GetIsaParm (current_card); Shell("/sbin/depmod -a -F /boot/System.map-`uname -r` `uname -r`"); if (mod_active == false) { boolean probe = lookup (module, "modprobe", true); if (!probe) Shell("/sbin/insmod "+mod_parm); else Shell("/sbin/modprobe "+mod_parm); } mod_parm = lookup (user_settings, "snd-pcm-oss"); // this module is for compatibility with OSS Shell("/sbin/modprobe "+mod_parm); map pm = SCR(`Read(.proc.modules)); string ret = ""; if (haskey (pm, lookup (module, "name"))) module = add (module, "active", true); else // To translators: label message ret = sformat (UI(_("The kernel module %1 for sound support cannot be loaded.")), lookup (module, "name")); current_driver = add (current_driver, "module", module); return ret; }; define RemoveModule (string m) ``{ Shell ("/sbin/rmmod -r $MODULE", $["MODULE" : m]); }; define RemoveModules (list modules) ``{ foreach (`m, modules, ``{ RemoveModule (m); }); }; // quits all sound programs; if // someone want to reset the // configuration (remove the modules), // nothing using sound devices can be // running, popup dialog with // confirmation is displayed define QuitAllSoundPrograms () ``{ integer ret = Shell ("/bin/fuser /dev/dsp* /dev/audio* /dev/mixer* /dev/midi* /dev/mixer*"); if (ret == 0) { // To translators: To reset the sound configuration these programs must be terminated // To translators: label message string msg = UI (_("There are running programs using some audio device.\n")); // To translators: label message msg = msg + UI (_("To reset the configuration these programs will be terminated. Proceed?")); integer terminate = UI(`DisplayYesNo (msg)); if (terminate == 1) { Shell ("/bin/fuser -k /dev/dsp* /dev/audio* /dev/mixer* /dev/midi* /dev/mixer*"); } return terminate; } return 1; }; // tries to remove all loaded alsa modules define RemoveAllAlsaModules () ``{ map pm = SCR(`Read(.proc.modules)); string not_removed = ""; QuitAllSoundPrograms (); foreach (`k, `v, pm, ``{ string temp = substring (k, 0, 3); if (temp == "snd") { // this is alsa module Shell ("/sbin/rmmod -r $MODULE", $["MODULE" : k]); } }); Shell ("/sbin/rmmod -r $MODULE", $["MODULE" : "soundcore"]); /* */ }; // NOT used now define NotImplemented () ``{ UI(`SetContents (_("Sound cards"), `HVCenter ( // To translators: obsolete dialog, not used now `Label (_("Sorry, but this is not implemented yet!!!")) ), help_text, true, true)); return UI(`UserInput ()); }; // called when exists /proc/asound/cars // but with unreadable output define WrongOutput () ``{ // Help text, if an attempt for configuration failed 1/2 string help_text = UI (_("<p>The sound card does not function correctly although it has <b>previously</b> been configured. Possible causes are: 1. You have tried to configure the sound outside the <b>YaST2</b> and you were unsuccessful, 2. The card requires option values which you must enter manually. 3. You have passed incorrect options or optionvalues to the sound card module.</p> ")); // Help text, if an attempt for configuration failed 2/2 help_text = help_text + UI(_("<p>You can reset the configuration process by pressing the <i>Reset</i>button and try to configure the card again. Please refer to the <b>SuSE</b> system, section 'package description', series 'snd', <b>alsa</b>package for more information.</p> ")); // This is unused ;-( //Please refer to the <i>INSTALL</i> file in <i>/usr/doc/packages/alsa</i> directory for appropriate information about possibly required options for your card.</p>")); UI(`SetContents (_("Sound cards"), `HVCenter ( `ReplacePoint (`id(`wo), `VBox( // To translators: label message `Label (_("Incorrect sound configuration found.")), // To translators: button label `PushButton (`id (`reset), _("&Reset")) ) ) ), help_text, true, true)); any ret = nil; repeat { ret = UI(`UserInput ()); if (ret == `reset) { RemoveAllAlsaModules (); list|void r = nil; if ((Shell ("/bin/ls /proc/asound/cards")) == 0) r = SCR(`Read(.proc.asound.cards)); if (r != nil) { CanNotReset (); } else { // To translators: label message UI(`ReplaceWidget(`id(`wo), `Label (_("The configuration has been reset.")))); UI(`ChangeWidget(`id(`back), `Enabled, false)); } } } until (((ret == `back) || (ret == `next) || ret == `cancel)); return ret; }; // this dialog is displayed if ALSA // not istalled define NotInstalled () ``{ // Help text when Alsa-drivers are not installed 1/1 string help_text = UI(_("Sound support requires the <b>ALSA</b> package. You can find it in the <b>SuSE</b> distribution (series 'snd') or you can download it from <i>http://www.alsa-project.org</i> and then install it. ")); UI(`SetContents (_("Sound cards"), `HVCenter ( // This label is displayed when no alsa package is not installed // To translators: label message `Label (_("Please install the package ALSA (Advanced Linux Sound Architecture)\n before you proceed with the configuration of your sound system. ")) ), help_text, true, true)); return UI(`UserInput ()); }; // this dialog is displayed, when // sndcards DB not found, this should // never happen, just if someone // delete or edit this db define DBNotFound () ``{ // Help text when sndcards database not found 1/1 string help_text = UI(_("An internal <b>YaST2</b> file is missing or corrupted. Please try toreinstall <b>YaST2</b>. You will find it in <b>SuSE</b> distribution,series 'a1'. ")); UI(`SetContents (_("Sound cards"), `HVCenter ( // To translators: label message `Label (_("The Sound card database cannot be found!!!")) ), help_text, true, true)); return UI(`UserInput ()); }; define SearchForCard (string name) ``{ integer len = size (name); name = tolower(name); map ret = $[]; string cmp = ""; integer j = 0; foreach (`m, snd_database, ``{ integer i = 0; foreach(`c, lookup (m, "cards"), ``{ cmp = substring (c, 0, len); if (tolower(cmp) == name) { ret = add (ret, "module", lookup (m, "name")); ret = add (ret, "card", i); ret = add (ret, "driver", j); return ret; } i = i + 1; }); j = j + 1; }); return ret; }; // dialog, when no sound cards were // autodetected, manual selection is // provided here, with two selection // boxes and the text entry for searching define ChooseCard () ``{ // Help text - manual configuration 1/1 string help_text = UI(_("Please <b>manually</b> choose the sound card you want to configure. You can search for a particular sound card by entering the name in the search box. ")); list drivers = GetDrivers (snd_database); string ven = select (drivers, 0); list models = GetCards (ven, snd_database); list index_drivers = index_list (drivers, 0); list index_models = index_list (models, 0); UI(`SetContents(_("Sound cards"), `VBox ( `HBox ( `ReplacePoint (`id (`rep_ven), // To translators: selection box title `SelectionBox (`id (`sel_ven), `opt(`notify), _("Sound card driver"), index_drivers) ), `ReplacePoint(`id(`rep_mod), // To translators: selection box title `SelectionBox (`id (`sel_mod), `opt(`notify), _("Sound card model"), index_models) ) ), // To translators: text entry label `TextEntry (`id(`search), `opt(`notify), _("Search")) //`Empty () ) , help_text, true, true)); any ret = nil; repeat { ret = UI (`UserInput ()); if (ret == `sel_ven) { integer n = UI (`QueryWidget (`id(`sel_ven), `CurrentItem)); ven = select (drivers, n); models = GetCards (ven, snd_database); index_models = index_list (models, 0); UI(`ReplaceWidget (`id(`rep_mod), // To translators: selection box title `SelectionBox (`id (`sel_mod), _("Sound card model"), index_models))); } else if (ret == `search) { string entry = UI(`QueryWidget (`id(`search), `Value)); if (size (entry) > 0) { map found = SearchForCard (entry); if (size(found) > 0) { models = GetCards(lookup (found, "module"), snd_database); index_drivers = index_list (drivers, lookup (found, "driver")); index_models = index_list (models, lookup(found, "card")); UI(`ReplaceWidget (`id(`rep_ven), // To translators: selection box title `SelectionBox (`id (`sel_ven), `opt(`notify), _("Sound card driver"), index_drivers))); UI(`ReplaceWidget (`id(`rep_mod), // To translators: selection box title `SelectionBox (`id (`sel_mod), `opt(`notify), _("Sound card model"), index_models))); } } else { models = GetCards (select (drivers, 0), snd_database); index_models = index_list (models, 0); index_drivers = index_list (drivers, 0); UI(`ReplaceWidget (`id(`rep_ven), // To translators: selection box title `SelectionBox (`id (`sel_ven), `opt(`notify), _("Sound card driver"), index_drivers))); UI(`ReplaceWidget (`id(`rep_mod), // To translators: selection box title `SelectionBox (`id (`sel_mod), `opt(`notify), _("Sound card model"), index_models))); } } card_title = select (models, UI (`QueryWidget (`id(`sel_mod), `CurrentItem))); } until ((ret == `back) || (ret == `next) || ret == `cancel); if (ret == `next) { cards = filter (`d, snd_database, ``(lookup (d, "name") == select (drivers, UI (`QueryWidget (`id(`sel_ven), `CurrentItem))))); } return ret; }; // main dialog, searching for the // sound card; if some is found, than // its displayed, if none, dialog with // "Manual" button it shown to the user define FindCard () ``{ // Help text - found cards 1/3 string help_text = UI (_("<p>If multiple sound cards were found on your system, select on the left side <b>the driver</b> that is appropriate for the sound card model listed on the right side. If only one sound card is found, then <b>one</b> displayed on the left. If there are multiple models of the card, they are listed on the right.</p> ")); // Help text - found cards 2/3 help_text = help_text + UI(_("If <b>no sound cards</b> were found, you can try manual setup. You can skip sound card configuration by pressing the <i>Next</i> button. ")); // Help text - found cards 3/3 help_text = help_text + UI(_("Press the button <i>Options</i> if you want to set the module options manually. ")); // To translators: label message locale msg = _("Searching for a sound card on your system..."); term con = `ReplacePoint (`id (`rp), `Label (msg)); UI(`SetContents (_("Sound cards"), con, help_text, false, false)); cards = GetAudio (); UI(`ChangeWidget(`id(`back), `Enabled, true)); UI(`ChangeWidget(`id(`next), `Enabled, true)); list card_names = maplist (`c, cards, ``(GetCardName (lookup(c, "bus"), lookup (c, "vendor_id"),lookup (c, "device_id")))); list index_names = index_list (card_names, 0); string|void ven = select (card_names, 0); list models = GetCards (ven, snd_database); list index_models = index_list (models, 0); if (cards == []) { con = `VBox ( // To translators: label message `HVCenter(`Label (_("No sound cards were found on your system.\n Try manual setup. "))), // To translators: button label to popup dialog when no sound cards were autodetected `Bottom (`PushButton (`id (`manual), _("&Manual"))) ); } else { if (card_names == [""]) { con = `VBox( `HVCenter (`Label (_("Found card does not have a database entry.\n Try manual setup."))), // To translators: button label to popup dialog when no sound cards were autodetected `Bottom (`PushButton (`id (`manual), _("&Manual"))) ); } else { con = `VBox ( `HBox ( `SelectionBox (`id(`fc), `opt(`notify), _("Sound card driver"), index_names), `ReplacePoint(`id(`rep_mod), `SelectionBox (`id (`sel_mod), `opt(`notify), _("Sound card model"), index_models) )), // To traslators: this is button label, dialog with options setup for a particular sound card is called `PushButton (`id (`expert), _("&Options")) ); } } UI(`ReplaceWidget (`id (`rp), con)); any ret = nil; boolean manually_selected = false; repeat { ret = UI (`UserInput ()); card_title = select (models, UI (`QueryWidget (`id(`sel_mod), `CurrentItem))); if (ret == `fc) { integer n = UI (`QueryWidget (`id(`fc), `CurrentItem)); ven = select (card_names, n); models = GetCards (ven, snd_database); index_models = index_list (models, 0); UI(`ReplaceWidget (`id(`rep_mod), // To translators: selection box title `SelectionBox (`id (`sel_mod), _("Sound card model"), index_models))); } else if (ret == `expert) { integer n = 0; n = UI (`QueryWidget(`id(`fc), `CurrentItem)); if (manually_selected) current_driver = select (cards, n); else { current_card = select (cards, n); current_driver = select (filter (`d, snd_database, ``(lookup (d, "name") == GetCardName (lookup (current_card, "bus"), lookup (current_card, "vendor_id"), lookup (current_card, "device_id")))), 0); } OptionsSetup (current_driver); UI(`SetContents (_("Sound cards"), con, help_text, true, true)); } if (ret == `back && manually_selected) ret = `manual; if (ret == `manual) { cards = []; card_names = []; index_names = []; if (ChooseCard () == `next){ // Help text - user should confirm his/her decision 1/1 string help_text = UI(_("You should be sure that you have selected the <b>correct</b> sound card. ")); if (size (cards) > 0) { card_names = maplist(`c, cards, ``(lookup (c, "name"))); index_names = index_list (card_names, 0); con = `VBox( // To translators: selection box title `SelectionBox (`id(`fc), _("Manually configured drivers"), index_names), // To traslators: this is button label, dialog with options setup for a particular sound card is called `PushButton (`id(`expert), _("&Options")) ); UI(`SetContents (_("Sound cards"), con, help_text, true, true)); manually_selected = true; } } // back to first dialog else { con = `VBox ( // To translators: label message `Label (_("No sound cards were found on your system.\n Try manual setup. ")), // To translators: button label to popup dialog when no sound cards were autodetected `Bottom (`PushButton (`id (`manual), _("&Manual"))) ); UI(`SetContents (_("Sound cards"), con, help_text, true, true)); manually_selected = false; } } } until (( ret == `back) || (ret == `next) || ret == `cancel); if ((ret == `next) && (size (cards) > 0)) { integer n = 0; n = UI (`QueryWidget(`id(`fc), `CurrentItem)); if (manually_selected) { current_card = $[]; current_driver = select (cards, n); } else { current_card = select (cards, n); current_driver = select (filter (`d, snd_database, ``(lookup (d, "name") == GetCardName (lookup (current_card, "bus"), lookup (current_card, "vendor_id"), lookup (current_card, "device_id")))), 0); } string error = ""; if (current_driver == nil) // To translators: label message error = _("This sound card is NOT supported by YaST2 !"); else error = ProbeModule (); if (size(error) > 0) { // Help text - intenal YaST2 error 1/3 string help_text = UI(_("<p>An error has occurred. </p> ")); // Help text - intenal YaST2 error 2/3 help_text = help_text + UI(_("<p>Check that you have installed the correct <b>ALSA</b> package (series 'snd') and that you are running this configuration as root.</p> ")); // Help text - intenal YaST2 error 3/3 help_text = help_text + UI (_("<p>If this problem persists, you can try to pass <b>options</b> to the ALSA kernel module. If you still cannot get the sound card to work, you can try <i>OSS/Free</i> or other sound modules(drivers). However, <b>YaST2</b>sound configuration currently supports only ALSA modules. </p> ")); UI(`SetContents(_("Sound cards"), // To translators: parameter to this is text, one of cannot find/write file `Label(sformat (UI(_("There was an error.\n%1")), error)), help_text, true, true)); ret = UI(`UserInput ()); if (ret == `next) id = size (conf_dialogs); // skip the rest of dialogs else if (ret == `back) id = 1; // first one } } return ret; }; // dialog for adjusting volume define AdjustVolume (integer step) ``{ // Help text - adjusting volume 1/3 string help_text = UI(_("Please adjust the volume. ")); // Help text - adjusting volume 2/3 help_text = help_text + UI(_("You can test your sound card by pressing the <i>Test</i> button. ")); // Help text - adjusting volume 3/3 help_text = help_text + UI(_("After the configuration is done you can use <b>amixer</b> (or any program of your choice) for adjusting the volume.")); integer vol = 50; // let's start with 50% volume Shell ("/usr/bin/amixer set PCM $VOL unmute", $["VOL" : 100]); // various settings for various cards // ESS 1969 chipset has 2 PCM channels Shell ("/usr/bin/amixer set PCM,1 100% unmute 2>/dev/null"); // Trident chipsets have also Wave group on digital path Shell ("/usr/bin/amixer set Wave 100% unmute 2>/dev/null"); // CS4237B chipset Shell ("/usr/bin/amixer set Master Digital' 80% unmute 2>/dev/null"); // for some GUS soundcards Shell ("/usr/bin/amixer set Synth 50% unmute 2>/dev/null"); set_volume (vol); term con = `VBox ( `VBox ( `Top ( `Label (card_title) ), `ReplacePoint (`id(`rprog), // To translators: progress bar title `ProgressBar(`id(`pb), _("Volume"), 100, vol)), `HBox ( `PushButton (`id(`minus), "-"), `PushButton (`id(`plus), "+") ) ), `VStretch (), // To translators: this label is just above the Test button `Label (_("To test the sound card press the button")), // To translators: Test button label `PushButton (`id (`test), _("&Test")) ); UI(`SetContents (_("Sound cards"), con, help_text, true, true)); any ret = nil; repeat { ret = UI (`UserInput ()); if (ret == `minus) { if (vol > step) { vol = vol - step; set_volume (vol); } else { vol = 0; } } else if (ret == `plus) { if (vol + step < 100) { vol = vol + step; set_volume (vol); } else { vol = 100; } } else if (ret == `test) PlayTest (); UI (`ChangeWidget(`id(`pb), `Value, vol)); } until ((ret == `back) || (ret == `next) || ret == `cancel); if (ret == `back) { RemoveModule (lookup (lookup(current_driver, "module"), "name")); } return ret; }; // dialog for saving volume and // modules.conf, now joined into one dialog define SaveVolume () ``{ // Help text - saving configuration/volume 1/2 string help_text = UI(_("The previously adjusted <b>volume</b> will be <b>stored</b> now for later use.")); // Help text - saving configuration/volume 2/2 help_text = help_text + UI(_("The configuration of the sound card will be <b>saved</b>.")); UI (`SetContents (_("Sound cards"), `VBox ( `Top ( `Label (card_title) ), `HVCenter ( `ReplacePoint(`id(`la), // To translators: label message `Label (_("Sound volume and the configuration for the sound card\n will be saved now. ")) )) ), help_text, true, true)); any ret = UI(`UserInput ()); if (ret == `next) { if (Shell ("/usr/sbin/alsactl store") == 127) { // To translators: alsa package corrupted, exactly: alsactl missing string msg = sformat (UI(_("Cannot find 'alsactl'\nPlease check your installation of ALSA package"))); UI (`DisplayMessage (msg, 0, "")); } else { UI(`ChangeWidget(`id(`back), `Enabled, false)); UI(`ChangeWidget(`id(`next), `Enabled, false)); string|void err = ConfModules (lookup (user_settings, "conf_modules")); UI(`ChangeWidget(`id(`back), `Enabled, true)); UI(`ChangeWidget(`id(`next), `Enabled, true)); if (err != nil) { // show error to the user UI(`ReplaceWidget(`id(`la), `Label(err))); ret = UI(`UserInput ()); } else { if (Shell("/sbin/depmod -a -F /boot/System.map-`uname -r` `uname -r`") == 127) { // To translators: possibly never happens, except that someone delete this file UI (`DisplayMessage (_("Cannot make a list of module dependencies."), 0, _("Program 'depmod' missing. Please reinstall 'modules' package (series 'a1')."))); } else { UI(`ReplaceWidget(`id(`la), // To translators: label message `Label(_("The sound card was successfully configured\nand you can now use it.")))); ret = UI(`UserInput ()); } } } } return ret; }; // OBSOLETE NOW AND NOT USED, becouse // it was joined into one dialog define SaveConfig (string f) ``{ // Help text 1/1 string help_text = UI(_("The configuration of the sound card will be <b>saved</b>.")); UI (`SetContents (_("Sound cards"), `VBox ( `Top ( `Label (card_title) ), `HVCenter ( `ReplacePoint(`id(`la), // To translators: label message `Label (_("The configuration for the sound card will be saved now."))) )), help_text, true, true)); any ret = UI(`UserInput ()); if (ret == `next) { string|void err = ConfModules (f); if (err != nil) { // show error to the user UI(`ReplaceWidget(`id(`la), `Label(err))); ret = UI(`UserInput ()); } } if (Shell("/sbin/depmod -a -F /boot/System.map-`uname -r` `uname -r`") == 127) { // To translators: possibly never happens, except that someone delete this file UI (`DisplayMessage (_("Cannot make a list of module dependencies."), 0, _("Program 'depmod' missing. Please reinstall 'modules' package (series 'a1')."))); } return ret; }; // dialog, when some configuration // already exists, it can be reseted // by "Reset" button define EditCard () ``{ // Help text - existing sound card 1/2 string help_text = UI(_("There <b>already exists</b> a configured sound card. ")); // Help text - existing sound card 2/2 // To translators: the only way to change the configuration is to delete an old one and create another help_text = help_text + UI(_("Currently, YaST2 <b>cannot</b> be used for modifying existing sound card configurations. If you want to change a sound card's configuration,you must <b>reset</b> the existing card configuration and reconfigure the card from scratch. ")); list names = index_list (maplist (`i, already_configured, ``(lookup (i, "line1"))), 0); term contents = `ReplacePoint(`id(`ac_whole),`VBox( `ReplacePoint (`id(`ac), // To translators: selection box title `SelectionBox (_("Already configured sound cards"), names)), // To translators: button label `PushButton (`id(`reset), _("&Reset")) ) ); UI(`SetContents (_("Sound cards"), contents, help_text, true, true)); any ret = nil; repeat { ret = UI(`UserInput ()); if (ret == `reset) { RemoveAllAlsaModules (); if ((Shell ("/bin/ls /proc/asound/cards")) == 0) already_configured = SCR(`Read(.proc.asound.cards)); else already_configured = nil; if (already_configured == nil) { // To translators: label message UI(`ReplaceWidget(`id(`ac_whole), `Label (_("The previous configuration has been reset.")))); UI(`ChangeWidget(`id(`back), `Enabled, false)); } else { CanNotReset (); names = index_list (maplist (`i, already_configured, ``(lookup (i, "line1"))), 0); } } } until ((ret == `back) || (ret == `next) || ret == `cancel); }; /* ==== */ /* main */ /* ==== */ list|void snd_database = ReadY2 ("sndcards.ycp"); map conf_dialogs = $[ 0 : ``FindCard (), 1 : ``AdjustVolume (3), 2 : ``SaveVolume () //3 : ``SaveConfig (lookup (user_settings, "conf_modules")) ]; integer id = 0; list cards = []; // global variables map|void current_card = nil; map|void current_driver = nil; string current_options = ""; map cur_options_map = $[]; string card_title = ""; list|void already_configured = nil; if ((Shell ("/bin/ls /proc/asound/cards")) == 0) already_configured = SCR(`Read(.proc.asound.cards)); if (already_configured != nil && already_configured != []) { EditCard (); } if (already_configured == []) { WrongOutput (); // "--- no soundcards ---" or other unrecognized output } if (IsAlsaInstalled ()) { if (snd_database != nil) { if (already_configured == nil) { // FindCard, AdjustVolume, SaveVolume, SaveConfig while (id >= 0 && id < size (conf_dialogs)) { term dlg = lookup (conf_dialogs, id); any ret = eval(dlg); if (ret == `next) id = id + 1; else if (ret == `back) { id = id - 1; if (id == 0) cards = GetAudio (); } else if (ret == `cancel) break; if (id > 0 && cards == []) // no sound cards - exit break; } } } else DBNotFound (); } else NotInstalled (); UI(`CloseDialog()); }