ACC SHELL
/**
* File:
* newid.ycp
*
* Summary:
* Configuration of PCI ID - User interface
*
* Authors:
* Ladislav Slezak <lslezak@suse.cz>
*
* $Id: newid.ycp 51884 2008-10-06 16:18:52Z lslezak $
*
*/
{
textdomain "tune";
import "Wizard";
import "NewID";
import "Report";
import "Popup";
import "Label";
import "Mode";
include "hwinfo/routines.ycp";
define symbol ReadSettings() {
NewID::Read("/etc/sysconfig/hardware/newids");
return `next;
}
define symbol WriteSettings() {
return (NewID::Write()) ? `next : `abort;
}
/**
* Return list of items for table widget
* @return list List of items
*/
define list get_table_items() ``{
list<map<string,any> > ids = NewID::GetNewIDs();
// prepare table items
list table_items = [];
integer id = 0;
if (ids != nil)
{
foreach(map newid, ids, ``{
// IDs for selected PCI device
if (haskey(newid, "uniq"))
{
newid = NewID::AddIDs(newid);
}
table_items = add(table_items, `item(`id(id),
newid["driver"]:"",
NewID::GetModelString(newid["uniq"]:""),
add_hex_prefix(newid["vendor"]:""),
add_hex_prefix(newid["device"]:""),
add_hex_prefix(newid["subvendor"]:""),
add_hex_prefix(newid["subdevice"]:""),
add_hex_prefix(newid["class"]:""),
add_hex_prefix(newid["class_mask"]:""),
newid["sysdir"]:""
)
);
id = id + 1;
}
);
}
return table_items;
}
define string GetIdValue(symbol widget) {
string ret = (string) UI::QueryWidget(`id(widget), `Value);
if (ret == nil)
{
ret = "";
}
return ret;
}
define map NewIDPopup(map<string,any> newid) {
// ask user to support new device
term new_id_dialog = `VBox(
`VSpacing(0.4),
// text in dialog header
`Heading(_("PCI ID Setup")),
`VSpacing(0.5),
`HBox(
`HSpacing(1),
`VBox(
// textentry label
`TextEntry(`id(`driver), _("&Driver"), newid["driver"]:""),
`VSpacing(0.5),
// textentry label
`TextEntry(`id(`vendor), _("&Vendor"), newid["vendor"]:""),
`VSpacing(0.5),
// textentry label
`TextEntry(`id(`subvendor), _("&Subvendor"), newid["subvendor"]:""),
`VSpacing(0.5),
// textentry label
`TextEntry(`id(`class), _("&Class"), newid["class"]:"")
),
`HSpacing(1.5),
`VBox(
// textentry label
`TextEntry(`id(`sysdir), _("Sys&FS Directory"), newid["sysdir"]:""),
`VSpacing(0.5),
// textentry label
`TextEntry(`id(`device), _("&Device"), newid["device"]:""),
`VSpacing(0.5),
// textentry label
`TextEntry(`id(`subdevice), _("S&ubdevice"), newid["subdevice"]:""),
`VSpacing(0.5),
// textentry label
`TextEntry(`id(`class_mask), _("Class &Mask"), newid["class_mask"]:"")
),
`HSpacing(1)
),
`VSpacing(1),
`HBox(
`HStretch(),
`HWeight(1, `PushButton(`id(`ok), `opt(`default), Label::OKButton())),
`HSpacing(3),
`HWeight(1, `PushButton(`id(`cancel), Label::CancelButton())),
`HStretch()
),
`VSpacing(0.4)
);
UI::OpenDialog(new_id_dialog);
// allow only hex numbures
string hexchars = "0123456789abcdefABCDEFx";
UI::ChangeWidget(`id(`vendor), `ValidChars, hexchars);
UI::ChangeWidget(`id(`subvendor), `ValidChars, hexchars);
UI::ChangeWidget(`id(`device), `ValidChars, hexchars);
UI::ChangeWidget(`id(`subdevice), `ValidChars, hexchars);
UI::ChangeWidget(`id(`class), `ValidChars, hexchars);
UI::ChangeWidget(`id(`class_mask), `ValidChars, hexchars);
symbol ui = nil;
map ret = $[];
do {
ui = (symbol)UI::UserInput();
if (ui == `ok)
{
// read and set values
string vendor = GetIdValue(`vendor);
string subvendor = GetIdValue(`subvendor);
string device = GetIdValue(`device);
string subdevice = GetIdValue(`subdevice);
string class = GetIdValue(`class);
string class_mask = GetIdValue(`class_mask);
string driver = (string)UI::QueryWidget(`id(`driver), `Value);
string sysdir = (string)UI::QueryWidget(`id(`sysdir), `Value);
if (driver == "" && sysdir == "")
{
// error message, driver name and sysfs directory are empty. one is needed
Report::Error(_("Enter the driver or SysFS directory name."));
ui = nil;
}
else if (vendor == "" && subvendor == "" && device == "" && subdevice == ""
&& class_mask == "" && class == "")
{
// error message, user didn't fill any PCI ID value
Report::Error(_("At least one PCI ID value is required."));
ui = nil;
}
else
{
ret = $["ui" : `ok, "newid" : $[
"vendor" : vendor,
"device" : device,
"subvendor" : subvendor,
"subdevice" : subdevice,
"class" : class,
"class_mask" : class_mask,
"driver" : driver,
"sysdir" : sysdir
]
];
}
}
else if (ui == `close || ui == `cancel)
{
ret = $["ui" : `cancel];
}
}
while (ui != `ok && ui != `cancel && ui != `close);
UI::CloseDialog();
return ret;
}
define list<term> pci_items(string selected_uniq) {
list<term> ret = [];
list<map> pcidevices = NewID::GetPCIdevices();
foreach(map pcidev, pcidevices, {
string uniq = pcidev["unique_key"]:"";
string model = pcidev["model"]:"";
string busid = pcidev["sysfs_bus_id"]:"";
if (uniq != "" && model != "" && busid != "")
{
ret = add(ret, `item(`id(uniq), sformat("%1 (%2)", model, busid), uniq == selected_uniq));
}
}
);
return ret;
}
define map NewDeviceIDPopup(map<string,any> newid) {
// ask user to support new device
term new_id_dialog = `VBox(
`VSpacing(0.4),
// text in dialog header
`Heading(_("PCI ID Setup")),
`VSpacing(0.5),
`HBox(
`HSpacing(1),
// textentry label
`TextEntry(`id(`driver), _("&Driver"), newid["driver"]:""),
`HSpacing(1.5),
// textentry label
`TextEntry(`id(`sysdir), _("Sys&FS Directory"), newid["sysdir"]:""),
`HSpacing(1)
),
`VSpacing(1),
`HBox(
`HSpacing(1),
`ComboBox(`id(`pcidevices), _("PCI &Device"), pci_items(newid["uniq"]:"")),
`HSpacing(1)
),
`VSpacing(1),
`HBox(
`HStretch(),
`HWeight(1, `PushButton(`id(`ok), `opt(`default), Label::OKButton())),
`HSpacing(3),
`HWeight(1, `PushButton(`id(`cancel), Label::CancelButton())),
`HStretch()
),
`VSpacing(0.4)
);
UI::OpenDialog(new_id_dialog);
symbol ui = nil;
map ret = $[];
do {
ui = (symbol)UI::UserInput();
if (ui == `ok)
{
// read and set values
string driver = (string)UI::QueryWidget(`id(`driver), `Value);
string sysdir = (string)UI::QueryWidget(`id(`sysdir), `Value);
string uniq = (string)UI::QueryWidget(`id(`pcidevices), `Value);
if (driver == "" && sysdir == "")
{
// error message, driver name and sysfs directory are empty
Report::Error(_("Enter the driver or SysFS directory name."));
ui = nil;
}
else
{
ret = $["ui" : `ok, "newid" : $[
"uniq" : uniq,
"driver" : driver,
"sysdir" : sysdir
]
];
}
}
else if (ui == `close || ui == `cancel)
{
ret = $["ui" : `cancel];
}
}
while (ui != `ok && ui != `cancel && ui != `close);
UI::CloseDialog();
return ret;
}
// bugzilla #237339
define void AdjustDialogButtons (integer count_of_items_in_table) {
// at least one PCIID defined
if (count_of_items_in_table > 0) {
UI::ChangeWidget (`id(`edit), `Enabled, true);
UI::ChangeWidget (`id(`delete), `Enabled, true);
// nothing listed, disabling buttons
} else {
UI::ChangeWidget (`id(`edit), `Enabled, false);
UI::ChangeWidget (`id(`delete), `Enabled, false);
}
}
define void RefreshTableContent() {
list items = get_table_items();
UI::ChangeWidget(`newid_table, `Items, items);
AdjustDialogButtons (size(items));
}
define term NewPCIIDDialogContent () {
return `VBox(
// table header, use as short texts as possible
`Table(`id(`newid_table), `header(_("Driver"), _("Card Name"), _("Vendor"), _("Device"),
// table header, use as short texts as possible
_("Subvendor"), _("Subdevice"), _("Class"), _("Class Mask"), _("SysFS Dir."))),
`VSpacing(0.5),
`HBox(
`MenuButton( Label::AddButton() + "...", [
`item(`id(`add_selected), _("&From List")),
`item(`id(`add), _("&Manually")),
]),
`HSpacing(1),
`PushButton(`id(`edit), Label::EditButton()),
`HSpacing(1),
`PushButton(`id(`delete), Label::DeleteButton()),
`HStretch()
),
`VSpacing(0.5)
);
}
define string NewPCIIDDialogHelp () {
// bugzilla #237379
string button_label = (Mode::installation() || Mode::config() ? Label::OKButton() : Label::FinishButton());
if (regexpmatch(button_label, "&")) button_label = regexpsub (button_label, "(.*)&(.*)", "\\1\\2");
return
// help text header
_("<P><B>PCI ID Setup</B><BR></P>")
// PCI ID help text
+ _("<P>It is possible to add a PCI ID to a device driver to extend its internal database of known supported devices.</P>")
// PCI ID help text
+ _("<P>PCI ID numbers are entered and displayed as hexadecimal numbers. <b>SysFS Dir.</b> is the directory name in the /sys/bus/pci/drivers directory. If it is empty, the driver name is used as the directory name.</P>")
// PCI ID help text
+ _("<P>If the driver is compiled into the kernel, leave the driver name empty and enter the SysFS directory name instead.</P>")
+ sformat(
// PCI ID help text, %1 stands for a button name (OK or Finish -- depends on the situation)
_("<P>Use the buttons below the table to change the list of PCI IDs. Press <b>%1</b> to activate the settings.</P>"),
button_label
)
// PCI ID help text
+ _("<P><B>Warning:</B> This is an expert configuration. Only continue if you know what you are doing.</P>");
}
define string NewPCIIDDialogCaption () {
// dialog header
return _("PCI ID Setup");
}
define void InitNewPCIIDDialog (string id) {
Wizard::DisableBackButton();
y2milestone("Init: %1", id);
list items = get_table_items();
UI::ChangeWidget(`id(`newid_table), `Items, items);
AdjustDialogButtons (size(items));
}
// FIXME: move to the NewID.ycp module
/* PCI ID settings have been changed */
boolean pci_id_changed = false;
/*
* Function sets whether PCI ID settings have been changed
*/
void SetNewPCIIDChanged (boolean changed) {
pci_id_changed = changed;
}
/*
* Function returns whether PCI ID settings have been changed
*/
boolean GetNewPCIIDChanged () {
return pci_id_changed;
}
symbol handle_function_returns = nil;
define symbol HandleNewPCIIDDialog (string key, map event) {
// we serve only PC_ID settings
if (key != "pci_id_table_and_buttons") return nil;
if (event["ID"]:nil == "kernel_settings") return nil;
y2milestone("Key: %1, Event: %2", key, event);
any handle_function_returns = event["ID"]:nil;
if (handle_function_returns== nil) {
y2warning("Unknown event");
}
else if (handle_function_returns== `back)
{
// returning back
handle_function_returns = `back;
}
else if (handle_function_returns== `next)
{
// activate the settings
NewID::Activate();
// returning next
handle_function_returns = `next;
}
else if (handle_function_returns== `cancel)
{
if (GetNewPCIIDChanged())
{
if (Popup::ReallyAbort(true) == false)
{
// loop - continue
handle_function_returns = `continue;
}
}
// returning abort
handle_function_returns = `abort;
}
else if (handle_function_returns== `add || handle_function_returns== `add_selected)
{
map result = (handle_function_returns== `add) ? NewIDPopup($[]) : NewDeviceIDPopup($[]);
if (result["ui"]:`cancel == `ok) {
// add new id
NewID::AddID(result["newid"]:$[]);
// refresh table content
RefreshTableContent();
}
}
else if (handle_function_returns== `edit)
{
integer curr = (integer) UI::QueryWidget(`id(`newid_table), `CurrentItem);
map<string,any> nid = NewID::GetNewID(curr);
map result = (haskey(nid, "uniq")) ? NewDeviceIDPopup(nid) : NewIDPopup(nid);
if (result["ui"]:`cancel == `ok) {
NewID::SetNewID(result["newid"]:$[], curr);
RefreshTableContent();
UI::ChangeWidget(`id(`newid_table), `CurrentItem, curr);
}
}
else if (handle_function_returns== `delete)
{
integer curr = (integer) UI::QueryWidget(`id(`newid_table), `CurrentItem);
NewID::RemoveID(curr);
RefreshTableContent();
integer numids = size(NewID::GetNewIDs());
// preselect the nearest line to deleted one if possible
if (numids > 0)
{
if (curr >= numids)
{
curr = numids - 1;
}
UI::ChangeWidget(`id(`newid_table), `CurrentItem, curr);
}
}
y2milestone("Returning %1", handle_function_returns);
}
/**
* Main PCI ID configuration dialog
* @return any Result from UserInput()
*/
define any NewIDConfigDialog() ``{
Wizard::SetContents(
NewPCIIDDialogCaption(),
NewPCIIDDialogContent(),
NewPCIIDDialogHelp(),
true, true
);
Wizard::DisableBackButton();
Wizard::SetNextButton(`next, Label::OKButton());
InitNewPCIIDDialog("pci_id_table_and_buttons");
handle_function_returns = nil;
while (true)
{
handle_function_returns = (symbol) UI::UserInput();
HandleNewPCIIDDialog("pci_id_table_and_buttons", $["ID" : handle_function_returns]);
// breaking the loop
if (handle_function_returns== `back || handle_function_returns== `next || handle_function_returns== `abort) break;
};
y2milestone("New PCI ID: %1", handle_function_returns);
return handle_function_returns;
}
}
ACC SHELL 2018