ACC SHELL

Path : /usr/share/YaST2/include/hwinfo/
File Upload :
Current File : //usr/share/YaST2/include/hwinfo/newid.ycp

/**
 * 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