1692d97c3Snir.tzachar@gmail.com /* 2692d97c3Snir.tzachar@gmail.com * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? 3692d97c3Snir.tzachar@gmail.com * Released under the terms of the GNU GPL v2.0. 4692d97c3Snir.tzachar@gmail.com * 5692d97c3Snir.tzachar@gmail.com * Derived from menuconfig. 6692d97c3Snir.tzachar@gmail.com * 7692d97c3Snir.tzachar@gmail.com */ 8*a72f3e2bSNir Tzachar #define _GNU_SOURCE 9*a72f3e2bSNir Tzachar #include <string.h> 10692d97c3Snir.tzachar@gmail.com #define LKC_DIRECT_LINK 11692d97c3Snir.tzachar@gmail.com #include "lkc.h" 12692d97c3Snir.tzachar@gmail.com #include "nconf.h" 13*a72f3e2bSNir Tzachar #include <ctype.h> 14692d97c3Snir.tzachar@gmail.com 15692d97c3Snir.tzachar@gmail.com static const char nconf_readme[] = N_( 16692d97c3Snir.tzachar@gmail.com "Overview\n" 17692d97c3Snir.tzachar@gmail.com "--------\n" 18692d97c3Snir.tzachar@gmail.com "Some kernel features may be built directly into the kernel.\n" 19692d97c3Snir.tzachar@gmail.com "Some may be made into loadable runtime modules. Some features\n" 20692d97c3Snir.tzachar@gmail.com "may be completely removed altogether. There are also certain\n" 21692d97c3Snir.tzachar@gmail.com "kernel parameters which are not really features, but must be\n" 22692d97c3Snir.tzachar@gmail.com "entered in as decimal or hexadecimal numbers or possibly text.\n" 23692d97c3Snir.tzachar@gmail.com "\n" 24692d97c3Snir.tzachar@gmail.com "Menu items beginning with following braces represent features that\n" 25692d97c3Snir.tzachar@gmail.com " [ ] can be built in or removed\n" 26692d97c3Snir.tzachar@gmail.com " < > can be built in, modularized or removed\n" 27692d97c3Snir.tzachar@gmail.com " { } can be built in or modularized (selected by other feature)\n" 28692d97c3Snir.tzachar@gmail.com " - - are selected by other feature,\n" 29*a72f3e2bSNir Tzachar " XXX cannot be selected. Use Symbol Info to find out why,\n" 30692d97c3Snir.tzachar@gmail.com "while *, M or whitespace inside braces means to build in, build as\n" 31692d97c3Snir.tzachar@gmail.com "a module or to exclude the feature respectively.\n" 32692d97c3Snir.tzachar@gmail.com "\n" 33692d97c3Snir.tzachar@gmail.com "To change any of these features, highlight it with the cursor\n" 34692d97c3Snir.tzachar@gmail.com "keys and press <Y> to build it in, <M> to make it a module or\n" 35692d97c3Snir.tzachar@gmail.com "<N> to removed it. You may also press the <Space Bar> to cycle\n" 36692d97c3Snir.tzachar@gmail.com "through the available options (ie. Y->N->M->Y).\n" 37692d97c3Snir.tzachar@gmail.com "\n" 38692d97c3Snir.tzachar@gmail.com "Some additional keyboard hints:\n" 39692d97c3Snir.tzachar@gmail.com "\n" 40692d97c3Snir.tzachar@gmail.com "Menus\n" 41692d97c3Snir.tzachar@gmail.com "----------\n" 42692d97c3Snir.tzachar@gmail.com "o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" 43692d97c3Snir.tzachar@gmail.com " you wish to change use <Enter> or <Space>. Goto submenu by \n" 44692d97c3Snir.tzachar@gmail.com " pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" 45692d97c3Snir.tzachar@gmail.com " Submenus are designated by \"--->\".\n" 46692d97c3Snir.tzachar@gmail.com "\n" 47*a72f3e2bSNir Tzachar " Searching: pressing '/' triggers interactive search mode.\n" 48*a72f3e2bSNir Tzachar " nconfig performs a case insensitive search for the string\n" 49*a72f3e2bSNir Tzachar " in the menu prompts (no regex support).\n" 50*a72f3e2bSNir Tzachar " Pressing the up/down keys highlights the previous/next\n" 51*a72f3e2bSNir Tzachar " matching item. Backspace removes one character from the\n" 52*a72f3e2bSNir Tzachar " match string. Pressing either '/' again or ESC exits\n" 53*a72f3e2bSNir Tzachar " search mode. All other keys behave normally.\n" 54692d97c3Snir.tzachar@gmail.com "\n" 55692d97c3Snir.tzachar@gmail.com " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" 56692d97c3Snir.tzachar@gmail.com " unseen options into view.\n" 57692d97c3Snir.tzachar@gmail.com "\n" 58692d97c3Snir.tzachar@gmail.com "o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n" 59692d97c3Snir.tzachar@gmail.com "\n" 60692d97c3Snir.tzachar@gmail.com "o To get help with an item, press <F1>\n" 61692d97c3Snir.tzachar@gmail.com " Shortcut: Press <h> or <?>.\n" 62692d97c3Snir.tzachar@gmail.com "\n" 63692d97c3Snir.tzachar@gmail.com "\n" 64692d97c3Snir.tzachar@gmail.com "Radiolists (Choice lists)\n" 65692d97c3Snir.tzachar@gmail.com "-----------\n" 66692d97c3Snir.tzachar@gmail.com "o Use the cursor keys to select the option you wish to set and press\n" 67692d97c3Snir.tzachar@gmail.com " <S> or the <SPACE BAR>.\n" 68692d97c3Snir.tzachar@gmail.com "\n" 69692d97c3Snir.tzachar@gmail.com " Shortcut: Press the first letter of the option you wish to set then\n" 70692d97c3Snir.tzachar@gmail.com " press <S> or <SPACE BAR>.\n" 71692d97c3Snir.tzachar@gmail.com "\n" 72692d97c3Snir.tzachar@gmail.com "o To see available help for the item, press <F1>\n" 73692d97c3Snir.tzachar@gmail.com " Shortcut: Press <H> or <?>.\n" 74692d97c3Snir.tzachar@gmail.com "\n" 75692d97c3Snir.tzachar@gmail.com "\n" 76692d97c3Snir.tzachar@gmail.com "Data Entry\n" 77692d97c3Snir.tzachar@gmail.com "-----------\n" 78692d97c3Snir.tzachar@gmail.com "o Enter the requested information and press <ENTER>\n" 79692d97c3Snir.tzachar@gmail.com " If you are entering hexadecimal values, it is not necessary to\n" 80692d97c3Snir.tzachar@gmail.com " add the '0x' prefix to the entry.\n" 81692d97c3Snir.tzachar@gmail.com "\n" 82692d97c3Snir.tzachar@gmail.com "o For help, press <F1>.\n" 83692d97c3Snir.tzachar@gmail.com "\n" 84692d97c3Snir.tzachar@gmail.com "\n" 85692d97c3Snir.tzachar@gmail.com "Text Box (Help Window)\n" 86692d97c3Snir.tzachar@gmail.com "--------\n" 87692d97c3Snir.tzachar@gmail.com "o Use the cursor keys to scroll up/down/left/right. The VI editor\n" 88692d97c3Snir.tzachar@gmail.com " keys h,j,k,l function here as do <SPACE BAR> for those\n" 89692d97c3Snir.tzachar@gmail.com " who are familiar with less and lynx.\n" 90692d97c3Snir.tzachar@gmail.com "\n" 91692d97c3Snir.tzachar@gmail.com "o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n" 92692d97c3Snir.tzachar@gmail.com "\n" 93692d97c3Snir.tzachar@gmail.com "\n" 94692d97c3Snir.tzachar@gmail.com "Alternate Configuration Files\n" 95692d97c3Snir.tzachar@gmail.com "-----------------------------\n" 96692d97c3Snir.tzachar@gmail.com "nconfig supports the use of alternate configuration files for\n" 97692d97c3Snir.tzachar@gmail.com "those who, for various reasons, find it necessary to switch\n" 98692d97c3Snir.tzachar@gmail.com "between different kernel configurations.\n" 99692d97c3Snir.tzachar@gmail.com "\n" 100692d97c3Snir.tzachar@gmail.com "At the end of the main menu you will find two options. One is\n" 101692d97c3Snir.tzachar@gmail.com "for saving the current configuration to a file of your choosing.\n" 102692d97c3Snir.tzachar@gmail.com "The other option is for loading a previously saved alternate\n" 103692d97c3Snir.tzachar@gmail.com "configuration.\n" 104692d97c3Snir.tzachar@gmail.com "\n" 105692d97c3Snir.tzachar@gmail.com "Even if you don't use alternate configuration files, but you\n" 106692d97c3Snir.tzachar@gmail.com "find during a nconfig session that you have completely messed\n" 107692d97c3Snir.tzachar@gmail.com "up your settings, you may use the \"Load Alternate...\" option to\n" 108692d97c3Snir.tzachar@gmail.com "restore your previously saved settings from \".config\" without\n" 109692d97c3Snir.tzachar@gmail.com "restarting nconfig.\n" 110692d97c3Snir.tzachar@gmail.com "\n" 111692d97c3Snir.tzachar@gmail.com "Other information\n" 112692d97c3Snir.tzachar@gmail.com "-----------------\n" 113692d97c3Snir.tzachar@gmail.com "If you use nconfig in an XTERM window make sure you have your\n" 114692d97c3Snir.tzachar@gmail.com "$TERM variable set to point to a xterm definition which supports color.\n" 115692d97c3Snir.tzachar@gmail.com "Otherwise, nconfig will look rather bad. nconfig will not\n" 116692d97c3Snir.tzachar@gmail.com "display correctly in a RXVT window because rxvt displays only one\n" 117692d97c3Snir.tzachar@gmail.com "intensity of color, bright.\n" 118692d97c3Snir.tzachar@gmail.com "\n" 119692d97c3Snir.tzachar@gmail.com "nconfig will display larger menus on screens or xterms which are\n" 120692d97c3Snir.tzachar@gmail.com "set to display more than the standard 25 row by 80 column geometry.\n" 121692d97c3Snir.tzachar@gmail.com "In order for this to work, the \"stty size\" command must be able to\n" 122692d97c3Snir.tzachar@gmail.com "display the screen's current row and column geometry. I STRONGLY\n" 123692d97c3Snir.tzachar@gmail.com "RECOMMEND that you make sure you do NOT have the shell variables\n" 124692d97c3Snir.tzachar@gmail.com "LINES and COLUMNS exported into your environment. Some distributions\n" 125692d97c3Snir.tzachar@gmail.com "export those variables via /etc/profile. Some ncurses programs can\n" 126692d97c3Snir.tzachar@gmail.com "become confused when those variables (LINES & COLUMNS) don't reflect\n" 127692d97c3Snir.tzachar@gmail.com "the true screen size.\n" 128692d97c3Snir.tzachar@gmail.com "\n" 129692d97c3Snir.tzachar@gmail.com "Optional personality available\n" 130692d97c3Snir.tzachar@gmail.com "------------------------------\n" 131692d97c3Snir.tzachar@gmail.com "If you prefer to have all of the kernel options listed in a single\n" 132692d97c3Snir.tzachar@gmail.com "menu, rather than the default multimenu hierarchy, run the nconfig\n" 133692d97c3Snir.tzachar@gmail.com "with NCONFIG_MODE environment variable set to single_menu. Example:\n" 134692d97c3Snir.tzachar@gmail.com "\n" 135692d97c3Snir.tzachar@gmail.com "make NCONFIG_MODE=single_menu nconfig\n" 136692d97c3Snir.tzachar@gmail.com "\n" 137692d97c3Snir.tzachar@gmail.com "<Enter> will then unroll the appropriate category, or enfold it if it\n" 138692d97c3Snir.tzachar@gmail.com "is already unrolled.\n" 139692d97c3Snir.tzachar@gmail.com "\n" 140692d97c3Snir.tzachar@gmail.com "Note that this mode can eventually be a little more CPU expensive\n" 141692d97c3Snir.tzachar@gmail.com "(especially with a larger number of unrolled categories) than the\n" 142692d97c3Snir.tzachar@gmail.com "default mode.\n" 143692d97c3Snir.tzachar@gmail.com "\n"), 144692d97c3Snir.tzachar@gmail.com menu_no_f_instructions[] = N_( 145692d97c3Snir.tzachar@gmail.com " You do not have function keys support. Please follow the\n" 146692d97c3Snir.tzachar@gmail.com " following instructions:\n" 147692d97c3Snir.tzachar@gmail.com " Arrow keys navigate the menu.\n" 148692d97c3Snir.tzachar@gmail.com " <Enter> or <right-arrow> selects submenus --->.\n" 149692d97c3Snir.tzachar@gmail.com " Capital Letters are hotkeys.\n" 150692d97c3Snir.tzachar@gmail.com " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" 151*a72f3e2bSNir Tzachar " Pressing SpaceBar toggles between the above options.\n" 152692d97c3Snir.tzachar@gmail.com " Press <Esc> or <left-arrow> to go back one menu,\n" 153692d97c3Snir.tzachar@gmail.com " <?> or <h> for Help, </> for Search.\n" 154*a72f3e2bSNir Tzachar " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n" 155692d97c3Snir.tzachar@gmail.com " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 156*a72f3e2bSNir Tzachar " <Esc> always leaves the current window.\n"), 157692d97c3Snir.tzachar@gmail.com menu_instructions[] = N_( 158692d97c3Snir.tzachar@gmail.com " Arrow keys navigate the menu.\n" 159692d97c3Snir.tzachar@gmail.com " <Enter> or <right-arrow> selects submenus --->.\n" 160692d97c3Snir.tzachar@gmail.com " Capital Letters are hotkeys.\n" 161692d97c3Snir.tzachar@gmail.com " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" 162692d97c3Snir.tzachar@gmail.com " Pressing SpaceBar toggles between the above options\n" 163*a72f3e2bSNir Tzachar " Press <Esc>, <F5> or <left-arrow> to go back one menu,\n" 164692d97c3Snir.tzachar@gmail.com " <?>, <F1> or <h> for Help, </> for Search.\n" 165*a72f3e2bSNir Tzachar " <1> is interchangeable with <F1>, <2> with <F2>, etc.\n" 166692d97c3Snir.tzachar@gmail.com " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 167692d97c3Snir.tzachar@gmail.com " <Esc> always leaves the current window\n"), 168692d97c3Snir.tzachar@gmail.com radiolist_instructions[] = N_( 169692d97c3Snir.tzachar@gmail.com " Use the arrow keys to navigate this window or\n" 170692d97c3Snir.tzachar@gmail.com " press the hotkey of the item you wish to select\n" 171692d97c3Snir.tzachar@gmail.com " followed by the <SPACE BAR>.\n" 172692d97c3Snir.tzachar@gmail.com " Press <?>, <F1> or <h> for additional information about this option.\n"), 173692d97c3Snir.tzachar@gmail.com inputbox_instructions_int[] = N_( 174692d97c3Snir.tzachar@gmail.com "Please enter a decimal value.\n" 175692d97c3Snir.tzachar@gmail.com "Fractions will not be accepted.\n" 176692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."), 177692d97c3Snir.tzachar@gmail.com inputbox_instructions_hex[] = N_( 178692d97c3Snir.tzachar@gmail.com "Please enter a hexadecimal value.\n" 179692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."), 180692d97c3Snir.tzachar@gmail.com inputbox_instructions_string[] = N_( 181692d97c3Snir.tzachar@gmail.com "Please enter a string value.\n" 182692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."), 183692d97c3Snir.tzachar@gmail.com setmod_text[] = N_( 184692d97c3Snir.tzachar@gmail.com "This feature depends on another which\n" 185692d97c3Snir.tzachar@gmail.com "has been configured as a module.\n" 186692d97c3Snir.tzachar@gmail.com "As a result, this feature will be built as a module."), 187692d97c3Snir.tzachar@gmail.com nohelp_text[] = N_( 188692d97c3Snir.tzachar@gmail.com "There is no help available for this kernel option.\n"), 189692d97c3Snir.tzachar@gmail.com load_config_text[] = N_( 190692d97c3Snir.tzachar@gmail.com "Enter the name of the configuration file you wish to load.\n" 191692d97c3Snir.tzachar@gmail.com "Accept the name shown to restore the configuration you\n" 192692d97c3Snir.tzachar@gmail.com "last retrieved. Leave blank to abort."), 193692d97c3Snir.tzachar@gmail.com load_config_help[] = N_( 194692d97c3Snir.tzachar@gmail.com "\n" 195692d97c3Snir.tzachar@gmail.com "For various reasons, one may wish to keep several different kernel\n" 196692d97c3Snir.tzachar@gmail.com "configurations available on a single machine.\n" 197692d97c3Snir.tzachar@gmail.com "\n" 198692d97c3Snir.tzachar@gmail.com "If you have saved a previous configuration in a file other than the\n" 199692d97c3Snir.tzachar@gmail.com "kernel's default, entering the name of the file here will allow you\n" 200692d97c3Snir.tzachar@gmail.com "to modify that configuration.\n" 201692d97c3Snir.tzachar@gmail.com "\n" 202692d97c3Snir.tzachar@gmail.com "If you are uncertain, then you have probably never used alternate\n" 203692d97c3Snir.tzachar@gmail.com "configuration files. You should therefor leave this blank to abort.\n"), 204692d97c3Snir.tzachar@gmail.com save_config_text[] = N_( 205692d97c3Snir.tzachar@gmail.com "Enter a filename to which this configuration should be saved\n" 206692d97c3Snir.tzachar@gmail.com "as an alternate. Leave blank to abort."), 207692d97c3Snir.tzachar@gmail.com save_config_help[] = N_( 208692d97c3Snir.tzachar@gmail.com "\n" 209692d97c3Snir.tzachar@gmail.com "For various reasons, one may wish to keep different kernel\n" 210692d97c3Snir.tzachar@gmail.com "configurations available on a single machine.\n" 211692d97c3Snir.tzachar@gmail.com "\n" 212692d97c3Snir.tzachar@gmail.com "Entering a file name here will allow you to later retrieve, modify\n" 213692d97c3Snir.tzachar@gmail.com "and use the current configuration as an alternate to whatever\n" 214692d97c3Snir.tzachar@gmail.com "configuration options you have selected at that time.\n" 215692d97c3Snir.tzachar@gmail.com "\n" 216692d97c3Snir.tzachar@gmail.com "If you are uncertain what all this means then you should probably\n" 217692d97c3Snir.tzachar@gmail.com "leave this blank.\n"), 218692d97c3Snir.tzachar@gmail.com search_help[] = N_( 219692d97c3Snir.tzachar@gmail.com "\n" 220692d97c3Snir.tzachar@gmail.com "Search for CONFIG_ symbols and display their relations.\n" 221692d97c3Snir.tzachar@gmail.com "Regular expressions are allowed.\n" 222692d97c3Snir.tzachar@gmail.com "Example: search for \"^FOO\"\n" 223692d97c3Snir.tzachar@gmail.com "Result:\n" 224692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n" 225692d97c3Snir.tzachar@gmail.com "Symbol: FOO [ = m]\n" 226692d97c3Snir.tzachar@gmail.com "Prompt: Foo bus is used to drive the bar HW\n" 227692d97c3Snir.tzachar@gmail.com "Defined at drivers/pci/Kconfig:47\n" 228692d97c3Snir.tzachar@gmail.com "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" 229692d97c3Snir.tzachar@gmail.com "Location:\n" 230692d97c3Snir.tzachar@gmail.com " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" 231692d97c3Snir.tzachar@gmail.com " -> PCI support (PCI [ = y])\n" 232692d97c3Snir.tzachar@gmail.com " -> PCI access mode (<choice> [ = y])\n" 233692d97c3Snir.tzachar@gmail.com "Selects: LIBCRC32\n" 234692d97c3Snir.tzachar@gmail.com "Selected by: BAR\n" 235692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n" 236692d97c3Snir.tzachar@gmail.com "o The line 'Prompt:' shows the text used in the menu structure for\n" 237692d97c3Snir.tzachar@gmail.com " this CONFIG_ symbol\n" 238692d97c3Snir.tzachar@gmail.com "o The 'Defined at' line tell at what file / line number the symbol\n" 239692d97c3Snir.tzachar@gmail.com " is defined\n" 240692d97c3Snir.tzachar@gmail.com "o The 'Depends on:' line tell what symbols needs to be defined for\n" 241692d97c3Snir.tzachar@gmail.com " this symbol to be visible in the menu (selectable)\n" 242692d97c3Snir.tzachar@gmail.com "o The 'Location:' lines tell where in the menu structure this symbol\n" 243692d97c3Snir.tzachar@gmail.com " is located\n" 244692d97c3Snir.tzachar@gmail.com " A location followed by a [ = y] indicate that this is a selectable\n" 245692d97c3Snir.tzachar@gmail.com " menu item - and current value is displayed inside brackets.\n" 246692d97c3Snir.tzachar@gmail.com "o The 'Selects:' line tell what symbol will be automatically\n" 247692d97c3Snir.tzachar@gmail.com " selected if this symbol is selected (y or m)\n" 248692d97c3Snir.tzachar@gmail.com "o The 'Selected by' line tell what symbol has selected this symbol\n" 249692d97c3Snir.tzachar@gmail.com "\n" 250692d97c3Snir.tzachar@gmail.com "Only relevant lines are shown.\n" 251692d97c3Snir.tzachar@gmail.com "\n\n" 252692d97c3Snir.tzachar@gmail.com "Search examples:\n" 253692d97c3Snir.tzachar@gmail.com "Examples: USB = > find all CONFIG_ symbols containing USB\n" 254692d97c3Snir.tzachar@gmail.com " ^USB => find all CONFIG_ symbols starting with USB\n" 255692d97c3Snir.tzachar@gmail.com " USB$ => find all CONFIG_ symbols ending with USB\n" 256692d97c3Snir.tzachar@gmail.com "\n"); 257692d97c3Snir.tzachar@gmail.com 258692d97c3Snir.tzachar@gmail.com struct mitem { 259692d97c3Snir.tzachar@gmail.com char str[256]; 260692d97c3Snir.tzachar@gmail.com char tag; 261692d97c3Snir.tzachar@gmail.com void *usrptr; 262692d97c3Snir.tzachar@gmail.com int is_visible; 263692d97c3Snir.tzachar@gmail.com }; 264692d97c3Snir.tzachar@gmail.com 265692d97c3Snir.tzachar@gmail.com #define MAX_MENU_ITEMS 4096 266692d97c3Snir.tzachar@gmail.com static int show_all_items; 267692d97c3Snir.tzachar@gmail.com static int indent; 268692d97c3Snir.tzachar@gmail.com static struct menu *current_menu; 269692d97c3Snir.tzachar@gmail.com static int child_count; 270692d97c3Snir.tzachar@gmail.com static int single_menu_mode; 271692d97c3Snir.tzachar@gmail.com /* the window in which all information appears */ 272692d97c3Snir.tzachar@gmail.com static WINDOW *main_window; 273692d97c3Snir.tzachar@gmail.com /* the largest size of the menu window */ 274692d97c3Snir.tzachar@gmail.com static int mwin_max_lines; 275692d97c3Snir.tzachar@gmail.com static int mwin_max_cols; 276692d97c3Snir.tzachar@gmail.com /* the window in which we show option buttons */ 277692d97c3Snir.tzachar@gmail.com static MENU *curses_menu; 278692d97c3Snir.tzachar@gmail.com static ITEM *curses_menu_items[MAX_MENU_ITEMS]; 279692d97c3Snir.tzachar@gmail.com static struct mitem k_menu_items[MAX_MENU_ITEMS]; 280692d97c3Snir.tzachar@gmail.com static int items_num; 281692d97c3Snir.tzachar@gmail.com static int global_exit; 282692d97c3Snir.tzachar@gmail.com /* the currently selected button */ 283692d97c3Snir.tzachar@gmail.com const char *current_instructions = menu_instructions; 284692d97c3Snir.tzachar@gmail.com 285692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu); 286692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu); 287692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu); 288692d97c3Snir.tzachar@gmail.com static void conf_load(void); 289692d97c3Snir.tzachar@gmail.com static void conf_save(void); 290692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu); 291692d97c3Snir.tzachar@gmail.com static int do_exit(void); 292692d97c3Snir.tzachar@gmail.com static void setup_windows(void); 293*a72f3e2bSNir Tzachar static void search_conf(void); 294692d97c3Snir.tzachar@gmail.com 295692d97c3Snir.tzachar@gmail.com typedef void (*function_key_handler_t)(int *key, struct menu *menu); 296692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item); 297692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item); 298692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item); 299692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item); 300692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item); 301692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item); 302692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item); 303692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item); 304*a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item); 305692d97c3Snir.tzachar@gmail.com 306692d97c3Snir.tzachar@gmail.com struct function_keys { 307692d97c3Snir.tzachar@gmail.com const char *key_str; 308692d97c3Snir.tzachar@gmail.com const char *func; 309692d97c3Snir.tzachar@gmail.com function_key key; 310692d97c3Snir.tzachar@gmail.com function_key_handler_t handler; 311692d97c3Snir.tzachar@gmail.com }; 312692d97c3Snir.tzachar@gmail.com 313*a72f3e2bSNir Tzachar static const int function_keys_num = 9; 314692d97c3Snir.tzachar@gmail.com struct function_keys function_keys[] = { 315692d97c3Snir.tzachar@gmail.com { 316692d97c3Snir.tzachar@gmail.com .key_str = "F1", 317692d97c3Snir.tzachar@gmail.com .func = "Help", 318692d97c3Snir.tzachar@gmail.com .key = F_HELP, 319692d97c3Snir.tzachar@gmail.com .handler = handle_f1, 320692d97c3Snir.tzachar@gmail.com }, 321692d97c3Snir.tzachar@gmail.com { 322692d97c3Snir.tzachar@gmail.com .key_str = "F2", 323*a72f3e2bSNir Tzachar .func = "Sym Info", 324692d97c3Snir.tzachar@gmail.com .key = F_SYMBOL, 325692d97c3Snir.tzachar@gmail.com .handler = handle_f2, 326692d97c3Snir.tzachar@gmail.com }, 327692d97c3Snir.tzachar@gmail.com { 328692d97c3Snir.tzachar@gmail.com .key_str = "F3", 329*a72f3e2bSNir Tzachar .func = "Insts", 330692d97c3Snir.tzachar@gmail.com .key = F_INSTS, 331692d97c3Snir.tzachar@gmail.com .handler = handle_f3, 332692d97c3Snir.tzachar@gmail.com }, 333692d97c3Snir.tzachar@gmail.com { 334692d97c3Snir.tzachar@gmail.com .key_str = "F4", 335692d97c3Snir.tzachar@gmail.com .func = "Config", 336692d97c3Snir.tzachar@gmail.com .key = F_CONF, 337692d97c3Snir.tzachar@gmail.com .handler = handle_f4, 338692d97c3Snir.tzachar@gmail.com }, 339692d97c3Snir.tzachar@gmail.com { 340692d97c3Snir.tzachar@gmail.com .key_str = "F5", 341692d97c3Snir.tzachar@gmail.com .func = "Back", 342692d97c3Snir.tzachar@gmail.com .key = F_BACK, 343692d97c3Snir.tzachar@gmail.com .handler = handle_f5, 344692d97c3Snir.tzachar@gmail.com }, 345692d97c3Snir.tzachar@gmail.com { 346692d97c3Snir.tzachar@gmail.com .key_str = "F6", 347692d97c3Snir.tzachar@gmail.com .func = "Save", 348692d97c3Snir.tzachar@gmail.com .key = F_SAVE, 349692d97c3Snir.tzachar@gmail.com .handler = handle_f6, 350692d97c3Snir.tzachar@gmail.com }, 351692d97c3Snir.tzachar@gmail.com { 352692d97c3Snir.tzachar@gmail.com .key_str = "F7", 353692d97c3Snir.tzachar@gmail.com .func = "Load", 354692d97c3Snir.tzachar@gmail.com .key = F_LOAD, 355692d97c3Snir.tzachar@gmail.com .handler = handle_f7, 356692d97c3Snir.tzachar@gmail.com }, 357692d97c3Snir.tzachar@gmail.com { 358692d97c3Snir.tzachar@gmail.com .key_str = "F8", 359*a72f3e2bSNir Tzachar .func = "Sym Search", 360*a72f3e2bSNir Tzachar .key = F_SEARCH, 361*a72f3e2bSNir Tzachar .handler = handle_f8, 362*a72f3e2bSNir Tzachar }, 363*a72f3e2bSNir Tzachar { 364*a72f3e2bSNir Tzachar .key_str = "F9", 365692d97c3Snir.tzachar@gmail.com .func = "Exit", 366692d97c3Snir.tzachar@gmail.com .key = F_EXIT, 367*a72f3e2bSNir Tzachar .handler = handle_f9, 368692d97c3Snir.tzachar@gmail.com }, 369692d97c3Snir.tzachar@gmail.com }; 370692d97c3Snir.tzachar@gmail.com 371692d97c3Snir.tzachar@gmail.com static void print_function_line(void) 372692d97c3Snir.tzachar@gmail.com { 373692d97c3Snir.tzachar@gmail.com int i; 374692d97c3Snir.tzachar@gmail.com int offset = 1; 375692d97c3Snir.tzachar@gmail.com const int skip = 1; 376692d97c3Snir.tzachar@gmail.com 377692d97c3Snir.tzachar@gmail.com for (i = 0; i < function_keys_num; i++) { 378692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); 379692d97c3Snir.tzachar@gmail.com mvwprintw(main_window, LINES-3, offset, 380692d97c3Snir.tzachar@gmail.com "%s", 381692d97c3Snir.tzachar@gmail.com function_keys[i].key_str); 382692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[FUNCTION_TEXT]); 383692d97c3Snir.tzachar@gmail.com offset += strlen(function_keys[i].key_str); 384692d97c3Snir.tzachar@gmail.com mvwprintw(main_window, LINES-3, 385692d97c3Snir.tzachar@gmail.com offset, "%s", 386692d97c3Snir.tzachar@gmail.com function_keys[i].func); 387692d97c3Snir.tzachar@gmail.com offset += strlen(function_keys[i].func) + skip; 388692d97c3Snir.tzachar@gmail.com } 389692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[NORMAL]); 390692d97c3Snir.tzachar@gmail.com } 391692d97c3Snir.tzachar@gmail.com 392692d97c3Snir.tzachar@gmail.com /* help */ 393692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item) 394692d97c3Snir.tzachar@gmail.com { 395692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 396692d97c3Snir.tzachar@gmail.com _("README"), _(nconf_readme)); 397692d97c3Snir.tzachar@gmail.com return; 398692d97c3Snir.tzachar@gmail.com } 399692d97c3Snir.tzachar@gmail.com 400692d97c3Snir.tzachar@gmail.com /* symbole help */ 401692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item) 402692d97c3Snir.tzachar@gmail.com { 403692d97c3Snir.tzachar@gmail.com show_help(current_item); 404692d97c3Snir.tzachar@gmail.com return; 405692d97c3Snir.tzachar@gmail.com } 406692d97c3Snir.tzachar@gmail.com 407692d97c3Snir.tzachar@gmail.com /* instructions */ 408692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item) 409692d97c3Snir.tzachar@gmail.com { 410692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 411692d97c3Snir.tzachar@gmail.com _("Instructions"), 412692d97c3Snir.tzachar@gmail.com _(current_instructions)); 413692d97c3Snir.tzachar@gmail.com return; 414692d97c3Snir.tzachar@gmail.com } 415692d97c3Snir.tzachar@gmail.com 416692d97c3Snir.tzachar@gmail.com /* config */ 417692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item) 418692d97c3Snir.tzachar@gmail.com { 419692d97c3Snir.tzachar@gmail.com int res = btn_dialog(main_window, 420692d97c3Snir.tzachar@gmail.com _("Show all symbols?"), 421692d97c3Snir.tzachar@gmail.com 2, 422692d97c3Snir.tzachar@gmail.com " <Show All> ", 423692d97c3Snir.tzachar@gmail.com "<Don't show all>"); 424692d97c3Snir.tzachar@gmail.com if (res == 0) 425692d97c3Snir.tzachar@gmail.com show_all_items = 1; 426692d97c3Snir.tzachar@gmail.com else if (res == 1) 427692d97c3Snir.tzachar@gmail.com show_all_items = 0; 428692d97c3Snir.tzachar@gmail.com 429692d97c3Snir.tzachar@gmail.com return; 430692d97c3Snir.tzachar@gmail.com } 431692d97c3Snir.tzachar@gmail.com 432692d97c3Snir.tzachar@gmail.com /* back */ 433692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item) 434692d97c3Snir.tzachar@gmail.com { 435692d97c3Snir.tzachar@gmail.com *key = KEY_LEFT; 436692d97c3Snir.tzachar@gmail.com return; 437692d97c3Snir.tzachar@gmail.com } 438692d97c3Snir.tzachar@gmail.com 439692d97c3Snir.tzachar@gmail.com /* save */ 440692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item) 441692d97c3Snir.tzachar@gmail.com { 442692d97c3Snir.tzachar@gmail.com conf_save(); 443692d97c3Snir.tzachar@gmail.com return; 444692d97c3Snir.tzachar@gmail.com } 445692d97c3Snir.tzachar@gmail.com 446692d97c3Snir.tzachar@gmail.com /* load */ 447692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item) 448692d97c3Snir.tzachar@gmail.com { 449692d97c3Snir.tzachar@gmail.com conf_load(); 450692d97c3Snir.tzachar@gmail.com return; 451692d97c3Snir.tzachar@gmail.com } 452692d97c3Snir.tzachar@gmail.com 453*a72f3e2bSNir Tzachar /* search */ 454692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item) 455692d97c3Snir.tzachar@gmail.com { 456*a72f3e2bSNir Tzachar search_conf(); 457*a72f3e2bSNir Tzachar return; 458*a72f3e2bSNir Tzachar } 459*a72f3e2bSNir Tzachar 460*a72f3e2bSNir Tzachar /* exit */ 461*a72f3e2bSNir Tzachar static void handle_f9(int *key, struct menu *current_item) 462*a72f3e2bSNir Tzachar { 463692d97c3Snir.tzachar@gmail.com do_exit(); 464692d97c3Snir.tzachar@gmail.com return; 465692d97c3Snir.tzachar@gmail.com } 466692d97c3Snir.tzachar@gmail.com 467692d97c3Snir.tzachar@gmail.com /* return != 0 to indicate the key was handles */ 468851190c9SMichal Marek static int process_special_keys(int *key, struct menu *menu) 469692d97c3Snir.tzachar@gmail.com { 470692d97c3Snir.tzachar@gmail.com int i; 471692d97c3Snir.tzachar@gmail.com 472692d97c3Snir.tzachar@gmail.com if (*key == KEY_RESIZE) { 473692d97c3Snir.tzachar@gmail.com setup_windows(); 474692d97c3Snir.tzachar@gmail.com return 1; 475692d97c3Snir.tzachar@gmail.com } 476692d97c3Snir.tzachar@gmail.com 477692d97c3Snir.tzachar@gmail.com for (i = 0; i < function_keys_num; i++) { 478692d97c3Snir.tzachar@gmail.com if (*key == KEY_F(function_keys[i].key) || 479692d97c3Snir.tzachar@gmail.com *key == '0' + function_keys[i].key){ 480692d97c3Snir.tzachar@gmail.com function_keys[i].handler(key, menu); 481692d97c3Snir.tzachar@gmail.com return 1; 482692d97c3Snir.tzachar@gmail.com } 483692d97c3Snir.tzachar@gmail.com } 484692d97c3Snir.tzachar@gmail.com 485692d97c3Snir.tzachar@gmail.com return 0; 486692d97c3Snir.tzachar@gmail.com } 487692d97c3Snir.tzachar@gmail.com 488692d97c3Snir.tzachar@gmail.com static void clean_items(void) 489692d97c3Snir.tzachar@gmail.com { 490692d97c3Snir.tzachar@gmail.com int i; 491692d97c3Snir.tzachar@gmail.com for (i = 0; curses_menu_items[i]; i++) 492692d97c3Snir.tzachar@gmail.com free_item(curses_menu_items[i]); 493692d97c3Snir.tzachar@gmail.com bzero(curses_menu_items, sizeof(curses_menu_items)); 494692d97c3Snir.tzachar@gmail.com bzero(k_menu_items, sizeof(k_menu_items)); 495692d97c3Snir.tzachar@gmail.com items_num = 0; 496692d97c3Snir.tzachar@gmail.com } 497692d97c3Snir.tzachar@gmail.com 498*a72f3e2bSNir Tzachar typedef enum {MATCH_TINKER_PATTERN_UP, MATCH_TINKER_PATTERN_DOWN, 499*a72f3e2bSNir Tzachar FIND_NEXT_MATCH_DOWN, FIND_NEXT_MATCH_UP} match_f; 500692d97c3Snir.tzachar@gmail.com 501*a72f3e2bSNir Tzachar /* return the index of the matched item, or -1 if no such item exists */ 502*a72f3e2bSNir Tzachar static int get_mext_match(const char *match_str, match_f flag) 503*a72f3e2bSNir Tzachar { 504*a72f3e2bSNir Tzachar int match_start = item_index(current_item(curses_menu)); 505*a72f3e2bSNir Tzachar int index; 506*a72f3e2bSNir Tzachar 507*a72f3e2bSNir Tzachar if (flag == FIND_NEXT_MATCH_DOWN) 508*a72f3e2bSNir Tzachar ++match_start; 509*a72f3e2bSNir Tzachar else if (flag == FIND_NEXT_MATCH_UP) 510*a72f3e2bSNir Tzachar --match_start; 511*a72f3e2bSNir Tzachar 512*a72f3e2bSNir Tzachar index = match_start; 513*a72f3e2bSNir Tzachar index = (index + items_num) % items_num; 514*a72f3e2bSNir Tzachar while (true) { 515*a72f3e2bSNir Tzachar char *str = k_menu_items[index].str; 516*a72f3e2bSNir Tzachar if (strcasestr(str, match_str) != 0) 517*a72f3e2bSNir Tzachar return index; 518*a72f3e2bSNir Tzachar if (flag == FIND_NEXT_MATCH_UP || 519*a72f3e2bSNir Tzachar flag == MATCH_TINKER_PATTERN_UP) 520*a72f3e2bSNir Tzachar --index; 521*a72f3e2bSNir Tzachar else 522*a72f3e2bSNir Tzachar ++index; 523*a72f3e2bSNir Tzachar index = (index + items_num) % items_num; 524*a72f3e2bSNir Tzachar if (index == match_start) 525692d97c3Snir.tzachar@gmail.com return -1; 526692d97c3Snir.tzachar@gmail.com } 527692d97c3Snir.tzachar@gmail.com } 528692d97c3Snir.tzachar@gmail.com 529*a72f3e2bSNir Tzachar /* Make a new item. */ 530851190c9SMichal Marek static void item_make(struct menu *menu, char tag, const char *fmt, ...) 531692d97c3Snir.tzachar@gmail.com { 532692d97c3Snir.tzachar@gmail.com va_list ap; 533692d97c3Snir.tzachar@gmail.com 534692d97c3Snir.tzachar@gmail.com if (items_num > MAX_MENU_ITEMS-1) 535692d97c3Snir.tzachar@gmail.com return; 536692d97c3Snir.tzachar@gmail.com 537692d97c3Snir.tzachar@gmail.com bzero(&k_menu_items[items_num], sizeof(k_menu_items[0])); 538692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].tag = tag; 539692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].usrptr = menu; 540692d97c3Snir.tzachar@gmail.com if (menu != NULL) 541692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].is_visible = 542692d97c3Snir.tzachar@gmail.com menu_is_visible(menu); 543692d97c3Snir.tzachar@gmail.com else 544692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].is_visible = 1; 545692d97c3Snir.tzachar@gmail.com 546692d97c3Snir.tzachar@gmail.com va_start(ap, fmt); 547*a72f3e2bSNir Tzachar vsnprintf(k_menu_items[items_num].str, 548*a72f3e2bSNir Tzachar sizeof(k_menu_items[items_num].str), 549*a72f3e2bSNir Tzachar fmt, ap); 550692d97c3Snir.tzachar@gmail.com va_end(ap); 551*a72f3e2bSNir Tzachar 552*a72f3e2bSNir Tzachar if (!k_menu_items[items_num].is_visible) 553*a72f3e2bSNir Tzachar memcpy(k_menu_items[items_num].str, "XXX", 3); 554692d97c3Snir.tzachar@gmail.com 555692d97c3Snir.tzachar@gmail.com curses_menu_items[items_num] = new_item( 556692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].str, 557692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].str); 558692d97c3Snir.tzachar@gmail.com set_item_userptr(curses_menu_items[items_num], 559692d97c3Snir.tzachar@gmail.com &k_menu_items[items_num]); 560692d97c3Snir.tzachar@gmail.com /* 561692d97c3Snir.tzachar@gmail.com if (!k_menu_items[items_num].is_visible) 562692d97c3Snir.tzachar@gmail.com item_opts_off(curses_menu_items[items_num], O_SELECTABLE); 563692d97c3Snir.tzachar@gmail.com */ 564692d97c3Snir.tzachar@gmail.com 565692d97c3Snir.tzachar@gmail.com items_num++; 566692d97c3Snir.tzachar@gmail.com curses_menu_items[items_num] = NULL; 567692d97c3Snir.tzachar@gmail.com } 568692d97c3Snir.tzachar@gmail.com 569692d97c3Snir.tzachar@gmail.com /* very hackish. adds a string to the last item added */ 570851190c9SMichal Marek static void item_add_str(const char *fmt, ...) 571692d97c3Snir.tzachar@gmail.com { 572692d97c3Snir.tzachar@gmail.com va_list ap; 573692d97c3Snir.tzachar@gmail.com int index = items_num-1; 574692d97c3Snir.tzachar@gmail.com char new_str[256]; 575692d97c3Snir.tzachar@gmail.com char tmp_str[256]; 576692d97c3Snir.tzachar@gmail.com 577692d97c3Snir.tzachar@gmail.com if (index < 0) 578692d97c3Snir.tzachar@gmail.com return; 579692d97c3Snir.tzachar@gmail.com 580692d97c3Snir.tzachar@gmail.com va_start(ap, fmt); 581692d97c3Snir.tzachar@gmail.com vsnprintf(new_str, sizeof(new_str), fmt, ap); 582692d97c3Snir.tzachar@gmail.com va_end(ap); 583692d97c3Snir.tzachar@gmail.com snprintf(tmp_str, sizeof(tmp_str), "%s%s", 584692d97c3Snir.tzachar@gmail.com k_menu_items[index].str, new_str); 585692d97c3Snir.tzachar@gmail.com strncpy(k_menu_items[index].str, 586692d97c3Snir.tzachar@gmail.com tmp_str, 587692d97c3Snir.tzachar@gmail.com sizeof(k_menu_items[index].str)); 588692d97c3Snir.tzachar@gmail.com 589692d97c3Snir.tzachar@gmail.com free_item(curses_menu_items[index]); 590692d97c3Snir.tzachar@gmail.com curses_menu_items[index] = new_item( 591692d97c3Snir.tzachar@gmail.com k_menu_items[index].str, 592692d97c3Snir.tzachar@gmail.com k_menu_items[index].str); 593692d97c3Snir.tzachar@gmail.com set_item_userptr(curses_menu_items[index], 594692d97c3Snir.tzachar@gmail.com &k_menu_items[index]); 595692d97c3Snir.tzachar@gmail.com } 596692d97c3Snir.tzachar@gmail.com 597692d97c3Snir.tzachar@gmail.com /* get the tag of the currently selected item */ 598851190c9SMichal Marek static char item_tag(void) 599692d97c3Snir.tzachar@gmail.com { 600692d97c3Snir.tzachar@gmail.com ITEM *cur; 601692d97c3Snir.tzachar@gmail.com struct mitem *mcur; 602692d97c3Snir.tzachar@gmail.com 603692d97c3Snir.tzachar@gmail.com cur = current_item(curses_menu); 604692d97c3Snir.tzachar@gmail.com if (cur == NULL) 605692d97c3Snir.tzachar@gmail.com return 0; 606692d97c3Snir.tzachar@gmail.com mcur = (struct mitem *) item_userptr(cur); 607692d97c3Snir.tzachar@gmail.com return mcur->tag; 608692d97c3Snir.tzachar@gmail.com } 609692d97c3Snir.tzachar@gmail.com 610851190c9SMichal Marek static int curses_item_index(void) 611692d97c3Snir.tzachar@gmail.com { 612692d97c3Snir.tzachar@gmail.com return item_index(current_item(curses_menu)); 613692d97c3Snir.tzachar@gmail.com } 614692d97c3Snir.tzachar@gmail.com 615851190c9SMichal Marek static void *item_data(void) 616692d97c3Snir.tzachar@gmail.com { 617692d97c3Snir.tzachar@gmail.com ITEM *cur; 618692d97c3Snir.tzachar@gmail.com struct mitem *mcur; 619692d97c3Snir.tzachar@gmail.com 620692d97c3Snir.tzachar@gmail.com cur = current_item(curses_menu); 621866af407SAndrej Gelenberg if (!cur) 622866af407SAndrej Gelenberg return NULL; 623692d97c3Snir.tzachar@gmail.com mcur = (struct mitem *) item_userptr(cur); 624692d97c3Snir.tzachar@gmail.com return mcur->usrptr; 625692d97c3Snir.tzachar@gmail.com 626692d97c3Snir.tzachar@gmail.com } 627692d97c3Snir.tzachar@gmail.com 628851190c9SMichal Marek static int item_is_tag(char tag) 629692d97c3Snir.tzachar@gmail.com { 630692d97c3Snir.tzachar@gmail.com return item_tag() == tag; 631692d97c3Snir.tzachar@gmail.com } 632692d97c3Snir.tzachar@gmail.com 633692d97c3Snir.tzachar@gmail.com static char filename[PATH_MAX+1]; 634692d97c3Snir.tzachar@gmail.com static char menu_backtitle[PATH_MAX+128]; 635851190c9SMichal Marek static const char *set_config_filename(const char *config_filename) 636692d97c3Snir.tzachar@gmail.com { 637692d97c3Snir.tzachar@gmail.com int size; 638692d97c3Snir.tzachar@gmail.com struct symbol *sym; 639692d97c3Snir.tzachar@gmail.com 640692d97c3Snir.tzachar@gmail.com sym = sym_lookup("KERNELVERSION", 0); 641692d97c3Snir.tzachar@gmail.com sym_calc_value(sym); 642692d97c3Snir.tzachar@gmail.com size = snprintf(menu_backtitle, sizeof(menu_backtitle), 643692d97c3Snir.tzachar@gmail.com _("%s - Linux Kernel v%s Configuration"), 644692d97c3Snir.tzachar@gmail.com config_filename, sym_get_string_value(sym)); 645692d97c3Snir.tzachar@gmail.com if (size >= sizeof(menu_backtitle)) 646692d97c3Snir.tzachar@gmail.com menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; 647692d97c3Snir.tzachar@gmail.com 648692d97c3Snir.tzachar@gmail.com size = snprintf(filename, sizeof(filename), "%s", config_filename); 649692d97c3Snir.tzachar@gmail.com if (size >= sizeof(filename)) 650692d97c3Snir.tzachar@gmail.com filename[sizeof(filename)-1] = '\0'; 651692d97c3Snir.tzachar@gmail.com return menu_backtitle; 652692d97c3Snir.tzachar@gmail.com } 653692d97c3Snir.tzachar@gmail.com 654692d97c3Snir.tzachar@gmail.com /* command = 0 is supress, 1 is restore */ 655692d97c3Snir.tzachar@gmail.com static void supress_stdout(int command) 656692d97c3Snir.tzachar@gmail.com { 657692d97c3Snir.tzachar@gmail.com static FILE *org_stdout; 658692d97c3Snir.tzachar@gmail.com static FILE *org_stderr; 659692d97c3Snir.tzachar@gmail.com 660692d97c3Snir.tzachar@gmail.com if (command == 0) { 661692d97c3Snir.tzachar@gmail.com org_stdout = stdout; 662692d97c3Snir.tzachar@gmail.com org_stderr = stderr; 663692d97c3Snir.tzachar@gmail.com stdout = fopen("/dev/null", "a"); 664692d97c3Snir.tzachar@gmail.com stderr = fopen("/dev/null", "a"); 665692d97c3Snir.tzachar@gmail.com } else { 666692d97c3Snir.tzachar@gmail.com fclose(stdout); 667692d97c3Snir.tzachar@gmail.com fclose(stderr); 668692d97c3Snir.tzachar@gmail.com stdout = org_stdout; 669692d97c3Snir.tzachar@gmail.com stderr = org_stderr; 670692d97c3Snir.tzachar@gmail.com } 671692d97c3Snir.tzachar@gmail.com } 672692d97c3Snir.tzachar@gmail.com 673692d97c3Snir.tzachar@gmail.com /* return = 0 means we are successful. 674692d97c3Snir.tzachar@gmail.com * -1 means go on doing what you were doing 675692d97c3Snir.tzachar@gmail.com */ 676692d97c3Snir.tzachar@gmail.com static int do_exit(void) 677692d97c3Snir.tzachar@gmail.com { 678692d97c3Snir.tzachar@gmail.com int res; 679692d97c3Snir.tzachar@gmail.com if (!conf_get_changed()) { 680692d97c3Snir.tzachar@gmail.com global_exit = 1; 681692d97c3Snir.tzachar@gmail.com return 0; 682692d97c3Snir.tzachar@gmail.com } 683692d97c3Snir.tzachar@gmail.com res = btn_dialog(main_window, 684692d97c3Snir.tzachar@gmail.com _("Do you wish to save your " 685692d97c3Snir.tzachar@gmail.com "new kernel configuration?\n" 686692d97c3Snir.tzachar@gmail.com "<ESC> to cancel and resume nconfig."), 687692d97c3Snir.tzachar@gmail.com 2, 688692d97c3Snir.tzachar@gmail.com " <save> ", 689692d97c3Snir.tzachar@gmail.com "<don't save>"); 690692d97c3Snir.tzachar@gmail.com if (res == KEY_EXIT) { 691692d97c3Snir.tzachar@gmail.com global_exit = 0; 692692d97c3Snir.tzachar@gmail.com return -1; 693692d97c3Snir.tzachar@gmail.com } 694692d97c3Snir.tzachar@gmail.com 695692d97c3Snir.tzachar@gmail.com /* if we got here, the user really wants to exit */ 696692d97c3Snir.tzachar@gmail.com switch (res) { 697692d97c3Snir.tzachar@gmail.com case 0: 698692d97c3Snir.tzachar@gmail.com supress_stdout(0); 699692d97c3Snir.tzachar@gmail.com res = conf_write(filename); 700692d97c3Snir.tzachar@gmail.com supress_stdout(1); 701692d97c3Snir.tzachar@gmail.com if (res) 702692d97c3Snir.tzachar@gmail.com btn_dialog( 703692d97c3Snir.tzachar@gmail.com main_window, 704692d97c3Snir.tzachar@gmail.com _("Error during writing of the kernel " 705692d97c3Snir.tzachar@gmail.com "configuration.\n" 706692d97c3Snir.tzachar@gmail.com "Your kernel configuration " 707692d97c3Snir.tzachar@gmail.com "changes were NOT saved."), 708692d97c3Snir.tzachar@gmail.com 1, 709692d97c3Snir.tzachar@gmail.com "<OK>"); 710692d97c3Snir.tzachar@gmail.com else { 711692d97c3Snir.tzachar@gmail.com char buf[1024]; 712692d97c3Snir.tzachar@gmail.com snprintf(buf, 1024, 713692d97c3Snir.tzachar@gmail.com _("Configuration written to %s\n" 714692d97c3Snir.tzachar@gmail.com "End of Linux kernel configuration.\n" 715692d97c3Snir.tzachar@gmail.com "Execute 'make' to build the kernel or try" 716692d97c3Snir.tzachar@gmail.com " 'make help'."), filename); 717692d97c3Snir.tzachar@gmail.com btn_dialog( 718692d97c3Snir.tzachar@gmail.com main_window, 719692d97c3Snir.tzachar@gmail.com buf, 720692d97c3Snir.tzachar@gmail.com 1, 721692d97c3Snir.tzachar@gmail.com "<OK>"); 722692d97c3Snir.tzachar@gmail.com } 723692d97c3Snir.tzachar@gmail.com break; 724692d97c3Snir.tzachar@gmail.com default: 725692d97c3Snir.tzachar@gmail.com btn_dialog( 726692d97c3Snir.tzachar@gmail.com main_window, 727692d97c3Snir.tzachar@gmail.com _("Your kernel configuration changes were NOT saved."), 728692d97c3Snir.tzachar@gmail.com 1, 729692d97c3Snir.tzachar@gmail.com "<OK>"); 730692d97c3Snir.tzachar@gmail.com break; 731692d97c3Snir.tzachar@gmail.com } 732692d97c3Snir.tzachar@gmail.com global_exit = 1; 733692d97c3Snir.tzachar@gmail.com return 0; 734692d97c3Snir.tzachar@gmail.com } 735692d97c3Snir.tzachar@gmail.com 736692d97c3Snir.tzachar@gmail.com 737692d97c3Snir.tzachar@gmail.com static void search_conf(void) 738692d97c3Snir.tzachar@gmail.com { 739692d97c3Snir.tzachar@gmail.com struct symbol **sym_arr; 740692d97c3Snir.tzachar@gmail.com struct gstr res; 741692d97c3Snir.tzachar@gmail.com char dialog_input_result[100]; 742692d97c3Snir.tzachar@gmail.com char *dialog_input; 743692d97c3Snir.tzachar@gmail.com int dres; 744692d97c3Snir.tzachar@gmail.com again: 745692d97c3Snir.tzachar@gmail.com dres = dialog_inputbox(main_window, 746692d97c3Snir.tzachar@gmail.com _("Search Configuration Parameter"), 747692d97c3Snir.tzachar@gmail.com _("Enter CONFIG_ (sub)string to search for " 748692d97c3Snir.tzachar@gmail.com "(with or without \"CONFIG\")"), 749692d97c3Snir.tzachar@gmail.com "", dialog_input_result, 99); 750692d97c3Snir.tzachar@gmail.com switch (dres) { 751692d97c3Snir.tzachar@gmail.com case 0: 752692d97c3Snir.tzachar@gmail.com break; 753692d97c3Snir.tzachar@gmail.com case 1: 754692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 755692d97c3Snir.tzachar@gmail.com _("Search Configuration"), search_help); 756692d97c3Snir.tzachar@gmail.com goto again; 757692d97c3Snir.tzachar@gmail.com default: 758692d97c3Snir.tzachar@gmail.com return; 759692d97c3Snir.tzachar@gmail.com } 760692d97c3Snir.tzachar@gmail.com 761692d97c3Snir.tzachar@gmail.com /* strip CONFIG_ if necessary */ 762692d97c3Snir.tzachar@gmail.com dialog_input = dialog_input_result; 763692d97c3Snir.tzachar@gmail.com if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) 764692d97c3Snir.tzachar@gmail.com dialog_input += 7; 765692d97c3Snir.tzachar@gmail.com 766692d97c3Snir.tzachar@gmail.com sym_arr = sym_re_search(dialog_input); 767692d97c3Snir.tzachar@gmail.com res = get_relations_str(sym_arr); 768692d97c3Snir.tzachar@gmail.com free(sym_arr); 769692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 770692d97c3Snir.tzachar@gmail.com _("Search Results"), str_get(&res)); 771692d97c3Snir.tzachar@gmail.com str_free(&res); 772692d97c3Snir.tzachar@gmail.com } 773692d97c3Snir.tzachar@gmail.com 774692d97c3Snir.tzachar@gmail.com 775692d97c3Snir.tzachar@gmail.com static void build_conf(struct menu *menu) 776692d97c3Snir.tzachar@gmail.com { 777692d97c3Snir.tzachar@gmail.com struct symbol *sym; 778692d97c3Snir.tzachar@gmail.com struct property *prop; 779692d97c3Snir.tzachar@gmail.com struct menu *child; 780692d97c3Snir.tzachar@gmail.com int type, tmp, doint = 2; 781692d97c3Snir.tzachar@gmail.com tristate val; 782692d97c3Snir.tzachar@gmail.com char ch; 783692d97c3Snir.tzachar@gmail.com 784692d97c3Snir.tzachar@gmail.com if (!menu || (!show_all_items && !menu_is_visible(menu))) 785692d97c3Snir.tzachar@gmail.com return; 786692d97c3Snir.tzachar@gmail.com 787692d97c3Snir.tzachar@gmail.com sym = menu->sym; 788692d97c3Snir.tzachar@gmail.com prop = menu->prompt; 789692d97c3Snir.tzachar@gmail.com if (!sym) { 790692d97c3Snir.tzachar@gmail.com if (prop && menu != current_menu) { 791692d97c3Snir.tzachar@gmail.com const char *prompt = menu_get_prompt(menu); 792692d97c3Snir.tzachar@gmail.com enum prop_type ptype; 793692d97c3Snir.tzachar@gmail.com ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 794692d97c3Snir.tzachar@gmail.com switch (ptype) { 795692d97c3Snir.tzachar@gmail.com case P_MENU: 796692d97c3Snir.tzachar@gmail.com child_count++; 797692d97c3Snir.tzachar@gmail.com prompt = _(prompt); 798692d97c3Snir.tzachar@gmail.com if (single_menu_mode) { 799692d97c3Snir.tzachar@gmail.com item_make(menu, 'm', 800692d97c3Snir.tzachar@gmail.com "%s%*c%s", 801692d97c3Snir.tzachar@gmail.com menu->data ? "-->" : "++>", 802692d97c3Snir.tzachar@gmail.com indent + 1, ' ', prompt); 803692d97c3Snir.tzachar@gmail.com } else 804692d97c3Snir.tzachar@gmail.com item_make(menu, 'm', 805692d97c3Snir.tzachar@gmail.com " %*c%s --->", 806692d97c3Snir.tzachar@gmail.com indent + 1, 807692d97c3Snir.tzachar@gmail.com ' ', prompt); 808692d97c3Snir.tzachar@gmail.com 809692d97c3Snir.tzachar@gmail.com if (single_menu_mode && menu->data) 810692d97c3Snir.tzachar@gmail.com goto conf_childs; 811692d97c3Snir.tzachar@gmail.com return; 812692d97c3Snir.tzachar@gmail.com case P_COMMENT: 813692d97c3Snir.tzachar@gmail.com if (prompt) { 814692d97c3Snir.tzachar@gmail.com child_count++; 815692d97c3Snir.tzachar@gmail.com item_make(menu, ':', 816692d97c3Snir.tzachar@gmail.com " %*c*** %s ***", 817692d97c3Snir.tzachar@gmail.com indent + 1, ' ', 818692d97c3Snir.tzachar@gmail.com _(prompt)); 819692d97c3Snir.tzachar@gmail.com } 820692d97c3Snir.tzachar@gmail.com break; 821692d97c3Snir.tzachar@gmail.com default: 822692d97c3Snir.tzachar@gmail.com if (prompt) { 823692d97c3Snir.tzachar@gmail.com child_count++; 824692d97c3Snir.tzachar@gmail.com item_make(menu, ':', "---%*c%s", 825692d97c3Snir.tzachar@gmail.com indent + 1, ' ', 826692d97c3Snir.tzachar@gmail.com _(prompt)); 827692d97c3Snir.tzachar@gmail.com } 828692d97c3Snir.tzachar@gmail.com } 829692d97c3Snir.tzachar@gmail.com } else 830692d97c3Snir.tzachar@gmail.com doint = 0; 831692d97c3Snir.tzachar@gmail.com goto conf_childs; 832692d97c3Snir.tzachar@gmail.com } 833692d97c3Snir.tzachar@gmail.com 834692d97c3Snir.tzachar@gmail.com type = sym_get_type(sym); 835692d97c3Snir.tzachar@gmail.com if (sym_is_choice(sym)) { 836692d97c3Snir.tzachar@gmail.com struct symbol *def_sym = sym_get_choice_value(sym); 837692d97c3Snir.tzachar@gmail.com struct menu *def_menu = NULL; 838692d97c3Snir.tzachar@gmail.com 839692d97c3Snir.tzachar@gmail.com child_count++; 840692d97c3Snir.tzachar@gmail.com for (child = menu->list; child; child = child->next) { 841692d97c3Snir.tzachar@gmail.com if (menu_is_visible(child) && child->sym == def_sym) 842692d97c3Snir.tzachar@gmail.com def_menu = child; 843692d97c3Snir.tzachar@gmail.com } 844692d97c3Snir.tzachar@gmail.com 845692d97c3Snir.tzachar@gmail.com val = sym_get_tristate_value(sym); 846692d97c3Snir.tzachar@gmail.com if (sym_is_changable(sym)) { 847692d97c3Snir.tzachar@gmail.com switch (type) { 848692d97c3Snir.tzachar@gmail.com case S_BOOLEAN: 849692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "[%c]", 850692d97c3Snir.tzachar@gmail.com val == no ? ' ' : '*'); 851692d97c3Snir.tzachar@gmail.com break; 852692d97c3Snir.tzachar@gmail.com case S_TRISTATE: 853692d97c3Snir.tzachar@gmail.com switch (val) { 854692d97c3Snir.tzachar@gmail.com case yes: 855692d97c3Snir.tzachar@gmail.com ch = '*'; 856692d97c3Snir.tzachar@gmail.com break; 857692d97c3Snir.tzachar@gmail.com case mod: 858692d97c3Snir.tzachar@gmail.com ch = 'M'; 859692d97c3Snir.tzachar@gmail.com break; 860692d97c3Snir.tzachar@gmail.com default: 861692d97c3Snir.tzachar@gmail.com ch = ' '; 862692d97c3Snir.tzachar@gmail.com break; 863692d97c3Snir.tzachar@gmail.com } 864692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "<%c>", ch); 865692d97c3Snir.tzachar@gmail.com break; 866692d97c3Snir.tzachar@gmail.com } 867692d97c3Snir.tzachar@gmail.com } else { 868692d97c3Snir.tzachar@gmail.com item_make(menu, def_menu ? 't' : ':', " "); 869692d97c3Snir.tzachar@gmail.com } 870692d97c3Snir.tzachar@gmail.com 871692d97c3Snir.tzachar@gmail.com item_add_str("%*c%s", indent + 1, 872692d97c3Snir.tzachar@gmail.com ' ', _(menu_get_prompt(menu))); 873692d97c3Snir.tzachar@gmail.com if (val == yes) { 874692d97c3Snir.tzachar@gmail.com if (def_menu) { 875692d97c3Snir.tzachar@gmail.com item_add_str(" (%s)", 876692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(def_menu))); 877692d97c3Snir.tzachar@gmail.com item_add_str(" --->"); 878692d97c3Snir.tzachar@gmail.com if (def_menu->list) { 879692d97c3Snir.tzachar@gmail.com indent += 2; 880692d97c3Snir.tzachar@gmail.com build_conf(def_menu); 881692d97c3Snir.tzachar@gmail.com indent -= 2; 882692d97c3Snir.tzachar@gmail.com } 883692d97c3Snir.tzachar@gmail.com } 884692d97c3Snir.tzachar@gmail.com return; 885692d97c3Snir.tzachar@gmail.com } 886692d97c3Snir.tzachar@gmail.com } else { 887692d97c3Snir.tzachar@gmail.com if (menu == current_menu) { 888692d97c3Snir.tzachar@gmail.com item_make(menu, ':', 889692d97c3Snir.tzachar@gmail.com "---%*c%s", indent + 1, 890692d97c3Snir.tzachar@gmail.com ' ', _(menu_get_prompt(menu))); 891692d97c3Snir.tzachar@gmail.com goto conf_childs; 892692d97c3Snir.tzachar@gmail.com } 893692d97c3Snir.tzachar@gmail.com child_count++; 894692d97c3Snir.tzachar@gmail.com val = sym_get_tristate_value(sym); 895692d97c3Snir.tzachar@gmail.com if (sym_is_choice_value(sym) && val == yes) { 896692d97c3Snir.tzachar@gmail.com item_make(menu, ':', " "); 897692d97c3Snir.tzachar@gmail.com } else { 898692d97c3Snir.tzachar@gmail.com switch (type) { 899692d97c3Snir.tzachar@gmail.com case S_BOOLEAN: 900692d97c3Snir.tzachar@gmail.com if (sym_is_changable(sym)) 901692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "[%c]", 902692d97c3Snir.tzachar@gmail.com val == no ? ' ' : '*'); 903692d97c3Snir.tzachar@gmail.com else 904692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "-%c-", 905692d97c3Snir.tzachar@gmail.com val == no ? ' ' : '*'); 906692d97c3Snir.tzachar@gmail.com break; 907692d97c3Snir.tzachar@gmail.com case S_TRISTATE: 908692d97c3Snir.tzachar@gmail.com switch (val) { 909692d97c3Snir.tzachar@gmail.com case yes: 910692d97c3Snir.tzachar@gmail.com ch = '*'; 911692d97c3Snir.tzachar@gmail.com break; 912692d97c3Snir.tzachar@gmail.com case mod: 913692d97c3Snir.tzachar@gmail.com ch = 'M'; 914692d97c3Snir.tzachar@gmail.com break; 915692d97c3Snir.tzachar@gmail.com default: 916692d97c3Snir.tzachar@gmail.com ch = ' '; 917692d97c3Snir.tzachar@gmail.com break; 918692d97c3Snir.tzachar@gmail.com } 919692d97c3Snir.tzachar@gmail.com if (sym_is_changable(sym)) { 920692d97c3Snir.tzachar@gmail.com if (sym->rev_dep.tri == mod) 921692d97c3Snir.tzachar@gmail.com item_make(menu, 922692d97c3Snir.tzachar@gmail.com 't', "{%c}", ch); 923692d97c3Snir.tzachar@gmail.com else 924692d97c3Snir.tzachar@gmail.com item_make(menu, 925692d97c3Snir.tzachar@gmail.com 't', "<%c>", ch); 926692d97c3Snir.tzachar@gmail.com } else 927692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "-%c-", ch); 928692d97c3Snir.tzachar@gmail.com break; 929692d97c3Snir.tzachar@gmail.com default: 930692d97c3Snir.tzachar@gmail.com tmp = 2 + strlen(sym_get_string_value(sym)); 931692d97c3Snir.tzachar@gmail.com item_make(menu, 's', " (%s)", 932692d97c3Snir.tzachar@gmail.com sym_get_string_value(sym)); 933692d97c3Snir.tzachar@gmail.com tmp = indent - tmp + 4; 934692d97c3Snir.tzachar@gmail.com if (tmp < 0) 935692d97c3Snir.tzachar@gmail.com tmp = 0; 936692d97c3Snir.tzachar@gmail.com item_add_str("%*c%s%s", tmp, ' ', 937692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(menu)), 938692d97c3Snir.tzachar@gmail.com (sym_has_value(sym) || 939692d97c3Snir.tzachar@gmail.com !sym_is_changable(sym)) ? "" : 940692d97c3Snir.tzachar@gmail.com _(" (NEW)")); 941692d97c3Snir.tzachar@gmail.com goto conf_childs; 942692d97c3Snir.tzachar@gmail.com } 943692d97c3Snir.tzachar@gmail.com } 944692d97c3Snir.tzachar@gmail.com item_add_str("%*c%s%s", indent + 1, ' ', 945692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(menu)), 946692d97c3Snir.tzachar@gmail.com (sym_has_value(sym) || !sym_is_changable(sym)) ? 947692d97c3Snir.tzachar@gmail.com "" : _(" (NEW)")); 948692d97c3Snir.tzachar@gmail.com if (menu->prompt && menu->prompt->type == P_MENU) { 949692d97c3Snir.tzachar@gmail.com item_add_str(" --->"); 950692d97c3Snir.tzachar@gmail.com return; 951692d97c3Snir.tzachar@gmail.com } 952692d97c3Snir.tzachar@gmail.com } 953692d97c3Snir.tzachar@gmail.com 954692d97c3Snir.tzachar@gmail.com conf_childs: 955692d97c3Snir.tzachar@gmail.com indent += doint; 956692d97c3Snir.tzachar@gmail.com for (child = menu->list; child; child = child->next) 957692d97c3Snir.tzachar@gmail.com build_conf(child); 958692d97c3Snir.tzachar@gmail.com indent -= doint; 959692d97c3Snir.tzachar@gmail.com } 960692d97c3Snir.tzachar@gmail.com 961692d97c3Snir.tzachar@gmail.com static void reset_menu(void) 962692d97c3Snir.tzachar@gmail.com { 963692d97c3Snir.tzachar@gmail.com unpost_menu(curses_menu); 964692d97c3Snir.tzachar@gmail.com clean_items(); 965692d97c3Snir.tzachar@gmail.com } 966692d97c3Snir.tzachar@gmail.com 967692d97c3Snir.tzachar@gmail.com /* adjust the menu to show this item. 968692d97c3Snir.tzachar@gmail.com * prefer not to scroll the menu if possible*/ 969692d97c3Snir.tzachar@gmail.com static void center_item(int selected_index, int *last_top_row) 970692d97c3Snir.tzachar@gmail.com { 971692d97c3Snir.tzachar@gmail.com int toprow; 972692d97c3Snir.tzachar@gmail.com 973692d97c3Snir.tzachar@gmail.com set_top_row(curses_menu, *last_top_row); 974692d97c3Snir.tzachar@gmail.com toprow = top_row(curses_menu); 975*a72f3e2bSNir Tzachar if (selected_index < toprow || 976*a72f3e2bSNir Tzachar selected_index >= toprow+mwin_max_lines) { 977*a72f3e2bSNir Tzachar toprow = max(selected_index-mwin_max_lines/2, 0); 978*a72f3e2bSNir Tzachar if (toprow >= item_count(curses_menu)-mwin_max_lines) 979692d97c3Snir.tzachar@gmail.com toprow = item_count(curses_menu)-mwin_max_lines; 980692d97c3Snir.tzachar@gmail.com set_top_row(curses_menu, toprow); 981*a72f3e2bSNir Tzachar } 982692d97c3Snir.tzachar@gmail.com set_current_item(curses_menu, 983692d97c3Snir.tzachar@gmail.com curses_menu_items[selected_index]); 984692d97c3Snir.tzachar@gmail.com *last_top_row = toprow; 985692d97c3Snir.tzachar@gmail.com post_menu(curses_menu); 986692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 987692d97c3Snir.tzachar@gmail.com } 988692d97c3Snir.tzachar@gmail.com 989692d97c3Snir.tzachar@gmail.com /* this function assumes reset_menu has been called before */ 990692d97c3Snir.tzachar@gmail.com static void show_menu(const char *prompt, const char *instructions, 991692d97c3Snir.tzachar@gmail.com int selected_index, int *last_top_row) 992692d97c3Snir.tzachar@gmail.com { 993692d97c3Snir.tzachar@gmail.com int maxx, maxy; 994692d97c3Snir.tzachar@gmail.com WINDOW *menu_window; 995692d97c3Snir.tzachar@gmail.com 996692d97c3Snir.tzachar@gmail.com current_instructions = instructions; 997692d97c3Snir.tzachar@gmail.com 998692d97c3Snir.tzachar@gmail.com clear(); 999692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[NORMAL]); 1000692d97c3Snir.tzachar@gmail.com print_in_middle(stdscr, 1, 0, COLS, 1001692d97c3Snir.tzachar@gmail.com menu_backtitle, 1002692d97c3Snir.tzachar@gmail.com attributes[MAIN_HEADING]); 1003692d97c3Snir.tzachar@gmail.com 1004692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[MAIN_MENU_BOX]); 1005692d97c3Snir.tzachar@gmail.com box(main_window, 0, 0); 1006692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[MAIN_MENU_HEADING]); 1007692d97c3Snir.tzachar@gmail.com mvwprintw(main_window, 0, 3, " %s ", prompt); 1008692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[NORMAL]); 1009692d97c3Snir.tzachar@gmail.com 1010692d97c3Snir.tzachar@gmail.com set_menu_items(curses_menu, curses_menu_items); 1011692d97c3Snir.tzachar@gmail.com 1012692d97c3Snir.tzachar@gmail.com /* position the menu at the middle of the screen */ 1013692d97c3Snir.tzachar@gmail.com scale_menu(curses_menu, &maxy, &maxx); 101468c16eddSNir Tzachar maxx = min(maxx, mwin_max_cols-2); 1015*a72f3e2bSNir Tzachar maxy = mwin_max_lines; 1016692d97c3Snir.tzachar@gmail.com menu_window = derwin(main_window, 1017692d97c3Snir.tzachar@gmail.com maxy, 1018692d97c3Snir.tzachar@gmail.com maxx, 1019692d97c3Snir.tzachar@gmail.com 2, 1020692d97c3Snir.tzachar@gmail.com (mwin_max_cols-maxx)/2); 1021692d97c3Snir.tzachar@gmail.com keypad(menu_window, TRUE); 1022692d97c3Snir.tzachar@gmail.com set_menu_win(curses_menu, menu_window); 1023692d97c3Snir.tzachar@gmail.com set_menu_sub(curses_menu, menu_window); 1024692d97c3Snir.tzachar@gmail.com 1025692d97c3Snir.tzachar@gmail.com /* must reassert this after changing items, otherwise returns to a 1026692d97c3Snir.tzachar@gmail.com * default of 16 1027692d97c3Snir.tzachar@gmail.com */ 1028692d97c3Snir.tzachar@gmail.com set_menu_format(curses_menu, maxy, 1); 1029692d97c3Snir.tzachar@gmail.com center_item(selected_index, last_top_row); 1030692d97c3Snir.tzachar@gmail.com set_menu_format(curses_menu, maxy, 1); 1031692d97c3Snir.tzachar@gmail.com 1032692d97c3Snir.tzachar@gmail.com print_function_line(); 1033692d97c3Snir.tzachar@gmail.com 1034692d97c3Snir.tzachar@gmail.com /* Post the menu */ 1035692d97c3Snir.tzachar@gmail.com post_menu(curses_menu); 1036692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1037692d97c3Snir.tzachar@gmail.com } 1038692d97c3Snir.tzachar@gmail.com 1039*a72f3e2bSNir Tzachar static void adj_match_dir(match_f *match_direction) 1040*a72f3e2bSNir Tzachar { 1041*a72f3e2bSNir Tzachar if (*match_direction == FIND_NEXT_MATCH_DOWN) 1042*a72f3e2bSNir Tzachar *match_direction = 1043*a72f3e2bSNir Tzachar MATCH_TINKER_PATTERN_DOWN; 1044*a72f3e2bSNir Tzachar else if (*match_direction == FIND_NEXT_MATCH_UP) 1045*a72f3e2bSNir Tzachar *match_direction = 1046*a72f3e2bSNir Tzachar MATCH_TINKER_PATTERN_UP; 1047*a72f3e2bSNir Tzachar /* else, do no change.. */ 1048*a72f3e2bSNir Tzachar } 1049*a72f3e2bSNir Tzachar 1050*a72f3e2bSNir Tzachar struct match_state 1051*a72f3e2bSNir Tzachar { 1052*a72f3e2bSNir Tzachar int in_search; 1053*a72f3e2bSNir Tzachar match_f match_direction; 1054*a72f3e2bSNir Tzachar char pattern[256]; 1055*a72f3e2bSNir Tzachar }; 1056*a72f3e2bSNir Tzachar 1057*a72f3e2bSNir Tzachar /* Return 0 means I have handled the key. In such a case, ans should hold the 1058*a72f3e2bSNir Tzachar * item to center, or -1 otherwise. 1059*a72f3e2bSNir Tzachar * Else return -1 . 1060*a72f3e2bSNir Tzachar */ 1061*a72f3e2bSNir Tzachar static int do_match(int key, struct match_state *state, int *ans) 1062*a72f3e2bSNir Tzachar { 1063*a72f3e2bSNir Tzachar char c = (char) key; 1064*a72f3e2bSNir Tzachar int terminate_search = 0; 1065*a72f3e2bSNir Tzachar *ans = -1; 1066*a72f3e2bSNir Tzachar if (key == '/' || (state->in_search && key == 27)) { 1067*a72f3e2bSNir Tzachar move(0, 0); 1068*a72f3e2bSNir Tzachar refresh(); 1069*a72f3e2bSNir Tzachar clrtoeol(); 1070*a72f3e2bSNir Tzachar state->in_search = 1-state->in_search; 1071*a72f3e2bSNir Tzachar bzero(state->pattern, sizeof(state->pattern)); 1072*a72f3e2bSNir Tzachar state->match_direction = MATCH_TINKER_PATTERN_DOWN; 1073*a72f3e2bSNir Tzachar return 0; 1074*a72f3e2bSNir Tzachar } else if (!state->in_search) 1075*a72f3e2bSNir Tzachar return 1; 1076*a72f3e2bSNir Tzachar 1077*a72f3e2bSNir Tzachar if (isalnum(c) || isgraph(c) || c == ' ') { 1078*a72f3e2bSNir Tzachar state->pattern[strlen(state->pattern)] = c; 1079*a72f3e2bSNir Tzachar state->pattern[strlen(state->pattern)] = '\0'; 1080*a72f3e2bSNir Tzachar adj_match_dir(&state->match_direction); 1081*a72f3e2bSNir Tzachar *ans = get_mext_match(state->pattern, 1082*a72f3e2bSNir Tzachar state->match_direction); 1083*a72f3e2bSNir Tzachar } else if (key == KEY_DOWN) { 1084*a72f3e2bSNir Tzachar state->match_direction = FIND_NEXT_MATCH_DOWN; 1085*a72f3e2bSNir Tzachar *ans = get_mext_match(state->pattern, 1086*a72f3e2bSNir Tzachar state->match_direction); 1087*a72f3e2bSNir Tzachar } else if (key == KEY_UP) { 1088*a72f3e2bSNir Tzachar state->match_direction = FIND_NEXT_MATCH_UP; 1089*a72f3e2bSNir Tzachar *ans = get_mext_match(state->pattern, 1090*a72f3e2bSNir Tzachar state->match_direction); 1091*a72f3e2bSNir Tzachar } else if (key == KEY_BACKSPACE || key == 127) { 1092*a72f3e2bSNir Tzachar state->pattern[strlen(state->pattern)-1] = '\0'; 1093*a72f3e2bSNir Tzachar adj_match_dir(&state->match_direction); 1094*a72f3e2bSNir Tzachar } else 1095*a72f3e2bSNir Tzachar terminate_search = 1; 1096*a72f3e2bSNir Tzachar 1097*a72f3e2bSNir Tzachar if (terminate_search) { 1098*a72f3e2bSNir Tzachar state->in_search = 0; 1099*a72f3e2bSNir Tzachar bzero(state->pattern, sizeof(state->pattern)); 1100*a72f3e2bSNir Tzachar move(0, 0); 1101*a72f3e2bSNir Tzachar refresh(); 1102*a72f3e2bSNir Tzachar clrtoeol(); 1103*a72f3e2bSNir Tzachar return -1; 1104*a72f3e2bSNir Tzachar } 1105*a72f3e2bSNir Tzachar return 0; 1106*a72f3e2bSNir Tzachar } 1107692d97c3Snir.tzachar@gmail.com 1108692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu) 1109692d97c3Snir.tzachar@gmail.com { 1110692d97c3Snir.tzachar@gmail.com struct menu *submenu = 0; 1111692d97c3Snir.tzachar@gmail.com const char *prompt = menu_get_prompt(menu); 1112692d97c3Snir.tzachar@gmail.com struct symbol *sym; 1113692d97c3Snir.tzachar@gmail.com struct menu *active_menu = NULL; 1114692d97c3Snir.tzachar@gmail.com int res; 1115692d97c3Snir.tzachar@gmail.com int current_index = 0; 1116692d97c3Snir.tzachar@gmail.com int last_top_row = 0; 1117*a72f3e2bSNir Tzachar struct match_state match_state = { 1118*a72f3e2bSNir Tzachar .in_search = 0, 1119*a72f3e2bSNir Tzachar .match_direction = MATCH_TINKER_PATTERN_DOWN, 1120*a72f3e2bSNir Tzachar .pattern = "", 1121*a72f3e2bSNir Tzachar }; 1122692d97c3Snir.tzachar@gmail.com 1123692d97c3Snir.tzachar@gmail.com while (!global_exit) { 1124692d97c3Snir.tzachar@gmail.com reset_menu(); 1125692d97c3Snir.tzachar@gmail.com current_menu = menu; 1126692d97c3Snir.tzachar@gmail.com build_conf(menu); 1127692d97c3Snir.tzachar@gmail.com if (!child_count) 1128692d97c3Snir.tzachar@gmail.com break; 1129692d97c3Snir.tzachar@gmail.com 1130692d97c3Snir.tzachar@gmail.com show_menu(prompt ? _(prompt) : _("Main Menu"), 1131692d97c3Snir.tzachar@gmail.com _(menu_instructions), 1132692d97c3Snir.tzachar@gmail.com current_index, &last_top_row); 1133692d97c3Snir.tzachar@gmail.com keypad((menu_win(curses_menu)), TRUE); 1134*a72f3e2bSNir Tzachar while (!global_exit) { 1135*a72f3e2bSNir Tzachar if (match_state.in_search) { 1136*a72f3e2bSNir Tzachar mvprintw(0, 0, 1137*a72f3e2bSNir Tzachar "searching: %s", match_state.pattern); 1138*a72f3e2bSNir Tzachar clrtoeol(); 1139*a72f3e2bSNir Tzachar } 1140*a72f3e2bSNir Tzachar refresh_all_windows(main_window); 1141*a72f3e2bSNir Tzachar res = wgetch(menu_win(curses_menu)); 1142*a72f3e2bSNir Tzachar if (!res) 1143*a72f3e2bSNir Tzachar break; 1144*a72f3e2bSNir Tzachar if (do_match(res, &match_state, ¤t_index) == 0) { 1145*a72f3e2bSNir Tzachar if (current_index != -1) 1146*a72f3e2bSNir Tzachar center_item(current_index, 1147*a72f3e2bSNir Tzachar &last_top_row); 1148*a72f3e2bSNir Tzachar continue; 1149*a72f3e2bSNir Tzachar } 1150692d97c3Snir.tzachar@gmail.com if (process_special_keys(&res, 1151692d97c3Snir.tzachar@gmail.com (struct menu *) item_data())) 1152692d97c3Snir.tzachar@gmail.com break; 1153692d97c3Snir.tzachar@gmail.com switch (res) { 1154692d97c3Snir.tzachar@gmail.com case KEY_DOWN: 1155692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_DOWN_ITEM); 1156692d97c3Snir.tzachar@gmail.com break; 1157692d97c3Snir.tzachar@gmail.com case KEY_UP: 1158692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_UP_ITEM); 1159692d97c3Snir.tzachar@gmail.com break; 1160692d97c3Snir.tzachar@gmail.com case KEY_NPAGE: 1161692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_SCR_DPAGE); 1162692d97c3Snir.tzachar@gmail.com break; 1163692d97c3Snir.tzachar@gmail.com case KEY_PPAGE: 1164692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_SCR_UPAGE); 1165692d97c3Snir.tzachar@gmail.com break; 1166692d97c3Snir.tzachar@gmail.com case KEY_HOME: 1167692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_FIRST_ITEM); 1168692d97c3Snir.tzachar@gmail.com break; 1169692d97c3Snir.tzachar@gmail.com case KEY_END: 1170692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_LAST_ITEM); 1171692d97c3Snir.tzachar@gmail.com break; 1172692d97c3Snir.tzachar@gmail.com case 'h': 1173692d97c3Snir.tzachar@gmail.com case '?': 1174692d97c3Snir.tzachar@gmail.com show_help((struct menu *) item_data()); 1175692d97c3Snir.tzachar@gmail.com break; 1176692d97c3Snir.tzachar@gmail.com } 1177692d97c3Snir.tzachar@gmail.com if (res == 10 || res == 27 || 1178692d97c3Snir.tzachar@gmail.com res == 32 || res == 'n' || res == 'y' || 1179692d97c3Snir.tzachar@gmail.com res == KEY_LEFT || res == KEY_RIGHT || 1180*a72f3e2bSNir Tzachar res == 'm') 1181692d97c3Snir.tzachar@gmail.com break; 1182692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1183692d97c3Snir.tzachar@gmail.com } 1184692d97c3Snir.tzachar@gmail.com 1185692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1186692d97c3Snir.tzachar@gmail.com /* if ESC or left*/ 1187692d97c3Snir.tzachar@gmail.com if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) 1188692d97c3Snir.tzachar@gmail.com break; 1189692d97c3Snir.tzachar@gmail.com 1190692d97c3Snir.tzachar@gmail.com /* remember location in the menu */ 1191692d97c3Snir.tzachar@gmail.com last_top_row = top_row(curses_menu); 1192692d97c3Snir.tzachar@gmail.com current_index = curses_item_index(); 1193692d97c3Snir.tzachar@gmail.com 1194692d97c3Snir.tzachar@gmail.com if (!item_tag()) 1195692d97c3Snir.tzachar@gmail.com continue; 1196692d97c3Snir.tzachar@gmail.com 1197692d97c3Snir.tzachar@gmail.com submenu = (struct menu *) item_data(); 1198692d97c3Snir.tzachar@gmail.com active_menu = (struct menu *)item_data(); 1199692d97c3Snir.tzachar@gmail.com if (!submenu || !menu_is_visible(submenu)) 1200692d97c3Snir.tzachar@gmail.com continue; 1201692d97c3Snir.tzachar@gmail.com if (submenu) 1202692d97c3Snir.tzachar@gmail.com sym = submenu->sym; 1203692d97c3Snir.tzachar@gmail.com else 1204692d97c3Snir.tzachar@gmail.com sym = NULL; 1205692d97c3Snir.tzachar@gmail.com 1206692d97c3Snir.tzachar@gmail.com switch (res) { 1207692d97c3Snir.tzachar@gmail.com case ' ': 1208692d97c3Snir.tzachar@gmail.com if (item_is_tag('t')) 1209692d97c3Snir.tzachar@gmail.com sym_toggle_tristate_value(sym); 1210692d97c3Snir.tzachar@gmail.com else if (item_is_tag('m')) 1211692d97c3Snir.tzachar@gmail.com conf(submenu); 1212692d97c3Snir.tzachar@gmail.com break; 1213692d97c3Snir.tzachar@gmail.com case KEY_RIGHT: 1214692d97c3Snir.tzachar@gmail.com case 10: /* ENTER WAS PRESSED */ 1215692d97c3Snir.tzachar@gmail.com switch (item_tag()) { 1216692d97c3Snir.tzachar@gmail.com case 'm': 1217692d97c3Snir.tzachar@gmail.com if (single_menu_mode) 1218692d97c3Snir.tzachar@gmail.com submenu->data = 1219692d97c3Snir.tzachar@gmail.com (void *) (long) !submenu->data; 1220692d97c3Snir.tzachar@gmail.com else 1221692d97c3Snir.tzachar@gmail.com conf(submenu); 1222692d97c3Snir.tzachar@gmail.com break; 1223692d97c3Snir.tzachar@gmail.com case 't': 1224692d97c3Snir.tzachar@gmail.com if (sym_is_choice(sym) && 1225692d97c3Snir.tzachar@gmail.com sym_get_tristate_value(sym) == yes) 1226692d97c3Snir.tzachar@gmail.com conf_choice(submenu); 1227692d97c3Snir.tzachar@gmail.com else if (submenu->prompt && 1228692d97c3Snir.tzachar@gmail.com submenu->prompt->type == P_MENU) 1229692d97c3Snir.tzachar@gmail.com conf(submenu); 1230692d97c3Snir.tzachar@gmail.com else if (res == 10) 1231692d97c3Snir.tzachar@gmail.com sym_toggle_tristate_value(sym); 1232692d97c3Snir.tzachar@gmail.com break; 1233692d97c3Snir.tzachar@gmail.com case 's': 1234692d97c3Snir.tzachar@gmail.com conf_string(submenu); 1235692d97c3Snir.tzachar@gmail.com break; 1236692d97c3Snir.tzachar@gmail.com } 1237692d97c3Snir.tzachar@gmail.com break; 1238692d97c3Snir.tzachar@gmail.com case 'y': 1239692d97c3Snir.tzachar@gmail.com if (item_is_tag('t')) { 1240692d97c3Snir.tzachar@gmail.com if (sym_set_tristate_value(sym, yes)) 1241692d97c3Snir.tzachar@gmail.com break; 1242692d97c3Snir.tzachar@gmail.com if (sym_set_tristate_value(sym, mod)) 1243692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, setmod_text, 0); 1244692d97c3Snir.tzachar@gmail.com } 1245692d97c3Snir.tzachar@gmail.com break; 1246692d97c3Snir.tzachar@gmail.com case 'n': 1247692d97c3Snir.tzachar@gmail.com if (item_is_tag('t')) 1248692d97c3Snir.tzachar@gmail.com sym_set_tristate_value(sym, no); 1249692d97c3Snir.tzachar@gmail.com break; 1250692d97c3Snir.tzachar@gmail.com case 'm': 1251692d97c3Snir.tzachar@gmail.com if (item_is_tag('t')) 1252692d97c3Snir.tzachar@gmail.com sym_set_tristate_value(sym, mod); 1253692d97c3Snir.tzachar@gmail.com break; 1254692d97c3Snir.tzachar@gmail.com } 1255692d97c3Snir.tzachar@gmail.com } 1256692d97c3Snir.tzachar@gmail.com } 1257692d97c3Snir.tzachar@gmail.com 1258692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu) 1259692d97c3Snir.tzachar@gmail.com { 1260692d97c3Snir.tzachar@gmail.com struct gstr help = str_new(); 1261692d97c3Snir.tzachar@gmail.com 1262692d97c3Snir.tzachar@gmail.com if (menu && menu->sym && menu_has_help(menu)) { 1263692d97c3Snir.tzachar@gmail.com if (menu->sym->name) { 1264692d97c3Snir.tzachar@gmail.com str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name); 1265692d97c3Snir.tzachar@gmail.com str_append(&help, _(menu_get_help(menu))); 1266692d97c3Snir.tzachar@gmail.com str_append(&help, "\n"); 1267692d97c3Snir.tzachar@gmail.com get_symbol_str(&help, menu->sym); 1268692d97c3Snir.tzachar@gmail.com } 1269692d97c3Snir.tzachar@gmail.com } else { 1270692d97c3Snir.tzachar@gmail.com str_append(&help, nohelp_text); 1271692d97c3Snir.tzachar@gmail.com } 1272692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); 1273692d97c3Snir.tzachar@gmail.com str_free(&help); 1274692d97c3Snir.tzachar@gmail.com } 1275692d97c3Snir.tzachar@gmail.com 1276692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu) 1277692d97c3Snir.tzachar@gmail.com { 1278692d97c3Snir.tzachar@gmail.com const char *prompt = _(menu_get_prompt(menu)); 1279692d97c3Snir.tzachar@gmail.com struct menu *child = 0; 1280692d97c3Snir.tzachar@gmail.com struct symbol *active; 1281692d97c3Snir.tzachar@gmail.com int selected_index = 0; 1282692d97c3Snir.tzachar@gmail.com int last_top_row = 0; 1283692d97c3Snir.tzachar@gmail.com int res, i = 0; 1284*a72f3e2bSNir Tzachar struct match_state match_state = { 1285*a72f3e2bSNir Tzachar .in_search = 0, 1286*a72f3e2bSNir Tzachar .match_direction = MATCH_TINKER_PATTERN_DOWN, 1287*a72f3e2bSNir Tzachar .pattern = "", 1288*a72f3e2bSNir Tzachar }; 1289692d97c3Snir.tzachar@gmail.com 1290692d97c3Snir.tzachar@gmail.com active = sym_get_choice_value(menu->sym); 1291692d97c3Snir.tzachar@gmail.com /* this is mostly duplicated from the conf() function. */ 1292692d97c3Snir.tzachar@gmail.com while (!global_exit) { 1293692d97c3Snir.tzachar@gmail.com reset_menu(); 1294692d97c3Snir.tzachar@gmail.com 1295692d97c3Snir.tzachar@gmail.com for (i = 0, child = menu->list; child; child = child->next) { 1296692d97c3Snir.tzachar@gmail.com if (!show_all_items && !menu_is_visible(child)) 1297692d97c3Snir.tzachar@gmail.com continue; 1298692d97c3Snir.tzachar@gmail.com 1299692d97c3Snir.tzachar@gmail.com if (child->sym == sym_get_choice_value(menu->sym)) 1300692d97c3Snir.tzachar@gmail.com item_make(child, ':', "<X> %s", 1301692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(child))); 1302692d97c3Snir.tzachar@gmail.com else 1303692d97c3Snir.tzachar@gmail.com item_make(child, ':', " %s", 1304692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(child))); 1305692d97c3Snir.tzachar@gmail.com if (child->sym == active){ 1306692d97c3Snir.tzachar@gmail.com last_top_row = top_row(curses_menu); 1307692d97c3Snir.tzachar@gmail.com selected_index = i; 1308692d97c3Snir.tzachar@gmail.com } 1309692d97c3Snir.tzachar@gmail.com i++; 1310692d97c3Snir.tzachar@gmail.com } 1311692d97c3Snir.tzachar@gmail.com show_menu(prompt ? _(prompt) : _("Choice Menu"), 1312692d97c3Snir.tzachar@gmail.com _(radiolist_instructions), 1313692d97c3Snir.tzachar@gmail.com selected_index, 1314692d97c3Snir.tzachar@gmail.com &last_top_row); 1315*a72f3e2bSNir Tzachar while (!global_exit) { 1316*a72f3e2bSNir Tzachar if (match_state.in_search) { 1317*a72f3e2bSNir Tzachar mvprintw(0, 0, "searching: %s", 1318*a72f3e2bSNir Tzachar match_state.pattern); 1319*a72f3e2bSNir Tzachar clrtoeol(); 1320*a72f3e2bSNir Tzachar } 1321*a72f3e2bSNir Tzachar refresh_all_windows(main_window); 1322*a72f3e2bSNir Tzachar res = wgetch(menu_win(curses_menu)); 1323*a72f3e2bSNir Tzachar if (!res) 1324*a72f3e2bSNir Tzachar break; 1325*a72f3e2bSNir Tzachar if (do_match(res, &match_state, &selected_index) == 0) { 1326*a72f3e2bSNir Tzachar if (selected_index != -1) 1327*a72f3e2bSNir Tzachar center_item(selected_index, 1328*a72f3e2bSNir Tzachar &last_top_row); 1329*a72f3e2bSNir Tzachar continue; 1330*a72f3e2bSNir Tzachar } 1331692d97c3Snir.tzachar@gmail.com if (process_special_keys( 1332692d97c3Snir.tzachar@gmail.com &res, 1333692d97c3Snir.tzachar@gmail.com (struct menu *) item_data())) 1334692d97c3Snir.tzachar@gmail.com break; 1335692d97c3Snir.tzachar@gmail.com switch (res) { 1336692d97c3Snir.tzachar@gmail.com case KEY_DOWN: 1337692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_DOWN_ITEM); 1338692d97c3Snir.tzachar@gmail.com break; 1339692d97c3Snir.tzachar@gmail.com case KEY_UP: 1340692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_UP_ITEM); 1341692d97c3Snir.tzachar@gmail.com break; 1342692d97c3Snir.tzachar@gmail.com case KEY_NPAGE: 1343692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_SCR_DPAGE); 1344692d97c3Snir.tzachar@gmail.com break; 1345692d97c3Snir.tzachar@gmail.com case KEY_PPAGE: 1346692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_SCR_UPAGE); 1347692d97c3Snir.tzachar@gmail.com break; 1348692d97c3Snir.tzachar@gmail.com case KEY_HOME: 1349692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_FIRST_ITEM); 1350692d97c3Snir.tzachar@gmail.com break; 1351692d97c3Snir.tzachar@gmail.com case KEY_END: 1352692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_LAST_ITEM); 1353692d97c3Snir.tzachar@gmail.com break; 1354692d97c3Snir.tzachar@gmail.com case 'h': 1355692d97c3Snir.tzachar@gmail.com case '?': 1356692d97c3Snir.tzachar@gmail.com show_help((struct menu *) item_data()); 1357692d97c3Snir.tzachar@gmail.com break; 1358692d97c3Snir.tzachar@gmail.com } 1359692d97c3Snir.tzachar@gmail.com if (res == 10 || res == 27 || res == ' ' || 1360*a72f3e2bSNir Tzachar res == KEY_LEFT){ 1361692d97c3Snir.tzachar@gmail.com break; 1362692d97c3Snir.tzachar@gmail.com } 1363692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1364692d97c3Snir.tzachar@gmail.com } 1365692d97c3Snir.tzachar@gmail.com /* if ESC or left */ 1366692d97c3Snir.tzachar@gmail.com if (res == 27 || res == KEY_LEFT) 1367692d97c3Snir.tzachar@gmail.com break; 1368692d97c3Snir.tzachar@gmail.com 1369692d97c3Snir.tzachar@gmail.com child = item_data(); 1370692d97c3Snir.tzachar@gmail.com if (!child || !menu_is_visible(child)) 1371692d97c3Snir.tzachar@gmail.com continue; 1372692d97c3Snir.tzachar@gmail.com switch (res) { 1373692d97c3Snir.tzachar@gmail.com case ' ': 1374692d97c3Snir.tzachar@gmail.com case 10: 1375692d97c3Snir.tzachar@gmail.com case KEY_RIGHT: 1376692d97c3Snir.tzachar@gmail.com sym_set_tristate_value(child->sym, yes); 1377692d97c3Snir.tzachar@gmail.com return; 1378692d97c3Snir.tzachar@gmail.com case 'h': 1379692d97c3Snir.tzachar@gmail.com case '?': 1380692d97c3Snir.tzachar@gmail.com show_help(child); 1381692d97c3Snir.tzachar@gmail.com active = child->sym; 1382692d97c3Snir.tzachar@gmail.com break; 1383692d97c3Snir.tzachar@gmail.com case KEY_EXIT: 1384692d97c3Snir.tzachar@gmail.com return; 1385692d97c3Snir.tzachar@gmail.com } 1386692d97c3Snir.tzachar@gmail.com } 1387692d97c3Snir.tzachar@gmail.com } 1388692d97c3Snir.tzachar@gmail.com 1389692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu) 1390692d97c3Snir.tzachar@gmail.com { 1391692d97c3Snir.tzachar@gmail.com const char *prompt = menu_get_prompt(menu); 1392692d97c3Snir.tzachar@gmail.com char dialog_input_result[256]; 1393692d97c3Snir.tzachar@gmail.com 1394692d97c3Snir.tzachar@gmail.com while (1) { 1395692d97c3Snir.tzachar@gmail.com int res; 1396692d97c3Snir.tzachar@gmail.com const char *heading; 1397692d97c3Snir.tzachar@gmail.com 1398692d97c3Snir.tzachar@gmail.com switch (sym_get_type(menu->sym)) { 1399692d97c3Snir.tzachar@gmail.com case S_INT: 1400692d97c3Snir.tzachar@gmail.com heading = _(inputbox_instructions_int); 1401692d97c3Snir.tzachar@gmail.com break; 1402692d97c3Snir.tzachar@gmail.com case S_HEX: 1403692d97c3Snir.tzachar@gmail.com heading = _(inputbox_instructions_hex); 1404692d97c3Snir.tzachar@gmail.com break; 1405692d97c3Snir.tzachar@gmail.com case S_STRING: 1406692d97c3Snir.tzachar@gmail.com heading = _(inputbox_instructions_string); 1407692d97c3Snir.tzachar@gmail.com break; 1408692d97c3Snir.tzachar@gmail.com default: 1409692d97c3Snir.tzachar@gmail.com heading = _("Internal nconf error!"); 1410692d97c3Snir.tzachar@gmail.com } 1411692d97c3Snir.tzachar@gmail.com res = dialog_inputbox(main_window, 1412692d97c3Snir.tzachar@gmail.com prompt ? _(prompt) : _("Main Menu"), 1413692d97c3Snir.tzachar@gmail.com heading, 1414692d97c3Snir.tzachar@gmail.com sym_get_string_value(menu->sym), 1415692d97c3Snir.tzachar@gmail.com dialog_input_result, 1416692d97c3Snir.tzachar@gmail.com sizeof(dialog_input_result)); 1417692d97c3Snir.tzachar@gmail.com switch (res) { 1418692d97c3Snir.tzachar@gmail.com case 0: 1419692d97c3Snir.tzachar@gmail.com if (sym_set_string_value(menu->sym, 1420692d97c3Snir.tzachar@gmail.com dialog_input_result)) 1421692d97c3Snir.tzachar@gmail.com return; 1422692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, 1423692d97c3Snir.tzachar@gmail.com _("You have made an invalid entry."), 0); 1424692d97c3Snir.tzachar@gmail.com break; 1425692d97c3Snir.tzachar@gmail.com case 1: 1426692d97c3Snir.tzachar@gmail.com show_help(menu); 1427692d97c3Snir.tzachar@gmail.com break; 1428692d97c3Snir.tzachar@gmail.com case KEY_EXIT: 1429692d97c3Snir.tzachar@gmail.com return; 1430692d97c3Snir.tzachar@gmail.com } 1431692d97c3Snir.tzachar@gmail.com } 1432692d97c3Snir.tzachar@gmail.com } 1433692d97c3Snir.tzachar@gmail.com 1434692d97c3Snir.tzachar@gmail.com static void conf_load(void) 1435692d97c3Snir.tzachar@gmail.com { 1436692d97c3Snir.tzachar@gmail.com char dialog_input_result[256]; 1437692d97c3Snir.tzachar@gmail.com while (1) { 1438692d97c3Snir.tzachar@gmail.com int res; 1439692d97c3Snir.tzachar@gmail.com res = dialog_inputbox(main_window, 1440692d97c3Snir.tzachar@gmail.com NULL, load_config_text, 1441692d97c3Snir.tzachar@gmail.com filename, 1442692d97c3Snir.tzachar@gmail.com dialog_input_result, 1443692d97c3Snir.tzachar@gmail.com sizeof(dialog_input_result)); 1444692d97c3Snir.tzachar@gmail.com switch (res) { 1445692d97c3Snir.tzachar@gmail.com case 0: 1446692d97c3Snir.tzachar@gmail.com if (!dialog_input_result[0]) 1447692d97c3Snir.tzachar@gmail.com return; 1448692d97c3Snir.tzachar@gmail.com if (!conf_read(dialog_input_result)) { 1449692d97c3Snir.tzachar@gmail.com set_config_filename(dialog_input_result); 1450692d97c3Snir.tzachar@gmail.com sym_set_change_count(1); 1451692d97c3Snir.tzachar@gmail.com return; 1452692d97c3Snir.tzachar@gmail.com } 1453692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, _("File does not exist!"), 0); 1454692d97c3Snir.tzachar@gmail.com break; 1455692d97c3Snir.tzachar@gmail.com case 1: 1456692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 1457692d97c3Snir.tzachar@gmail.com _("Load Alternate Configuration"), 1458692d97c3Snir.tzachar@gmail.com load_config_help); 1459692d97c3Snir.tzachar@gmail.com break; 1460692d97c3Snir.tzachar@gmail.com case KEY_EXIT: 1461692d97c3Snir.tzachar@gmail.com return; 1462692d97c3Snir.tzachar@gmail.com } 1463692d97c3Snir.tzachar@gmail.com } 1464692d97c3Snir.tzachar@gmail.com } 1465692d97c3Snir.tzachar@gmail.com 1466692d97c3Snir.tzachar@gmail.com static void conf_save(void) 1467692d97c3Snir.tzachar@gmail.com { 1468692d97c3Snir.tzachar@gmail.com char dialog_input_result[256]; 1469692d97c3Snir.tzachar@gmail.com while (1) { 1470692d97c3Snir.tzachar@gmail.com int res; 1471692d97c3Snir.tzachar@gmail.com res = dialog_inputbox(main_window, 1472692d97c3Snir.tzachar@gmail.com NULL, save_config_text, 1473692d97c3Snir.tzachar@gmail.com filename, 1474692d97c3Snir.tzachar@gmail.com dialog_input_result, 1475692d97c3Snir.tzachar@gmail.com sizeof(dialog_input_result)); 1476692d97c3Snir.tzachar@gmail.com switch (res) { 1477692d97c3Snir.tzachar@gmail.com case 0: 1478692d97c3Snir.tzachar@gmail.com if (!dialog_input_result[0]) 1479692d97c3Snir.tzachar@gmail.com return; 1480692d97c3Snir.tzachar@gmail.com supress_stdout(0); 1481692d97c3Snir.tzachar@gmail.com res = conf_write(dialog_input_result); 1482692d97c3Snir.tzachar@gmail.com supress_stdout(1); 1483692d97c3Snir.tzachar@gmail.com if (!res) { 1484692d97c3Snir.tzachar@gmail.com char buf[1024]; 1485692d97c3Snir.tzachar@gmail.com sprintf(buf, "%s %s", 1486692d97c3Snir.tzachar@gmail.com _("configuration file saved to: "), 1487692d97c3Snir.tzachar@gmail.com dialog_input_result); 1488692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, 1489692d97c3Snir.tzachar@gmail.com buf, 1, "<OK>"); 1490692d97c3Snir.tzachar@gmail.com set_config_filename(dialog_input_result); 1491692d97c3Snir.tzachar@gmail.com return; 1492692d97c3Snir.tzachar@gmail.com } 1493692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, _("Can't create file! " 1494692d97c3Snir.tzachar@gmail.com "Probably a nonexistent directory."), 1495692d97c3Snir.tzachar@gmail.com 1, "<OK>"); 1496692d97c3Snir.tzachar@gmail.com break; 1497692d97c3Snir.tzachar@gmail.com case 1: 1498692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 1499692d97c3Snir.tzachar@gmail.com _("Save Alternate Configuration"), 1500692d97c3Snir.tzachar@gmail.com save_config_help); 1501692d97c3Snir.tzachar@gmail.com break; 1502692d97c3Snir.tzachar@gmail.com case KEY_EXIT: 1503692d97c3Snir.tzachar@gmail.com return; 1504692d97c3Snir.tzachar@gmail.com } 1505692d97c3Snir.tzachar@gmail.com } 1506692d97c3Snir.tzachar@gmail.com } 1507692d97c3Snir.tzachar@gmail.com 1508692d97c3Snir.tzachar@gmail.com void setup_windows(void) 1509692d97c3Snir.tzachar@gmail.com { 1510692d97c3Snir.tzachar@gmail.com if (main_window != NULL) 1511692d97c3Snir.tzachar@gmail.com delwin(main_window); 1512692d97c3Snir.tzachar@gmail.com 1513692d97c3Snir.tzachar@gmail.com /* set up the menu and menu window */ 1514692d97c3Snir.tzachar@gmail.com main_window = newwin(LINES-2, COLS-2, 2, 1); 1515692d97c3Snir.tzachar@gmail.com keypad(main_window, TRUE); 1516*a72f3e2bSNir Tzachar mwin_max_lines = LINES-7; 1517692d97c3Snir.tzachar@gmail.com mwin_max_cols = COLS-6; 1518692d97c3Snir.tzachar@gmail.com 1519692d97c3Snir.tzachar@gmail.com /* panels order is from bottom to top */ 1520692d97c3Snir.tzachar@gmail.com new_panel(main_window); 1521692d97c3Snir.tzachar@gmail.com } 1522692d97c3Snir.tzachar@gmail.com 1523692d97c3Snir.tzachar@gmail.com int main(int ac, char **av) 1524692d97c3Snir.tzachar@gmail.com { 1525692d97c3Snir.tzachar@gmail.com char *mode; 1526692d97c3Snir.tzachar@gmail.com 1527692d97c3Snir.tzachar@gmail.com setlocale(LC_ALL, ""); 1528692d97c3Snir.tzachar@gmail.com bindtextdomain(PACKAGE, LOCALEDIR); 1529692d97c3Snir.tzachar@gmail.com textdomain(PACKAGE); 1530692d97c3Snir.tzachar@gmail.com 1531692d97c3Snir.tzachar@gmail.com conf_parse(av[1]); 1532692d97c3Snir.tzachar@gmail.com conf_read(NULL); 1533692d97c3Snir.tzachar@gmail.com 1534692d97c3Snir.tzachar@gmail.com mode = getenv("NCONFIG_MODE"); 1535692d97c3Snir.tzachar@gmail.com if (mode) { 1536692d97c3Snir.tzachar@gmail.com if (!strcasecmp(mode, "single_menu")) 1537692d97c3Snir.tzachar@gmail.com single_menu_mode = 1; 1538692d97c3Snir.tzachar@gmail.com } 1539692d97c3Snir.tzachar@gmail.com 1540692d97c3Snir.tzachar@gmail.com /* Initialize curses */ 1541692d97c3Snir.tzachar@gmail.com initscr(); 1542692d97c3Snir.tzachar@gmail.com /* set color theme */ 1543692d97c3Snir.tzachar@gmail.com set_colors(); 1544692d97c3Snir.tzachar@gmail.com 1545692d97c3Snir.tzachar@gmail.com cbreak(); 1546692d97c3Snir.tzachar@gmail.com noecho(); 1547692d97c3Snir.tzachar@gmail.com keypad(stdscr, TRUE); 1548692d97c3Snir.tzachar@gmail.com curs_set(0); 1549692d97c3Snir.tzachar@gmail.com 1550692d97c3Snir.tzachar@gmail.com if (COLS < 75 || LINES < 20) { 1551692d97c3Snir.tzachar@gmail.com endwin(); 1552692d97c3Snir.tzachar@gmail.com printf("Your terminal should have at " 1553692d97c3Snir.tzachar@gmail.com "least 20 lines and 75 columns\n"); 1554692d97c3Snir.tzachar@gmail.com return 1; 1555692d97c3Snir.tzachar@gmail.com } 1556692d97c3Snir.tzachar@gmail.com 1557692d97c3Snir.tzachar@gmail.com notimeout(stdscr, FALSE); 1558692d97c3Snir.tzachar@gmail.com ESCDELAY = 1; 1559692d97c3Snir.tzachar@gmail.com 1560692d97c3Snir.tzachar@gmail.com /* set btns menu */ 1561692d97c3Snir.tzachar@gmail.com curses_menu = new_menu(curses_menu_items); 1562692d97c3Snir.tzachar@gmail.com menu_opts_off(curses_menu, O_SHOWDESC); 1563*a72f3e2bSNir Tzachar menu_opts_on(curses_menu, O_SHOWMATCH); 1564692d97c3Snir.tzachar@gmail.com menu_opts_on(curses_menu, O_ONEVALUE); 1565692d97c3Snir.tzachar@gmail.com menu_opts_on(curses_menu, O_NONCYCLIC); 1566*a72f3e2bSNir Tzachar menu_opts_on(curses_menu, O_IGNORECASE); 1567692d97c3Snir.tzachar@gmail.com set_menu_mark(curses_menu, " "); 1568692d97c3Snir.tzachar@gmail.com set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); 1569692d97c3Snir.tzachar@gmail.com set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); 1570692d97c3Snir.tzachar@gmail.com set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]); 1571692d97c3Snir.tzachar@gmail.com 1572692d97c3Snir.tzachar@gmail.com set_config_filename(conf_get_configname()); 1573692d97c3Snir.tzachar@gmail.com setup_windows(); 1574692d97c3Snir.tzachar@gmail.com 1575692d97c3Snir.tzachar@gmail.com /* check for KEY_FUNC(1) */ 1576692d97c3Snir.tzachar@gmail.com if (has_key(KEY_F(1)) == FALSE) { 1577692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 1578692d97c3Snir.tzachar@gmail.com _("Instructions"), 1579692d97c3Snir.tzachar@gmail.com _(menu_no_f_instructions)); 1580692d97c3Snir.tzachar@gmail.com } 1581692d97c3Snir.tzachar@gmail.com 1582692d97c3Snir.tzachar@gmail.com /* do the work */ 1583692d97c3Snir.tzachar@gmail.com while (!global_exit) { 1584692d97c3Snir.tzachar@gmail.com conf(&rootmenu); 1585692d97c3Snir.tzachar@gmail.com if (!global_exit && do_exit() == 0) 1586692d97c3Snir.tzachar@gmail.com break; 1587692d97c3Snir.tzachar@gmail.com } 1588692d97c3Snir.tzachar@gmail.com /* ok, we are done */ 1589692d97c3Snir.tzachar@gmail.com unpost_menu(curses_menu); 1590692d97c3Snir.tzachar@gmail.com free_menu(curses_menu); 1591692d97c3Snir.tzachar@gmail.com delwin(main_window); 1592692d97c3Snir.tzachar@gmail.com clear(); 1593692d97c3Snir.tzachar@gmail.com refresh(); 1594692d97c3Snir.tzachar@gmail.com endwin(); 1595692d97c3Snir.tzachar@gmail.com return 0; 1596692d97c3Snir.tzachar@gmail.com } 1597692d97c3Snir.tzachar@gmail.com 1598