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 / include / hwinfo / newid.ycp < prev    next >
Text File  |  2006-11-29  |  13KB  |  499 lines

  1. /**
  2.  * File:
  3.  *   newid.ycp
  4.  *
  5.  * Summary:
  6.  *   Configuration of PCI ID - User interface
  7.  *
  8.  * Authors:
  9.  *   Ladislav Slezak <lslezak@suse.cz>
  10.  *
  11.  * $Id: newid.ycp 33530 2006-10-20 11:08:26Z lslezak $
  12.  *
  13.  */
  14.  
  15. {
  16.  
  17. textdomain "tune";
  18.  
  19. import "Wizard";
  20. import "NewID";
  21. import "Report";
  22.  
  23. import "Popup";
  24. import "Label";
  25.  
  26. include "hwinfo/routines.ycp";
  27.  
  28. define symbol ReadSettings() {
  29.     NewID::Read("/etc/sysconfig/hardware/newids");
  30.     return `next;
  31. }
  32.     
  33. define symbol WriteSettings() {
  34.     return (NewID::Write()) ? `next : `abort;
  35. }
  36.  
  37. /**
  38.  * Return list of items for table widget
  39.  * @return list List of items
  40.  */
  41. define list get_table_items() ``{
  42.     list<map<string,any> > ids = NewID::GetNewIDs();
  43.  
  44.     // prepare table items
  45.     list table_items = [];
  46.     integer id = 0;
  47.  
  48.     if (ids != nil)
  49.     {
  50.     foreach(map newid, ids, ``{
  51.           // IDs for selected PCI device
  52.           if (haskey(newid, "uniq"))
  53.           {
  54.           newid = NewID::AddIDs(newid);
  55.           }
  56.  
  57.           table_items = add(table_items, `item(`id(id),
  58.               newid["driver"]:"",
  59.               NewID::GetModelString(newid["uniq"]:""),
  60.               add_hex_prefix(newid["vendor"]:""),
  61.               add_hex_prefix(newid["device"]:""),
  62.               add_hex_prefix(newid["subvendor"]:""),
  63.               add_hex_prefix(newid["subdevice"]:""),
  64.               add_hex_prefix(newid["class"]:""),
  65.               add_hex_prefix(newid["class_mask"]:""),
  66.               newid["sysdir"]:""
  67.           )
  68.           );
  69.           id = id + 1;
  70.         }
  71.     );
  72.     }
  73.  
  74.     return table_items;
  75. }
  76.  
  77.  
  78. define string GetIdValue(symbol widget) {
  79.  
  80.     string ret = (string) UI::QueryWidget(`id(widget), `Value);
  81.  
  82.     if (ret == nil)
  83.     {
  84.     ret = "";
  85.     }
  86.  
  87.     return ret;
  88. }
  89.  
  90. define map NewIDPopup(map<string,any> newid) {
  91.     // ask user to support new device
  92.     term new_id_dialog = `VBox(
  93.     `VSpacing(0.4),
  94.     // text in dialog header
  95.     `Heading(_("PCI ID Setup")),
  96.     `VSpacing(0.5),
  97.     `HBox(
  98.         `HSpacing(1),
  99.         `VBox(
  100.         // textentry label
  101.         `TextEntry(`id(`driver), _("&Driver"), newid["driver"]:""),
  102.         `VSpacing(0.5),
  103.         // textentry label
  104.         `TextEntry(`id(`vendor), _("&Vendor"), newid["vendor"]:""),
  105.         `VSpacing(0.5),
  106.         // textentry label
  107.         `TextEntry(`id(`subvendor), _("&Subvendor"), newid["subvendor"]:""),
  108.         `VSpacing(0.5),
  109.         // textentry label
  110.         `TextEntry(`id(`class), _("&Class"), newid["class"]:"")
  111.         ),
  112.         `HSpacing(1.5),
  113.         `VBox(
  114.         // textentry label
  115.         `TextEntry(`id(`sysdir), _("Sys&FS Directory"), newid["sysdir"]:""),
  116.         `VSpacing(0.5),
  117.         // textentry label
  118.         `TextEntry(`id(`device), _("&Device"), newid["device"]:""),
  119.         `VSpacing(0.5),
  120.         // textentry label
  121.         `TextEntry(`id(`subdevice), _("S&ubdevice"), newid["subdevice"]:""),
  122.         `VSpacing(0.5),
  123.         // textentry label
  124.         `TextEntry(`id(`class_mask), _("Class &Mask"), newid["class_mask"]:"")
  125.         ),
  126.         `HSpacing(1)
  127.     ),
  128.  
  129.     `VSpacing(1),
  130.     `HBox(
  131.         `HStretch(),
  132.         `HWeight(1, `PushButton(`id(`ok), `opt(`default), Label::OKButton())),
  133.         `HSpacing(3),
  134.         `HWeight(1, `PushButton(`id(`cancel), Label::CancelButton())),
  135.         `HStretch()
  136.     ),
  137.     `VSpacing(0.4)
  138.     );
  139.  
  140.     UI::OpenDialog(new_id_dialog);
  141.  
  142.     // allow only hex numbures
  143.     string hexchars = "0123456789abcdefABCDEFx";
  144.     UI::ChangeWidget(`id(`vendor), `ValidChars, hexchars);
  145.     UI::ChangeWidget(`id(`subvendor), `ValidChars, hexchars);
  146.     UI::ChangeWidget(`id(`device), `ValidChars, hexchars);
  147.     UI::ChangeWidget(`id(`subdevice), `ValidChars, hexchars);
  148.     UI::ChangeWidget(`id(`class), `ValidChars, hexchars);
  149.     UI::ChangeWidget(`id(`class_mask), `ValidChars, hexchars);
  150.  
  151.     symbol ui = nil;
  152.     map ret = $[];
  153.  
  154.     do {
  155.     ui = (symbol)UI::UserInput();
  156.  
  157.     if (ui == `ok)
  158.     {
  159.         // read and set values
  160.         string vendor = GetIdValue(`vendor);
  161.         string subvendor = GetIdValue(`subvendor);
  162.         string device = GetIdValue(`device);
  163.         string subdevice = GetIdValue(`subdevice);
  164.         string class = GetIdValue(`class);
  165.         string class_mask = GetIdValue(`class_mask);
  166.         string driver = (string)UI::QueryWidget(`id(`driver), `Value);
  167.         string sysdir = (string)UI::QueryWidget(`id(`sysdir), `Value);
  168.  
  169.         if (driver == "" && sysdir == "")
  170.         {
  171.         // error message, driver name and sysfs directory are empty. one is needed
  172.         Report::Error(_("Enter the driver or SysFS directory name."));
  173.         ui = nil;
  174.         }
  175.         else if (vendor == "" && subvendor == "" && device == "" && subdevice == ""
  176.         && class_mask == "" && class == "")
  177.         {
  178.         // error message, user didn't fill any PCI ID value
  179.         Report::Error(_("At least one PCI ID value is required."));
  180.         ui = nil;
  181.         }
  182.         else
  183.         {
  184.         ret = $["ui" : `ok, "newid" : $[
  185.             "vendor" : vendor,
  186.             "device" : device,
  187.             "subvendor" : subvendor,
  188.             "subdevice" : subdevice,
  189.             "class" : class,
  190.             "class_mask" : class_mask,
  191.             "driver" : driver,
  192.             "sysdir" : sysdir
  193.             ]
  194.         ];
  195.         }
  196.     }
  197.     else if (ui == `close || ui == `cancel)
  198.     {
  199.         ret = $["ui" : `cancel];
  200.     }
  201.     }
  202.     while (ui != `ok && ui != `cancel && ui != `close);
  203.  
  204.     UI::CloseDialog();
  205.  
  206.     return ret;
  207. }
  208.  
  209. define list<term> pci_items(string selected_uniq) {
  210.     list<term> ret = [];
  211.  
  212.     list<map> pcidevices = NewID::GetPCIdevices();
  213.  
  214.     foreach(map pcidev, pcidevices, {
  215.         string uniq = pcidev["unique_key"]:"";
  216.         string model = pcidev["model"]:"";
  217.         string busid = pcidev["sysfs_bus_id"]:"";
  218.  
  219.         if (uniq != "" && model != "" && busid != "")
  220.         {
  221.         ret = add(ret, `item(`id(uniq), sformat("%1 (%2)", model, busid), uniq == selected_uniq));
  222.         }
  223.     }
  224.     );
  225.  
  226.     return ret;
  227. }
  228.  
  229. define map NewDeviceIDPopup(map<string,any> newid) {
  230.     // ask user to support new device
  231.     term new_id_dialog = `VBox(
  232.     `VSpacing(0.4),
  233.     // text in dialog header
  234.     `Heading(_("PCI ID Setup")),
  235.     `VSpacing(0.5),
  236.     `HBox(
  237.         `HSpacing(1),
  238.         // textentry label
  239.         `TextEntry(`id(`driver), _("&Driver"), newid["driver"]:""),
  240.         `HSpacing(1.5),
  241.         // textentry label
  242.         `TextEntry(`id(`sysdir), _("Sys&FS Directory"), newid["sysdir"]:""),
  243.         `HSpacing(1)
  244.     ),
  245.     `VSpacing(1),
  246.  
  247.     `HBox(
  248.         `HSpacing(1),
  249.         `ComboBox(`id(`pcidevices), _("PCI &Device"), pci_items(newid["uniq"]:"")),
  250.         `HSpacing(1)
  251.     ),
  252.  
  253.     `VSpacing(1),
  254.     `HBox(
  255.         `HStretch(),
  256.         `HWeight(1, `PushButton(`id(`ok), `opt(`default), Label::OKButton())),
  257.         `HSpacing(3),
  258.         `HWeight(1, `PushButton(`id(`cancel), Label::CancelButton())),
  259.         `HStretch()
  260.     ),
  261.     `VSpacing(0.4)
  262.     );
  263.  
  264.     UI::OpenDialog(new_id_dialog);
  265.  
  266.     symbol ui = nil;
  267.     map ret = $[];
  268.  
  269.     do {
  270.     ui = (symbol)UI::UserInput();
  271.  
  272.     if (ui == `ok)
  273.     {
  274.         // read and set values
  275.         string driver = (string)UI::QueryWidget(`id(`driver), `Value);
  276.         string sysdir = (string)UI::QueryWidget(`id(`sysdir), `Value);
  277.         string uniq = (string)UI::QueryWidget(`id(`pcidevices), `Value);
  278.  
  279.         if (driver == "" && sysdir == "")
  280.         {
  281.         // error message, driver name and sysfs directory are empty
  282.         Report::Error(_("Enter the driver or SysFS directory name."));
  283.         ui = nil;
  284.         }
  285.         else
  286.         {
  287.         ret = $["ui" : `ok, "newid" : $[
  288.             "uniq"   : uniq,
  289.             "driver" : driver,
  290.             "sysdir" : sysdir
  291.             ]
  292.         ];
  293.         }
  294.     }
  295.     else if (ui == `close || ui == `cancel)
  296.     {
  297.         ret = $["ui" : `cancel];
  298.     }
  299.     }
  300.     while (ui != `ok && ui != `cancel && ui != `close);
  301.  
  302.     UI::CloseDialog();
  303.  
  304.     return ret;
  305. }
  306.  
  307.  
  308. define void RefreshTableContent() {
  309.     list items = get_table_items();
  310.  
  311.     UI::ChangeWidget(`newid_table, `Items, items);
  312. }
  313.  
  314. define term NewPCIIDDialogContent () {
  315.     return     `VBox(
  316.             // table header, use as short texts as possible
  317.             `Table(`id(`newid_table), `header(_("Driver"), _("Card Name"), _("Vendor"), _("Device"),
  318.             // table header, use as short texts as possible
  319.                 _("Subvendor"), _("Subdevice"), _("Class"), _("Class Mask"), _("SysFS Dir."))),
  320.             `VSpacing(0.5),
  321.             `HBox(
  322.                 `MenuButton( Label::AddButton() + "...", [
  323.                 `item(`id(`add_selected), _("&From List")),
  324.                 `item(`id(`add), _("&Manually")),
  325.                 ]),
  326.                 `HSpacing(1),
  327.                 `PushButton(`id(`edit), Label::EditButton()),
  328.                 `HSpacing(1),
  329.                 `PushButton(`id(`delete), Label::DeleteButton())
  330.             ),
  331.             `VSpacing(0.5)
  332.         );
  333. }
  334.  
  335. define string NewPCIIDDialogHelp () {
  336.     return
  337.     // help text header
  338.     _("<P><B>PCI ID Setup</B><BR></P>")
  339.     // PCI ID help text
  340.     + _("<P>It is possible to add a PCI ID to a device driver to extend its internal database of known supported devices.</P>")
  341.     // PCI ID help text
  342.     + _("<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>")
  343.     // PCI ID help text
  344.     + _("<P>If the driver is compiled into the kernel, leave the driver name empty and enter the SysFS directory name instead.</P>")
  345.     // PCI ID help text
  346.     + _("<P>Use the buttons below the table to change the list of PCI IDs. Press <b>OK</b> to activate the settings.</P>")
  347.     // PCI ID help text
  348.     + _("<P><B>Warning:</B> This is an expert configuration. Only continue if you know what you are doing.</P>");
  349. }
  350.  
  351. define string NewPCIIDDialogCaption () {
  352.     // dialog header
  353.     return _("PCI ID Setup");
  354. }
  355.  
  356. define void InitNewPCIIDDialog (string id) {
  357.     y2milestone("Init: %1", id);
  358.     UI::ChangeWidget(`id(`newid_table), `Items, get_table_items());
  359. }
  360.  
  361. // FIXME: move to the NewID.ycp module
  362. /* PCI ID settings have been changed */
  363. boolean pci_id_changed = false;
  364.  
  365. /*
  366.  * Function sets whether PCI ID settings have been changed
  367.  */
  368. void SetNewPCIIDChanged (boolean changed) {
  369.     pci_id_changed = changed;
  370. }
  371.  
  372. /*
  373.  * Function returns whether PCI ID settings have been changed
  374.  */
  375. boolean GetNewPCIIDChanged () {
  376.     return pci_id_changed;
  377. }
  378.  
  379. symbol handle_function_returns = nil;
  380. define symbol HandleNewPCIIDDialog (string key, map event) {
  381.     // we serve only PC_ID settings
  382.     if (key != "pci_id_table_and_buttons") return nil;
  383.     if (event["ID"]:nil == "kernel_settings") return nil;
  384.  
  385.     y2milestone("Key: %1, Event: %2", key, event);
  386.  
  387.     any handle_function_returns = event["ID"]:nil;
  388.  
  389.     if (handle_function_returns== nil) {
  390.         y2warning("Unknown event");
  391.     }
  392.     else if (handle_function_returns== `back)
  393.     {
  394.         // returning back
  395.         handle_function_returns = `back;
  396.     }
  397.     else if (handle_function_returns== `next)
  398.     {
  399.         // activate the settings
  400.         NewID::Activate();
  401.         // returning next
  402.         handle_function_returns = `next;
  403.     }
  404.     else if (handle_function_returns== `cancel)
  405.     {
  406.         if (GetNewPCIIDChanged())
  407.         {
  408.         if (Popup::ReallyAbort(true) == false)
  409.         {
  410.             // loop - continue
  411.             handle_function_returns = `continue;
  412.         }
  413.         }
  414.         // returning abort
  415.         handle_function_returns = `abort;
  416.     }
  417.     else if (handle_function_returns== `add || handle_function_returns== `add_selected)
  418.     {
  419.         map result = (handle_function_returns== `add) ? NewIDPopup($[]) : NewDeviceIDPopup($[]);
  420.  
  421.         if (result["ui"]:`cancel == `ok) {
  422.         // add new id
  423.         NewID::AddID(result["newid"]:$[]);
  424.  
  425.         // refresh table content
  426.         RefreshTableContent();
  427.         }
  428.     }
  429.     else if (handle_function_returns== `edit)
  430.     {
  431.         integer curr = (integer) UI::QueryWidget(`id(`newid_table), `CurrentItem);
  432.         map<string,any> nid = NewID::GetNewID(curr);
  433.  
  434.         map result = (haskey(nid, "uniq")) ? NewDeviceIDPopup(nid) : NewIDPopup(nid);
  435.  
  436.         if (result["ui"]:`cancel == `ok) {
  437.         NewID::SetNewID(result["newid"]:$[], curr);
  438.         RefreshTableContent();
  439.         UI::ChangeWidget(`id(`newid_table), `CurrentItem, curr);
  440.         }
  441.     }
  442.     else if (handle_function_returns== `delete)
  443.     {
  444.         integer curr = (integer) UI::QueryWidget(`id(`newid_table), `CurrentItem);
  445.         NewID::RemoveID(curr);
  446.  
  447.         RefreshTableContent();
  448.  
  449.         integer numids = size(NewID::GetNewIDs());
  450.  
  451.         // preselect the nearest line to deleted one if possible
  452.         if (numids > 0)
  453.         {
  454.         if (curr >= numids)
  455.         {
  456.             curr = numids - 1;
  457.         }
  458.  
  459.         UI::ChangeWidget(`id(`newid_table), `CurrentItem, curr);
  460.         }
  461.     }
  462.  
  463.     y2milestone("Returning %1", handle_function_returns);
  464. }
  465.  
  466. /**
  467.  * Main PCI ID configuration dialog
  468.  * @return any Result from UserInput()
  469.  */
  470. define any NewIDConfigDialog() ``{
  471.     Wizard::SetContents(
  472.     NewPCIIDDialogCaption(),
  473.     NewPCIIDDialogContent(),
  474.     NewPCIIDDialogHelp(),
  475.     true, true
  476.     );
  477.  
  478.     // remove Back button - workflow has only one dialog
  479.     Wizard::HideAbortButton();
  480.     Wizard::SetNextButton(`next, Label::OKButton());
  481.  
  482.     InitNewPCIIDDialog("pci_id_table_and_buttons");
  483.  
  484.     handle_function_returns = nil;
  485.     while (true)
  486.     {
  487.     handle_function_returns = (symbol) UI::UserInput();
  488.     HandleNewPCIIDDialog("pci_id_table_and_buttons", $["ID" : handle_function_returns]);
  489.     // breaking the loop
  490.     if (handle_function_returns== `back || handle_function_returns== `next || handle_function_returns== `abort) break;
  491.     };
  492.  
  493.     y2milestone("New PCI ID: %1", handle_function_returns);
  494.     return handle_function_returns;
  495. }
  496.  
  497.  
  498. }
  499.