1*692d97c3Snir.tzachar@gmail.com /* 2*692d97c3Snir.tzachar@gmail.com * Copyright (C) 2008 Nir Tzachar <nir.tzachar@gmail.com? 3*692d97c3Snir.tzachar@gmail.com * Released under the terms of the GNU GPL v2.0. 4*692d97c3Snir.tzachar@gmail.com * 5*692d97c3Snir.tzachar@gmail.com * Derived from menuconfig. 6*692d97c3Snir.tzachar@gmail.com * 7*692d97c3Snir.tzachar@gmail.com */ 8*692d97c3Snir.tzachar@gmail.com #define LKC_DIRECT_LINK 9*692d97c3Snir.tzachar@gmail.com #include "lkc.h" 10*692d97c3Snir.tzachar@gmail.com #include "nconf.h" 11*692d97c3Snir.tzachar@gmail.com 12*692d97c3Snir.tzachar@gmail.com static const char nconf_readme[] = N_( 13*692d97c3Snir.tzachar@gmail.com "Overview\n" 14*692d97c3Snir.tzachar@gmail.com "--------\n" 15*692d97c3Snir.tzachar@gmail.com "Some kernel features may be built directly into the kernel.\n" 16*692d97c3Snir.tzachar@gmail.com "Some may be made into loadable runtime modules. Some features\n" 17*692d97c3Snir.tzachar@gmail.com "may be completely removed altogether. There are also certain\n" 18*692d97c3Snir.tzachar@gmail.com "kernel parameters which are not really features, but must be\n" 19*692d97c3Snir.tzachar@gmail.com "entered in as decimal or hexadecimal numbers or possibly text.\n" 20*692d97c3Snir.tzachar@gmail.com "\n" 21*692d97c3Snir.tzachar@gmail.com "Menu items beginning with following braces represent features that\n" 22*692d97c3Snir.tzachar@gmail.com " [ ] can be built in or removed\n" 23*692d97c3Snir.tzachar@gmail.com " < > can be built in, modularized or removed\n" 24*692d97c3Snir.tzachar@gmail.com " { } can be built in or modularized (selected by other feature)\n" 25*692d97c3Snir.tzachar@gmail.com " - - are selected by other feature,\n" 26*692d97c3Snir.tzachar@gmail.com " XXX cannot be selected. use Symbol Info to find out why,\n" 27*692d97c3Snir.tzachar@gmail.com "while *, M or whitespace inside braces means to build in, build as\n" 28*692d97c3Snir.tzachar@gmail.com "a module or to exclude the feature respectively.\n" 29*692d97c3Snir.tzachar@gmail.com "\n" 30*692d97c3Snir.tzachar@gmail.com "To change any of these features, highlight it with the cursor\n" 31*692d97c3Snir.tzachar@gmail.com "keys and press <Y> to build it in, <M> to make it a module or\n" 32*692d97c3Snir.tzachar@gmail.com "<N> to removed it. You may also press the <Space Bar> to cycle\n" 33*692d97c3Snir.tzachar@gmail.com "through the available options (ie. Y->N->M->Y).\n" 34*692d97c3Snir.tzachar@gmail.com "\n" 35*692d97c3Snir.tzachar@gmail.com "Some additional keyboard hints:\n" 36*692d97c3Snir.tzachar@gmail.com "\n" 37*692d97c3Snir.tzachar@gmail.com "Menus\n" 38*692d97c3Snir.tzachar@gmail.com "----------\n" 39*692d97c3Snir.tzachar@gmail.com "o Use the Up/Down arrow keys (cursor keys) to highlight the item\n" 40*692d97c3Snir.tzachar@gmail.com " you wish to change use <Enter> or <Space>. Goto submenu by \n" 41*692d97c3Snir.tzachar@gmail.com " pressing <Enter> of <right-arrow>. Use <Esc> or <left-arrow> to go back.\n" 42*692d97c3Snir.tzachar@gmail.com " Submenus are designated by \"--->\".\n" 43*692d97c3Snir.tzachar@gmail.com "\n" 44*692d97c3Snir.tzachar@gmail.com " Shortcut: Press the option's highlighted letter (hotkey).\n" 45*692d97c3Snir.tzachar@gmail.com " Pressing a hotkey more than once will sequence\n" 46*692d97c3Snir.tzachar@gmail.com " through all visible items which use that hotkey.\n" 47*692d97c3Snir.tzachar@gmail.com "\n" 48*692d97c3Snir.tzachar@gmail.com " You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n" 49*692d97c3Snir.tzachar@gmail.com " unseen options into view.\n" 50*692d97c3Snir.tzachar@gmail.com "\n" 51*692d97c3Snir.tzachar@gmail.com "o To exit a menu use the just press <ESC> <F5> <F8> or <left-arrow>.\n" 52*692d97c3Snir.tzachar@gmail.com "\n" 53*692d97c3Snir.tzachar@gmail.com "o To get help with an item, press <F1>\n" 54*692d97c3Snir.tzachar@gmail.com " Shortcut: Press <h> or <?>.\n" 55*692d97c3Snir.tzachar@gmail.com "\n" 56*692d97c3Snir.tzachar@gmail.com "\n" 57*692d97c3Snir.tzachar@gmail.com "Radiolists (Choice lists)\n" 58*692d97c3Snir.tzachar@gmail.com "-----------\n" 59*692d97c3Snir.tzachar@gmail.com "o Use the cursor keys to select the option you wish to set and press\n" 60*692d97c3Snir.tzachar@gmail.com " <S> or the <SPACE BAR>.\n" 61*692d97c3Snir.tzachar@gmail.com "\n" 62*692d97c3Snir.tzachar@gmail.com " Shortcut: Press the first letter of the option you wish to set then\n" 63*692d97c3Snir.tzachar@gmail.com " press <S> or <SPACE BAR>.\n" 64*692d97c3Snir.tzachar@gmail.com "\n" 65*692d97c3Snir.tzachar@gmail.com "o To see available help for the item, press <F1>\n" 66*692d97c3Snir.tzachar@gmail.com " Shortcut: Press <H> or <?>.\n" 67*692d97c3Snir.tzachar@gmail.com "\n" 68*692d97c3Snir.tzachar@gmail.com "\n" 69*692d97c3Snir.tzachar@gmail.com "Data Entry\n" 70*692d97c3Snir.tzachar@gmail.com "-----------\n" 71*692d97c3Snir.tzachar@gmail.com "o Enter the requested information and press <ENTER>\n" 72*692d97c3Snir.tzachar@gmail.com " If you are entering hexadecimal values, it is not necessary to\n" 73*692d97c3Snir.tzachar@gmail.com " add the '0x' prefix to the entry.\n" 74*692d97c3Snir.tzachar@gmail.com "\n" 75*692d97c3Snir.tzachar@gmail.com "o For help, press <F1>.\n" 76*692d97c3Snir.tzachar@gmail.com "\n" 77*692d97c3Snir.tzachar@gmail.com "\n" 78*692d97c3Snir.tzachar@gmail.com "Text Box (Help Window)\n" 79*692d97c3Snir.tzachar@gmail.com "--------\n" 80*692d97c3Snir.tzachar@gmail.com "o Use the cursor keys to scroll up/down/left/right. The VI editor\n" 81*692d97c3Snir.tzachar@gmail.com " keys h,j,k,l function here as do <SPACE BAR> for those\n" 82*692d97c3Snir.tzachar@gmail.com " who are familiar with less and lynx.\n" 83*692d97c3Snir.tzachar@gmail.com "\n" 84*692d97c3Snir.tzachar@gmail.com "o Press <Enter>, <F1>, <F5>, <F7> or <Esc> to exit.\n" 85*692d97c3Snir.tzachar@gmail.com "\n" 86*692d97c3Snir.tzachar@gmail.com "\n" 87*692d97c3Snir.tzachar@gmail.com "Alternate Configuration Files\n" 88*692d97c3Snir.tzachar@gmail.com "-----------------------------\n" 89*692d97c3Snir.tzachar@gmail.com "nconfig supports the use of alternate configuration files for\n" 90*692d97c3Snir.tzachar@gmail.com "those who, for various reasons, find it necessary to switch\n" 91*692d97c3Snir.tzachar@gmail.com "between different kernel configurations.\n" 92*692d97c3Snir.tzachar@gmail.com "\n" 93*692d97c3Snir.tzachar@gmail.com "At the end of the main menu you will find two options. One is\n" 94*692d97c3Snir.tzachar@gmail.com "for saving the current configuration to a file of your choosing.\n" 95*692d97c3Snir.tzachar@gmail.com "The other option is for loading a previously saved alternate\n" 96*692d97c3Snir.tzachar@gmail.com "configuration.\n" 97*692d97c3Snir.tzachar@gmail.com "\n" 98*692d97c3Snir.tzachar@gmail.com "Even if you don't use alternate configuration files, but you\n" 99*692d97c3Snir.tzachar@gmail.com "find during a nconfig session that you have completely messed\n" 100*692d97c3Snir.tzachar@gmail.com "up your settings, you may use the \"Load Alternate...\" option to\n" 101*692d97c3Snir.tzachar@gmail.com "restore your previously saved settings from \".config\" without\n" 102*692d97c3Snir.tzachar@gmail.com "restarting nconfig.\n" 103*692d97c3Snir.tzachar@gmail.com "\n" 104*692d97c3Snir.tzachar@gmail.com "Other information\n" 105*692d97c3Snir.tzachar@gmail.com "-----------------\n" 106*692d97c3Snir.tzachar@gmail.com "If you use nconfig in an XTERM window make sure you have your\n" 107*692d97c3Snir.tzachar@gmail.com "$TERM variable set to point to a xterm definition which supports color.\n" 108*692d97c3Snir.tzachar@gmail.com "Otherwise, nconfig will look rather bad. nconfig will not\n" 109*692d97c3Snir.tzachar@gmail.com "display correctly in a RXVT window because rxvt displays only one\n" 110*692d97c3Snir.tzachar@gmail.com "intensity of color, bright.\n" 111*692d97c3Snir.tzachar@gmail.com "\n" 112*692d97c3Snir.tzachar@gmail.com "nconfig will display larger menus on screens or xterms which are\n" 113*692d97c3Snir.tzachar@gmail.com "set to display more than the standard 25 row by 80 column geometry.\n" 114*692d97c3Snir.tzachar@gmail.com "In order for this to work, the \"stty size\" command must be able to\n" 115*692d97c3Snir.tzachar@gmail.com "display the screen's current row and column geometry. I STRONGLY\n" 116*692d97c3Snir.tzachar@gmail.com "RECOMMEND that you make sure you do NOT have the shell variables\n" 117*692d97c3Snir.tzachar@gmail.com "LINES and COLUMNS exported into your environment. Some distributions\n" 118*692d97c3Snir.tzachar@gmail.com "export those variables via /etc/profile. Some ncurses programs can\n" 119*692d97c3Snir.tzachar@gmail.com "become confused when those variables (LINES & COLUMNS) don't reflect\n" 120*692d97c3Snir.tzachar@gmail.com "the true screen size.\n" 121*692d97c3Snir.tzachar@gmail.com "\n" 122*692d97c3Snir.tzachar@gmail.com "Optional personality available\n" 123*692d97c3Snir.tzachar@gmail.com "------------------------------\n" 124*692d97c3Snir.tzachar@gmail.com "If you prefer to have all of the kernel options listed in a single\n" 125*692d97c3Snir.tzachar@gmail.com "menu, rather than the default multimenu hierarchy, run the nconfig\n" 126*692d97c3Snir.tzachar@gmail.com "with NCONFIG_MODE environment variable set to single_menu. Example:\n" 127*692d97c3Snir.tzachar@gmail.com "\n" 128*692d97c3Snir.tzachar@gmail.com "make NCONFIG_MODE=single_menu nconfig\n" 129*692d97c3Snir.tzachar@gmail.com "\n" 130*692d97c3Snir.tzachar@gmail.com "<Enter> will then unroll the appropriate category, or enfold it if it\n" 131*692d97c3Snir.tzachar@gmail.com "is already unrolled.\n" 132*692d97c3Snir.tzachar@gmail.com "\n" 133*692d97c3Snir.tzachar@gmail.com "Note that this mode can eventually be a little more CPU expensive\n" 134*692d97c3Snir.tzachar@gmail.com "(especially with a larger number of unrolled categories) than the\n" 135*692d97c3Snir.tzachar@gmail.com "default mode.\n" 136*692d97c3Snir.tzachar@gmail.com "\n"), 137*692d97c3Snir.tzachar@gmail.com menu_no_f_instructions[] = N_( 138*692d97c3Snir.tzachar@gmail.com " You do not have function keys support. Please follow the\n" 139*692d97c3Snir.tzachar@gmail.com " following instructions:\n" 140*692d97c3Snir.tzachar@gmail.com " Arrow keys navigate the menu.\n" 141*692d97c3Snir.tzachar@gmail.com " <Enter> or <right-arrow> selects submenus --->.\n" 142*692d97c3Snir.tzachar@gmail.com " Capital Letters are hotkeys.\n" 143*692d97c3Snir.tzachar@gmail.com " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" 144*692d97c3Snir.tzachar@gmail.com " Pressing SpaceBar toggles between the above options\n" 145*692d97c3Snir.tzachar@gmail.com " Press <Esc> or <left-arrow> to go back one menu, \n" 146*692d97c3Snir.tzachar@gmail.com " <?> or <h> for Help, </> for Search.\n" 147*692d97c3Snir.tzachar@gmail.com " <1> is interchangable with <F1>, <2> with <F2>, etc.\n" 148*692d97c3Snir.tzachar@gmail.com " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 149*692d97c3Snir.tzachar@gmail.com " <Esc> always leaves the current window\n"), 150*692d97c3Snir.tzachar@gmail.com menu_instructions[] = N_( 151*692d97c3Snir.tzachar@gmail.com " Arrow keys navigate the menu.\n" 152*692d97c3Snir.tzachar@gmail.com " <Enter> or <right-arrow> selects submenus --->.\n" 153*692d97c3Snir.tzachar@gmail.com " Capital Letters are hotkeys.\n" 154*692d97c3Snir.tzachar@gmail.com " Pressing <Y> includes, <N> excludes, <M> modularizes features.\n" 155*692d97c3Snir.tzachar@gmail.com " Pressing SpaceBar toggles between the above options\n" 156*692d97c3Snir.tzachar@gmail.com " Press <Esc>, <F3> or <left-arrow> to go back one menu, \n" 157*692d97c3Snir.tzachar@gmail.com " <?>, <F1> or <h> for Help, </> for Search.\n" 158*692d97c3Snir.tzachar@gmail.com " <1> is interchangable with <F1>, <2> with <F2>, etc.\n" 159*692d97c3Snir.tzachar@gmail.com " Legend: [*] built-in [ ] excluded <M> module < > module capable.\n" 160*692d97c3Snir.tzachar@gmail.com " <Esc> always leaves the current window\n"), 161*692d97c3Snir.tzachar@gmail.com radiolist_instructions[] = N_( 162*692d97c3Snir.tzachar@gmail.com " Use the arrow keys to navigate this window or\n" 163*692d97c3Snir.tzachar@gmail.com " press the hotkey of the item you wish to select\n" 164*692d97c3Snir.tzachar@gmail.com " followed by the <SPACE BAR>.\n" 165*692d97c3Snir.tzachar@gmail.com " Press <?>, <F1> or <h> for additional information about this option.\n"), 166*692d97c3Snir.tzachar@gmail.com inputbox_instructions_int[] = N_( 167*692d97c3Snir.tzachar@gmail.com "Please enter a decimal value.\n" 168*692d97c3Snir.tzachar@gmail.com "Fractions will not be accepted.\n" 169*692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."), 170*692d97c3Snir.tzachar@gmail.com inputbox_instructions_hex[] = N_( 171*692d97c3Snir.tzachar@gmail.com "Please enter a hexadecimal value.\n" 172*692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."), 173*692d97c3Snir.tzachar@gmail.com inputbox_instructions_string[] = N_( 174*692d97c3Snir.tzachar@gmail.com "Please enter a string value.\n" 175*692d97c3Snir.tzachar@gmail.com "Press <RETURN> to accept, <ESC> to cancel."), 176*692d97c3Snir.tzachar@gmail.com setmod_text[] = N_( 177*692d97c3Snir.tzachar@gmail.com "This feature depends on another which\n" 178*692d97c3Snir.tzachar@gmail.com "has been configured as a module.\n" 179*692d97c3Snir.tzachar@gmail.com "As a result, this feature will be built as a module."), 180*692d97c3Snir.tzachar@gmail.com nohelp_text[] = N_( 181*692d97c3Snir.tzachar@gmail.com "There is no help available for this kernel option.\n"), 182*692d97c3Snir.tzachar@gmail.com load_config_text[] = N_( 183*692d97c3Snir.tzachar@gmail.com "Enter the name of the configuration file you wish to load.\n" 184*692d97c3Snir.tzachar@gmail.com "Accept the name shown to restore the configuration you\n" 185*692d97c3Snir.tzachar@gmail.com "last retrieved. Leave blank to abort."), 186*692d97c3Snir.tzachar@gmail.com load_config_help[] = N_( 187*692d97c3Snir.tzachar@gmail.com "\n" 188*692d97c3Snir.tzachar@gmail.com "For various reasons, one may wish to keep several different kernel\n" 189*692d97c3Snir.tzachar@gmail.com "configurations available on a single machine.\n" 190*692d97c3Snir.tzachar@gmail.com "\n" 191*692d97c3Snir.tzachar@gmail.com "If you have saved a previous configuration in a file other than the\n" 192*692d97c3Snir.tzachar@gmail.com "kernel's default, entering the name of the file here will allow you\n" 193*692d97c3Snir.tzachar@gmail.com "to modify that configuration.\n" 194*692d97c3Snir.tzachar@gmail.com "\n" 195*692d97c3Snir.tzachar@gmail.com "If you are uncertain, then you have probably never used alternate\n" 196*692d97c3Snir.tzachar@gmail.com "configuration files. You should therefor leave this blank to abort.\n"), 197*692d97c3Snir.tzachar@gmail.com save_config_text[] = N_( 198*692d97c3Snir.tzachar@gmail.com "Enter a filename to which this configuration should be saved\n" 199*692d97c3Snir.tzachar@gmail.com "as an alternate. Leave blank to abort."), 200*692d97c3Snir.tzachar@gmail.com save_config_help[] = N_( 201*692d97c3Snir.tzachar@gmail.com "\n" 202*692d97c3Snir.tzachar@gmail.com "For various reasons, one may wish to keep different kernel\n" 203*692d97c3Snir.tzachar@gmail.com "configurations available on a single machine.\n" 204*692d97c3Snir.tzachar@gmail.com "\n" 205*692d97c3Snir.tzachar@gmail.com "Entering a file name here will allow you to later retrieve, modify\n" 206*692d97c3Snir.tzachar@gmail.com "and use the current configuration as an alternate to whatever\n" 207*692d97c3Snir.tzachar@gmail.com "configuration options you have selected at that time.\n" 208*692d97c3Snir.tzachar@gmail.com "\n" 209*692d97c3Snir.tzachar@gmail.com "If you are uncertain what all this means then you should probably\n" 210*692d97c3Snir.tzachar@gmail.com "leave this blank.\n"), 211*692d97c3Snir.tzachar@gmail.com search_help[] = N_( 212*692d97c3Snir.tzachar@gmail.com "\n" 213*692d97c3Snir.tzachar@gmail.com "Search for CONFIG_ symbols and display their relations.\n" 214*692d97c3Snir.tzachar@gmail.com "Regular expressions are allowed.\n" 215*692d97c3Snir.tzachar@gmail.com "Example: search for \"^FOO\"\n" 216*692d97c3Snir.tzachar@gmail.com "Result:\n" 217*692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n" 218*692d97c3Snir.tzachar@gmail.com "Symbol: FOO [ = m]\n" 219*692d97c3Snir.tzachar@gmail.com "Prompt: Foo bus is used to drive the bar HW\n" 220*692d97c3Snir.tzachar@gmail.com "Defined at drivers/pci/Kconfig:47\n" 221*692d97c3Snir.tzachar@gmail.com "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" 222*692d97c3Snir.tzachar@gmail.com "Location:\n" 223*692d97c3Snir.tzachar@gmail.com " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" 224*692d97c3Snir.tzachar@gmail.com " -> PCI support (PCI [ = y])\n" 225*692d97c3Snir.tzachar@gmail.com " -> PCI access mode (<choice> [ = y])\n" 226*692d97c3Snir.tzachar@gmail.com "Selects: LIBCRC32\n" 227*692d97c3Snir.tzachar@gmail.com "Selected by: BAR\n" 228*692d97c3Snir.tzachar@gmail.com "-----------------------------------------------------------------\n" 229*692d97c3Snir.tzachar@gmail.com "o The line 'Prompt:' shows the text used in the menu structure for\n" 230*692d97c3Snir.tzachar@gmail.com " this CONFIG_ symbol\n" 231*692d97c3Snir.tzachar@gmail.com "o The 'Defined at' line tell at what file / line number the symbol\n" 232*692d97c3Snir.tzachar@gmail.com " is defined\n" 233*692d97c3Snir.tzachar@gmail.com "o The 'Depends on:' line tell what symbols needs to be defined for\n" 234*692d97c3Snir.tzachar@gmail.com " this symbol to be visible in the menu (selectable)\n" 235*692d97c3Snir.tzachar@gmail.com "o The 'Location:' lines tell where in the menu structure this symbol\n" 236*692d97c3Snir.tzachar@gmail.com " is located\n" 237*692d97c3Snir.tzachar@gmail.com " A location followed by a [ = y] indicate that this is a selectable\n" 238*692d97c3Snir.tzachar@gmail.com " menu item - and current value is displayed inside brackets.\n" 239*692d97c3Snir.tzachar@gmail.com "o The 'Selects:' line tell what symbol will be automatically\n" 240*692d97c3Snir.tzachar@gmail.com " selected if this symbol is selected (y or m)\n" 241*692d97c3Snir.tzachar@gmail.com "o The 'Selected by' line tell what symbol has selected this symbol\n" 242*692d97c3Snir.tzachar@gmail.com "\n" 243*692d97c3Snir.tzachar@gmail.com "Only relevant lines are shown.\n" 244*692d97c3Snir.tzachar@gmail.com "\n\n" 245*692d97c3Snir.tzachar@gmail.com "Search examples:\n" 246*692d97c3Snir.tzachar@gmail.com "Examples: USB = > find all CONFIG_ symbols containing USB\n" 247*692d97c3Snir.tzachar@gmail.com " ^USB => find all CONFIG_ symbols starting with USB\n" 248*692d97c3Snir.tzachar@gmail.com " USB$ => find all CONFIG_ symbols ending with USB\n" 249*692d97c3Snir.tzachar@gmail.com "\n"); 250*692d97c3Snir.tzachar@gmail.com 251*692d97c3Snir.tzachar@gmail.com struct mitem { 252*692d97c3Snir.tzachar@gmail.com char str[256]; 253*692d97c3Snir.tzachar@gmail.com char tag; 254*692d97c3Snir.tzachar@gmail.com void *usrptr; 255*692d97c3Snir.tzachar@gmail.com int is_hot; 256*692d97c3Snir.tzachar@gmail.com int is_visible; 257*692d97c3Snir.tzachar@gmail.com }; 258*692d97c3Snir.tzachar@gmail.com 259*692d97c3Snir.tzachar@gmail.com #define MAX_MENU_ITEMS 4096 260*692d97c3Snir.tzachar@gmail.com static int show_all_items; 261*692d97c3Snir.tzachar@gmail.com static int indent; 262*692d97c3Snir.tzachar@gmail.com static struct menu *current_menu; 263*692d97c3Snir.tzachar@gmail.com static int child_count; 264*692d97c3Snir.tzachar@gmail.com static int single_menu_mode; 265*692d97c3Snir.tzachar@gmail.com /* the window in which all information appears */ 266*692d97c3Snir.tzachar@gmail.com static WINDOW *main_window; 267*692d97c3Snir.tzachar@gmail.com /* the largest size of the menu window */ 268*692d97c3Snir.tzachar@gmail.com static int mwin_max_lines; 269*692d97c3Snir.tzachar@gmail.com static int mwin_max_cols; 270*692d97c3Snir.tzachar@gmail.com /* the window in which we show option buttons */ 271*692d97c3Snir.tzachar@gmail.com static MENU *curses_menu; 272*692d97c3Snir.tzachar@gmail.com static ITEM *curses_menu_items[MAX_MENU_ITEMS]; 273*692d97c3Snir.tzachar@gmail.com static struct mitem k_menu_items[MAX_MENU_ITEMS]; 274*692d97c3Snir.tzachar@gmail.com static int items_num; 275*692d97c3Snir.tzachar@gmail.com static int global_exit; 276*692d97c3Snir.tzachar@gmail.com /* the currently selected button */ 277*692d97c3Snir.tzachar@gmail.com const char *current_instructions = menu_instructions; 278*692d97c3Snir.tzachar@gmail.com /* this array is used to implement hot keys. it is updated in item_make and 279*692d97c3Snir.tzachar@gmail.com * resetted in clean_items. It would be better to use a hash, but lets keep it 280*692d97c3Snir.tzachar@gmail.com * simple... */ 281*692d97c3Snir.tzachar@gmail.com #define MAX_SAME_KEY MAX_MENU_ITEMS 282*692d97c3Snir.tzachar@gmail.com struct { 283*692d97c3Snir.tzachar@gmail.com int count; 284*692d97c3Snir.tzachar@gmail.com int ptrs[MAX_MENU_ITEMS]; 285*692d97c3Snir.tzachar@gmail.com } hotkeys[1<<(sizeof(char)*8)]; 286*692d97c3Snir.tzachar@gmail.com 287*692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu); 288*692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu); 289*692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu); 290*692d97c3Snir.tzachar@gmail.com static void conf_load(void); 291*692d97c3Snir.tzachar@gmail.com static void conf_save(void); 292*692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu); 293*692d97c3Snir.tzachar@gmail.com static int do_exit(void); 294*692d97c3Snir.tzachar@gmail.com static void setup_windows(void); 295*692d97c3Snir.tzachar@gmail.com 296*692d97c3Snir.tzachar@gmail.com typedef void (*function_key_handler_t)(int *key, struct menu *menu); 297*692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item); 298*692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item); 299*692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item); 300*692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item); 301*692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item); 302*692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item); 303*692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item); 304*692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item); 305*692d97c3Snir.tzachar@gmail.com 306*692d97c3Snir.tzachar@gmail.com struct function_keys { 307*692d97c3Snir.tzachar@gmail.com const char *key_str; 308*692d97c3Snir.tzachar@gmail.com const char *func; 309*692d97c3Snir.tzachar@gmail.com function_key key; 310*692d97c3Snir.tzachar@gmail.com function_key_handler_t handler; 311*692d97c3Snir.tzachar@gmail.com }; 312*692d97c3Snir.tzachar@gmail.com 313*692d97c3Snir.tzachar@gmail.com static const int function_keys_num = 8; 314*692d97c3Snir.tzachar@gmail.com struct function_keys function_keys[] = { 315*692d97c3Snir.tzachar@gmail.com { 316*692d97c3Snir.tzachar@gmail.com .key_str = "F1", 317*692d97c3Snir.tzachar@gmail.com .func = "Help", 318*692d97c3Snir.tzachar@gmail.com .key = F_HELP, 319*692d97c3Snir.tzachar@gmail.com .handler = handle_f1, 320*692d97c3Snir.tzachar@gmail.com }, 321*692d97c3Snir.tzachar@gmail.com { 322*692d97c3Snir.tzachar@gmail.com .key_str = "F2", 323*692d97c3Snir.tzachar@gmail.com .func = "Symbol Info", 324*692d97c3Snir.tzachar@gmail.com .key = F_SYMBOL, 325*692d97c3Snir.tzachar@gmail.com .handler = handle_f2, 326*692d97c3Snir.tzachar@gmail.com }, 327*692d97c3Snir.tzachar@gmail.com { 328*692d97c3Snir.tzachar@gmail.com .key_str = "F3", 329*692d97c3Snir.tzachar@gmail.com .func = "Instructions", 330*692d97c3Snir.tzachar@gmail.com .key = F_INSTS, 331*692d97c3Snir.tzachar@gmail.com .handler = handle_f3, 332*692d97c3Snir.tzachar@gmail.com }, 333*692d97c3Snir.tzachar@gmail.com { 334*692d97c3Snir.tzachar@gmail.com .key_str = "F4", 335*692d97c3Snir.tzachar@gmail.com .func = "Config", 336*692d97c3Snir.tzachar@gmail.com .key = F_CONF, 337*692d97c3Snir.tzachar@gmail.com .handler = handle_f4, 338*692d97c3Snir.tzachar@gmail.com }, 339*692d97c3Snir.tzachar@gmail.com { 340*692d97c3Snir.tzachar@gmail.com .key_str = "F5", 341*692d97c3Snir.tzachar@gmail.com .func = "Back", 342*692d97c3Snir.tzachar@gmail.com .key = F_BACK, 343*692d97c3Snir.tzachar@gmail.com .handler = handle_f5, 344*692d97c3Snir.tzachar@gmail.com }, 345*692d97c3Snir.tzachar@gmail.com { 346*692d97c3Snir.tzachar@gmail.com .key_str = "F6", 347*692d97c3Snir.tzachar@gmail.com .func = "Save", 348*692d97c3Snir.tzachar@gmail.com .key = F_SAVE, 349*692d97c3Snir.tzachar@gmail.com .handler = handle_f6, 350*692d97c3Snir.tzachar@gmail.com }, 351*692d97c3Snir.tzachar@gmail.com { 352*692d97c3Snir.tzachar@gmail.com .key_str = "F7", 353*692d97c3Snir.tzachar@gmail.com .func = "Load", 354*692d97c3Snir.tzachar@gmail.com .key = F_LOAD, 355*692d97c3Snir.tzachar@gmail.com .handler = handle_f7, 356*692d97c3Snir.tzachar@gmail.com }, 357*692d97c3Snir.tzachar@gmail.com { 358*692d97c3Snir.tzachar@gmail.com .key_str = "F8", 359*692d97c3Snir.tzachar@gmail.com .func = "Exit", 360*692d97c3Snir.tzachar@gmail.com .key = F_EXIT, 361*692d97c3Snir.tzachar@gmail.com .handler = handle_f8, 362*692d97c3Snir.tzachar@gmail.com }, 363*692d97c3Snir.tzachar@gmail.com }; 364*692d97c3Snir.tzachar@gmail.com 365*692d97c3Snir.tzachar@gmail.com static void print_function_line(void) 366*692d97c3Snir.tzachar@gmail.com { 367*692d97c3Snir.tzachar@gmail.com int i; 368*692d97c3Snir.tzachar@gmail.com int offset = 1; 369*692d97c3Snir.tzachar@gmail.com const int skip = 1; 370*692d97c3Snir.tzachar@gmail.com 371*692d97c3Snir.tzachar@gmail.com for (i = 0; i < function_keys_num; i++) { 372*692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]); 373*692d97c3Snir.tzachar@gmail.com mvwprintw(main_window, LINES-3, offset, 374*692d97c3Snir.tzachar@gmail.com "%s", 375*692d97c3Snir.tzachar@gmail.com function_keys[i].key_str); 376*692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[FUNCTION_TEXT]); 377*692d97c3Snir.tzachar@gmail.com offset += strlen(function_keys[i].key_str); 378*692d97c3Snir.tzachar@gmail.com mvwprintw(main_window, LINES-3, 379*692d97c3Snir.tzachar@gmail.com offset, "%s", 380*692d97c3Snir.tzachar@gmail.com function_keys[i].func); 381*692d97c3Snir.tzachar@gmail.com offset += strlen(function_keys[i].func) + skip; 382*692d97c3Snir.tzachar@gmail.com } 383*692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[NORMAL]); 384*692d97c3Snir.tzachar@gmail.com } 385*692d97c3Snir.tzachar@gmail.com 386*692d97c3Snir.tzachar@gmail.com /* help */ 387*692d97c3Snir.tzachar@gmail.com static void handle_f1(int *key, struct menu *current_item) 388*692d97c3Snir.tzachar@gmail.com { 389*692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 390*692d97c3Snir.tzachar@gmail.com _("README"), _(nconf_readme)); 391*692d97c3Snir.tzachar@gmail.com return; 392*692d97c3Snir.tzachar@gmail.com } 393*692d97c3Snir.tzachar@gmail.com 394*692d97c3Snir.tzachar@gmail.com /* symbole help */ 395*692d97c3Snir.tzachar@gmail.com static void handle_f2(int *key, struct menu *current_item) 396*692d97c3Snir.tzachar@gmail.com { 397*692d97c3Snir.tzachar@gmail.com show_help(current_item); 398*692d97c3Snir.tzachar@gmail.com return; 399*692d97c3Snir.tzachar@gmail.com } 400*692d97c3Snir.tzachar@gmail.com 401*692d97c3Snir.tzachar@gmail.com /* instructions */ 402*692d97c3Snir.tzachar@gmail.com static void handle_f3(int *key, struct menu *current_item) 403*692d97c3Snir.tzachar@gmail.com { 404*692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 405*692d97c3Snir.tzachar@gmail.com _("Instructions"), 406*692d97c3Snir.tzachar@gmail.com _(current_instructions)); 407*692d97c3Snir.tzachar@gmail.com return; 408*692d97c3Snir.tzachar@gmail.com } 409*692d97c3Snir.tzachar@gmail.com 410*692d97c3Snir.tzachar@gmail.com /* config */ 411*692d97c3Snir.tzachar@gmail.com static void handle_f4(int *key, struct menu *current_item) 412*692d97c3Snir.tzachar@gmail.com { 413*692d97c3Snir.tzachar@gmail.com int res = btn_dialog(main_window, 414*692d97c3Snir.tzachar@gmail.com _("Show all symbols?"), 415*692d97c3Snir.tzachar@gmail.com 2, 416*692d97c3Snir.tzachar@gmail.com " <Show All> ", 417*692d97c3Snir.tzachar@gmail.com "<Don't show all>"); 418*692d97c3Snir.tzachar@gmail.com if (res == 0) 419*692d97c3Snir.tzachar@gmail.com show_all_items = 1; 420*692d97c3Snir.tzachar@gmail.com else if (res == 1) 421*692d97c3Snir.tzachar@gmail.com show_all_items = 0; 422*692d97c3Snir.tzachar@gmail.com 423*692d97c3Snir.tzachar@gmail.com return; 424*692d97c3Snir.tzachar@gmail.com } 425*692d97c3Snir.tzachar@gmail.com 426*692d97c3Snir.tzachar@gmail.com /* back */ 427*692d97c3Snir.tzachar@gmail.com static void handle_f5(int *key, struct menu *current_item) 428*692d97c3Snir.tzachar@gmail.com { 429*692d97c3Snir.tzachar@gmail.com *key = KEY_LEFT; 430*692d97c3Snir.tzachar@gmail.com return; 431*692d97c3Snir.tzachar@gmail.com } 432*692d97c3Snir.tzachar@gmail.com 433*692d97c3Snir.tzachar@gmail.com /* save */ 434*692d97c3Snir.tzachar@gmail.com static void handle_f6(int *key, struct menu *current_item) 435*692d97c3Snir.tzachar@gmail.com { 436*692d97c3Snir.tzachar@gmail.com conf_save(); 437*692d97c3Snir.tzachar@gmail.com return; 438*692d97c3Snir.tzachar@gmail.com } 439*692d97c3Snir.tzachar@gmail.com 440*692d97c3Snir.tzachar@gmail.com /* load */ 441*692d97c3Snir.tzachar@gmail.com static void handle_f7(int *key, struct menu *current_item) 442*692d97c3Snir.tzachar@gmail.com { 443*692d97c3Snir.tzachar@gmail.com conf_load(); 444*692d97c3Snir.tzachar@gmail.com return; 445*692d97c3Snir.tzachar@gmail.com } 446*692d97c3Snir.tzachar@gmail.com 447*692d97c3Snir.tzachar@gmail.com /* exit */ 448*692d97c3Snir.tzachar@gmail.com static void handle_f8(int *key, struct menu *current_item) 449*692d97c3Snir.tzachar@gmail.com { 450*692d97c3Snir.tzachar@gmail.com do_exit(); 451*692d97c3Snir.tzachar@gmail.com return; 452*692d97c3Snir.tzachar@gmail.com } 453*692d97c3Snir.tzachar@gmail.com 454*692d97c3Snir.tzachar@gmail.com /* return != 0 to indicate the key was handles */ 455*692d97c3Snir.tzachar@gmail.com int process_special_keys(int *key, struct menu *menu) 456*692d97c3Snir.tzachar@gmail.com { 457*692d97c3Snir.tzachar@gmail.com int i; 458*692d97c3Snir.tzachar@gmail.com 459*692d97c3Snir.tzachar@gmail.com if (*key == KEY_RESIZE) { 460*692d97c3Snir.tzachar@gmail.com setup_windows(); 461*692d97c3Snir.tzachar@gmail.com return 1; 462*692d97c3Snir.tzachar@gmail.com } 463*692d97c3Snir.tzachar@gmail.com 464*692d97c3Snir.tzachar@gmail.com for (i = 0; i < function_keys_num; i++) { 465*692d97c3Snir.tzachar@gmail.com if (*key == KEY_F(function_keys[i].key) || 466*692d97c3Snir.tzachar@gmail.com *key == '0' + function_keys[i].key){ 467*692d97c3Snir.tzachar@gmail.com function_keys[i].handler(key, menu); 468*692d97c3Snir.tzachar@gmail.com return 1; 469*692d97c3Snir.tzachar@gmail.com } 470*692d97c3Snir.tzachar@gmail.com } 471*692d97c3Snir.tzachar@gmail.com 472*692d97c3Snir.tzachar@gmail.com return 0; 473*692d97c3Snir.tzachar@gmail.com } 474*692d97c3Snir.tzachar@gmail.com 475*692d97c3Snir.tzachar@gmail.com static void clean_items(void) 476*692d97c3Snir.tzachar@gmail.com { 477*692d97c3Snir.tzachar@gmail.com int i; 478*692d97c3Snir.tzachar@gmail.com for (i = 0; curses_menu_items[i]; i++) 479*692d97c3Snir.tzachar@gmail.com free_item(curses_menu_items[i]); 480*692d97c3Snir.tzachar@gmail.com bzero(curses_menu_items, sizeof(curses_menu_items)); 481*692d97c3Snir.tzachar@gmail.com bzero(k_menu_items, sizeof(k_menu_items)); 482*692d97c3Snir.tzachar@gmail.com bzero(hotkeys, sizeof(hotkeys)); 483*692d97c3Snir.tzachar@gmail.com items_num = 0; 484*692d97c3Snir.tzachar@gmail.com } 485*692d97c3Snir.tzachar@gmail.com 486*692d97c3Snir.tzachar@gmail.com /* return the index of the next hot item, or -1 if no such item exists */ 487*692d97c3Snir.tzachar@gmail.com int get_next_hot(int c) 488*692d97c3Snir.tzachar@gmail.com { 489*692d97c3Snir.tzachar@gmail.com static int hot_index; 490*692d97c3Snir.tzachar@gmail.com static int hot_char; 491*692d97c3Snir.tzachar@gmail.com 492*692d97c3Snir.tzachar@gmail.com if (c < 0 || c > 255 || hotkeys[c].count <= 0) 493*692d97c3Snir.tzachar@gmail.com return -1; 494*692d97c3Snir.tzachar@gmail.com 495*692d97c3Snir.tzachar@gmail.com if (hot_char == c) { 496*692d97c3Snir.tzachar@gmail.com hot_index = (hot_index+1)%hotkeys[c].count; 497*692d97c3Snir.tzachar@gmail.com return hotkeys[c].ptrs[hot_index]; 498*692d97c3Snir.tzachar@gmail.com } else { 499*692d97c3Snir.tzachar@gmail.com hot_char = c; 500*692d97c3Snir.tzachar@gmail.com hot_index = 0; 501*692d97c3Snir.tzachar@gmail.com return hotkeys[c].ptrs[0]; 502*692d97c3Snir.tzachar@gmail.com } 503*692d97c3Snir.tzachar@gmail.com } 504*692d97c3Snir.tzachar@gmail.com 505*692d97c3Snir.tzachar@gmail.com /* can the char c be a hot key? no, if c is a common shortcut used elsewhere */ 506*692d97c3Snir.tzachar@gmail.com int canbhot(char c) 507*692d97c3Snir.tzachar@gmail.com { 508*692d97c3Snir.tzachar@gmail.com c = tolower(c); 509*692d97c3Snir.tzachar@gmail.com return isalnum(c) && c != 'y' && c != 'm' && c != 'h' && 510*692d97c3Snir.tzachar@gmail.com c != 'n' && c != '?'; 511*692d97c3Snir.tzachar@gmail.com } 512*692d97c3Snir.tzachar@gmail.com 513*692d97c3Snir.tzachar@gmail.com /* check if str already contains a hot key. */ 514*692d97c3Snir.tzachar@gmail.com int is_hot(int index) 515*692d97c3Snir.tzachar@gmail.com { 516*692d97c3Snir.tzachar@gmail.com return k_menu_items[index].is_hot; 517*692d97c3Snir.tzachar@gmail.com } 518*692d97c3Snir.tzachar@gmail.com 519*692d97c3Snir.tzachar@gmail.com /* find the first possible hot key, and mark it. 520*692d97c3Snir.tzachar@gmail.com * index is the index of the item in the menu 521*692d97c3Snir.tzachar@gmail.com * return 0 on success*/ 522*692d97c3Snir.tzachar@gmail.com int make_hot(char *dest, int len, const char *org, int index) 523*692d97c3Snir.tzachar@gmail.com { 524*692d97c3Snir.tzachar@gmail.com int position = -1; 525*692d97c3Snir.tzachar@gmail.com int i; 526*692d97c3Snir.tzachar@gmail.com int tmp; 527*692d97c3Snir.tzachar@gmail.com int c; 528*692d97c3Snir.tzachar@gmail.com int org_len = strlen(org); 529*692d97c3Snir.tzachar@gmail.com 530*692d97c3Snir.tzachar@gmail.com if (org == NULL || is_hot(index)) 531*692d97c3Snir.tzachar@gmail.com return 1; 532*692d97c3Snir.tzachar@gmail.com 533*692d97c3Snir.tzachar@gmail.com /* make sure not to make hot keys out of markers. 534*692d97c3Snir.tzachar@gmail.com * find where to start looking for a hot key 535*692d97c3Snir.tzachar@gmail.com */ 536*692d97c3Snir.tzachar@gmail.com i = 0; 537*692d97c3Snir.tzachar@gmail.com /* skip white space */ 538*692d97c3Snir.tzachar@gmail.com while (i < org_len && org[i] == ' ') 539*692d97c3Snir.tzachar@gmail.com i++; 540*692d97c3Snir.tzachar@gmail.com if (i == org_len) 541*692d97c3Snir.tzachar@gmail.com return -1; 542*692d97c3Snir.tzachar@gmail.com /* if encountering '(' or '<' or '[', find the match and look from there 543*692d97c3Snir.tzachar@gmail.com **/ 544*692d97c3Snir.tzachar@gmail.com if (org[i] == '[' || org[i] == '<' || org[i] == '(') { 545*692d97c3Snir.tzachar@gmail.com i++; 546*692d97c3Snir.tzachar@gmail.com for (; i < org_len; i++) 547*692d97c3Snir.tzachar@gmail.com if (org[i] == ']' || org[i] == '>' || org[i] == ')') 548*692d97c3Snir.tzachar@gmail.com break; 549*692d97c3Snir.tzachar@gmail.com } 550*692d97c3Snir.tzachar@gmail.com if (i == org_len) 551*692d97c3Snir.tzachar@gmail.com return -1; 552*692d97c3Snir.tzachar@gmail.com for (; i < org_len; i++) { 553*692d97c3Snir.tzachar@gmail.com if (canbhot(org[i]) && org[i-1] != '<' && org[i-1] != '(') { 554*692d97c3Snir.tzachar@gmail.com position = i; 555*692d97c3Snir.tzachar@gmail.com break; 556*692d97c3Snir.tzachar@gmail.com } 557*692d97c3Snir.tzachar@gmail.com } 558*692d97c3Snir.tzachar@gmail.com if (position == -1) 559*692d97c3Snir.tzachar@gmail.com return 1; 560*692d97c3Snir.tzachar@gmail.com 561*692d97c3Snir.tzachar@gmail.com /* ok, char at org[position] should be a hot key to this item */ 562*692d97c3Snir.tzachar@gmail.com c = tolower(org[position]); 563*692d97c3Snir.tzachar@gmail.com tmp = hotkeys[c].count; 564*692d97c3Snir.tzachar@gmail.com hotkeys[c].ptrs[tmp] = index; 565*692d97c3Snir.tzachar@gmail.com hotkeys[c].count++; 566*692d97c3Snir.tzachar@gmail.com /* 567*692d97c3Snir.tzachar@gmail.com snprintf(dest, len, "%.*s(%c)%s", position, org, org[position], 568*692d97c3Snir.tzachar@gmail.com &org[position+1]); 569*692d97c3Snir.tzachar@gmail.com */ 570*692d97c3Snir.tzachar@gmail.com /* make org[position] uppercase, and all leading letter small case */ 571*692d97c3Snir.tzachar@gmail.com strncpy(dest, org, len); 572*692d97c3Snir.tzachar@gmail.com for (i = 0; i < position; i++) 573*692d97c3Snir.tzachar@gmail.com dest[i] = tolower(dest[i]); 574*692d97c3Snir.tzachar@gmail.com dest[position] = toupper(dest[position]); 575*692d97c3Snir.tzachar@gmail.com k_menu_items[index].is_hot = 1; 576*692d97c3Snir.tzachar@gmail.com return 0; 577*692d97c3Snir.tzachar@gmail.com } 578*692d97c3Snir.tzachar@gmail.com 579*692d97c3Snir.tzachar@gmail.com /* Make a new item. Add a hotkey mark in the first possible letter. 580*692d97c3Snir.tzachar@gmail.com * As ncurses does not allow any attributes inside menue item, we mark the 581*692d97c3Snir.tzachar@gmail.com * hot key as the first capitalized letter in the string */ 582*692d97c3Snir.tzachar@gmail.com void item_make(struct menu *menu, char tag, const char *fmt, ...) 583*692d97c3Snir.tzachar@gmail.com { 584*692d97c3Snir.tzachar@gmail.com va_list ap; 585*692d97c3Snir.tzachar@gmail.com char tmp_str[256]; 586*692d97c3Snir.tzachar@gmail.com 587*692d97c3Snir.tzachar@gmail.com if (items_num > MAX_MENU_ITEMS-1) 588*692d97c3Snir.tzachar@gmail.com return; 589*692d97c3Snir.tzachar@gmail.com 590*692d97c3Snir.tzachar@gmail.com bzero(&k_menu_items[items_num], sizeof(k_menu_items[0])); 591*692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].tag = tag; 592*692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].usrptr = menu; 593*692d97c3Snir.tzachar@gmail.com if (menu != NULL) 594*692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].is_visible = 595*692d97c3Snir.tzachar@gmail.com menu_is_visible(menu); 596*692d97c3Snir.tzachar@gmail.com else 597*692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].is_visible = 1; 598*692d97c3Snir.tzachar@gmail.com 599*692d97c3Snir.tzachar@gmail.com va_start(ap, fmt); 600*692d97c3Snir.tzachar@gmail.com vsnprintf(tmp_str, sizeof(tmp_str), fmt, ap); 601*692d97c3Snir.tzachar@gmail.com if (!k_menu_items[items_num].is_visible) 602*692d97c3Snir.tzachar@gmail.com memcpy(tmp_str, "XXX", 3); 603*692d97c3Snir.tzachar@gmail.com va_end(ap); 604*692d97c3Snir.tzachar@gmail.com if (make_hot( 605*692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].str, 606*692d97c3Snir.tzachar@gmail.com sizeof(k_menu_items[items_num].str), tmp_str, items_num) != 0) 607*692d97c3Snir.tzachar@gmail.com strncpy(k_menu_items[items_num].str, 608*692d97c3Snir.tzachar@gmail.com tmp_str, 609*692d97c3Snir.tzachar@gmail.com sizeof(k_menu_items[items_num].str)); 610*692d97c3Snir.tzachar@gmail.com 611*692d97c3Snir.tzachar@gmail.com curses_menu_items[items_num] = new_item( 612*692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].str, 613*692d97c3Snir.tzachar@gmail.com k_menu_items[items_num].str); 614*692d97c3Snir.tzachar@gmail.com set_item_userptr(curses_menu_items[items_num], 615*692d97c3Snir.tzachar@gmail.com &k_menu_items[items_num]); 616*692d97c3Snir.tzachar@gmail.com /* 617*692d97c3Snir.tzachar@gmail.com if (!k_menu_items[items_num].is_visible) 618*692d97c3Snir.tzachar@gmail.com item_opts_off(curses_menu_items[items_num], O_SELECTABLE); 619*692d97c3Snir.tzachar@gmail.com */ 620*692d97c3Snir.tzachar@gmail.com 621*692d97c3Snir.tzachar@gmail.com items_num++; 622*692d97c3Snir.tzachar@gmail.com curses_menu_items[items_num] = NULL; 623*692d97c3Snir.tzachar@gmail.com } 624*692d97c3Snir.tzachar@gmail.com 625*692d97c3Snir.tzachar@gmail.com /* very hackish. adds a string to the last item added */ 626*692d97c3Snir.tzachar@gmail.com void item_add_str(const char *fmt, ...) 627*692d97c3Snir.tzachar@gmail.com { 628*692d97c3Snir.tzachar@gmail.com va_list ap; 629*692d97c3Snir.tzachar@gmail.com int index = items_num-1; 630*692d97c3Snir.tzachar@gmail.com char new_str[256]; 631*692d97c3Snir.tzachar@gmail.com char tmp_str[256]; 632*692d97c3Snir.tzachar@gmail.com 633*692d97c3Snir.tzachar@gmail.com if (index < 0) 634*692d97c3Snir.tzachar@gmail.com return; 635*692d97c3Snir.tzachar@gmail.com 636*692d97c3Snir.tzachar@gmail.com va_start(ap, fmt); 637*692d97c3Snir.tzachar@gmail.com vsnprintf(new_str, sizeof(new_str), fmt, ap); 638*692d97c3Snir.tzachar@gmail.com va_end(ap); 639*692d97c3Snir.tzachar@gmail.com snprintf(tmp_str, sizeof(tmp_str), "%s%s", 640*692d97c3Snir.tzachar@gmail.com k_menu_items[index].str, new_str); 641*692d97c3Snir.tzachar@gmail.com if (make_hot(k_menu_items[index].str, 642*692d97c3Snir.tzachar@gmail.com sizeof(k_menu_items[index].str), tmp_str, index) != 0) 643*692d97c3Snir.tzachar@gmail.com strncpy(k_menu_items[index].str, 644*692d97c3Snir.tzachar@gmail.com tmp_str, 645*692d97c3Snir.tzachar@gmail.com sizeof(k_menu_items[index].str)); 646*692d97c3Snir.tzachar@gmail.com 647*692d97c3Snir.tzachar@gmail.com free_item(curses_menu_items[index]); 648*692d97c3Snir.tzachar@gmail.com curses_menu_items[index] = new_item( 649*692d97c3Snir.tzachar@gmail.com k_menu_items[index].str, 650*692d97c3Snir.tzachar@gmail.com k_menu_items[index].str); 651*692d97c3Snir.tzachar@gmail.com set_item_userptr(curses_menu_items[index], 652*692d97c3Snir.tzachar@gmail.com &k_menu_items[index]); 653*692d97c3Snir.tzachar@gmail.com } 654*692d97c3Snir.tzachar@gmail.com 655*692d97c3Snir.tzachar@gmail.com /* get the tag of the currently selected item */ 656*692d97c3Snir.tzachar@gmail.com char item_tag(void) 657*692d97c3Snir.tzachar@gmail.com { 658*692d97c3Snir.tzachar@gmail.com ITEM *cur; 659*692d97c3Snir.tzachar@gmail.com struct mitem *mcur; 660*692d97c3Snir.tzachar@gmail.com 661*692d97c3Snir.tzachar@gmail.com cur = current_item(curses_menu); 662*692d97c3Snir.tzachar@gmail.com if (cur == NULL) 663*692d97c3Snir.tzachar@gmail.com return 0; 664*692d97c3Snir.tzachar@gmail.com mcur = (struct mitem *) item_userptr(cur); 665*692d97c3Snir.tzachar@gmail.com return mcur->tag; 666*692d97c3Snir.tzachar@gmail.com } 667*692d97c3Snir.tzachar@gmail.com 668*692d97c3Snir.tzachar@gmail.com int curses_item_index(void) 669*692d97c3Snir.tzachar@gmail.com { 670*692d97c3Snir.tzachar@gmail.com return item_index(current_item(curses_menu)); 671*692d97c3Snir.tzachar@gmail.com } 672*692d97c3Snir.tzachar@gmail.com 673*692d97c3Snir.tzachar@gmail.com void *item_data(void) 674*692d97c3Snir.tzachar@gmail.com { 675*692d97c3Snir.tzachar@gmail.com ITEM *cur; 676*692d97c3Snir.tzachar@gmail.com struct mitem *mcur; 677*692d97c3Snir.tzachar@gmail.com 678*692d97c3Snir.tzachar@gmail.com cur = current_item(curses_menu); 679*692d97c3Snir.tzachar@gmail.com mcur = (struct mitem *) item_userptr(cur); 680*692d97c3Snir.tzachar@gmail.com return mcur->usrptr; 681*692d97c3Snir.tzachar@gmail.com 682*692d97c3Snir.tzachar@gmail.com } 683*692d97c3Snir.tzachar@gmail.com 684*692d97c3Snir.tzachar@gmail.com int item_is_tag(char tag) 685*692d97c3Snir.tzachar@gmail.com { 686*692d97c3Snir.tzachar@gmail.com return item_tag() == tag; 687*692d97c3Snir.tzachar@gmail.com } 688*692d97c3Snir.tzachar@gmail.com 689*692d97c3Snir.tzachar@gmail.com static char filename[PATH_MAX+1]; 690*692d97c3Snir.tzachar@gmail.com static char menu_backtitle[PATH_MAX+128]; 691*692d97c3Snir.tzachar@gmail.com const char *set_config_filename(const char *config_filename) 692*692d97c3Snir.tzachar@gmail.com { 693*692d97c3Snir.tzachar@gmail.com int size; 694*692d97c3Snir.tzachar@gmail.com struct symbol *sym; 695*692d97c3Snir.tzachar@gmail.com 696*692d97c3Snir.tzachar@gmail.com sym = sym_lookup("KERNELVERSION", 0); 697*692d97c3Snir.tzachar@gmail.com sym_calc_value(sym); 698*692d97c3Snir.tzachar@gmail.com size = snprintf(menu_backtitle, sizeof(menu_backtitle), 699*692d97c3Snir.tzachar@gmail.com _("%s - Linux Kernel v%s Configuration"), 700*692d97c3Snir.tzachar@gmail.com config_filename, sym_get_string_value(sym)); 701*692d97c3Snir.tzachar@gmail.com if (size >= sizeof(menu_backtitle)) 702*692d97c3Snir.tzachar@gmail.com menu_backtitle[sizeof(menu_backtitle)-1] = '\0'; 703*692d97c3Snir.tzachar@gmail.com 704*692d97c3Snir.tzachar@gmail.com size = snprintf(filename, sizeof(filename), "%s", config_filename); 705*692d97c3Snir.tzachar@gmail.com if (size >= sizeof(filename)) 706*692d97c3Snir.tzachar@gmail.com filename[sizeof(filename)-1] = '\0'; 707*692d97c3Snir.tzachar@gmail.com return menu_backtitle; 708*692d97c3Snir.tzachar@gmail.com } 709*692d97c3Snir.tzachar@gmail.com 710*692d97c3Snir.tzachar@gmail.com /* command = 0 is supress, 1 is restore */ 711*692d97c3Snir.tzachar@gmail.com static void supress_stdout(int command) 712*692d97c3Snir.tzachar@gmail.com { 713*692d97c3Snir.tzachar@gmail.com static FILE *org_stdout; 714*692d97c3Snir.tzachar@gmail.com static FILE *org_stderr; 715*692d97c3Snir.tzachar@gmail.com 716*692d97c3Snir.tzachar@gmail.com if (command == 0) { 717*692d97c3Snir.tzachar@gmail.com org_stdout = stdout; 718*692d97c3Snir.tzachar@gmail.com org_stderr = stderr; 719*692d97c3Snir.tzachar@gmail.com stdout = fopen("/dev/null", "a"); 720*692d97c3Snir.tzachar@gmail.com stderr = fopen("/dev/null", "a"); 721*692d97c3Snir.tzachar@gmail.com } else { 722*692d97c3Snir.tzachar@gmail.com fclose(stdout); 723*692d97c3Snir.tzachar@gmail.com fclose(stderr); 724*692d97c3Snir.tzachar@gmail.com stdout = org_stdout; 725*692d97c3Snir.tzachar@gmail.com stderr = org_stderr; 726*692d97c3Snir.tzachar@gmail.com } 727*692d97c3Snir.tzachar@gmail.com } 728*692d97c3Snir.tzachar@gmail.com 729*692d97c3Snir.tzachar@gmail.com /* return = 0 means we are successful. 730*692d97c3Snir.tzachar@gmail.com * -1 means go on doing what you were doing 731*692d97c3Snir.tzachar@gmail.com */ 732*692d97c3Snir.tzachar@gmail.com static int do_exit(void) 733*692d97c3Snir.tzachar@gmail.com { 734*692d97c3Snir.tzachar@gmail.com int res; 735*692d97c3Snir.tzachar@gmail.com if (!conf_get_changed()) { 736*692d97c3Snir.tzachar@gmail.com global_exit = 1; 737*692d97c3Snir.tzachar@gmail.com return 0; 738*692d97c3Snir.tzachar@gmail.com } 739*692d97c3Snir.tzachar@gmail.com res = btn_dialog(main_window, 740*692d97c3Snir.tzachar@gmail.com _("Do you wish to save your " 741*692d97c3Snir.tzachar@gmail.com "new kernel configuration?\n" 742*692d97c3Snir.tzachar@gmail.com "<ESC> to cancel and resume nconfig."), 743*692d97c3Snir.tzachar@gmail.com 2, 744*692d97c3Snir.tzachar@gmail.com " <save> ", 745*692d97c3Snir.tzachar@gmail.com "<don't save>"); 746*692d97c3Snir.tzachar@gmail.com if (res == KEY_EXIT) { 747*692d97c3Snir.tzachar@gmail.com global_exit = 0; 748*692d97c3Snir.tzachar@gmail.com return -1; 749*692d97c3Snir.tzachar@gmail.com } 750*692d97c3Snir.tzachar@gmail.com 751*692d97c3Snir.tzachar@gmail.com /* if we got here, the user really wants to exit */ 752*692d97c3Snir.tzachar@gmail.com switch (res) { 753*692d97c3Snir.tzachar@gmail.com case 0: 754*692d97c3Snir.tzachar@gmail.com supress_stdout(0); 755*692d97c3Snir.tzachar@gmail.com res = conf_write(filename); 756*692d97c3Snir.tzachar@gmail.com supress_stdout(1); 757*692d97c3Snir.tzachar@gmail.com if (res) 758*692d97c3Snir.tzachar@gmail.com btn_dialog( 759*692d97c3Snir.tzachar@gmail.com main_window, 760*692d97c3Snir.tzachar@gmail.com _("Error during writing of the kernel " 761*692d97c3Snir.tzachar@gmail.com "configuration.\n" 762*692d97c3Snir.tzachar@gmail.com "Your kernel configuration " 763*692d97c3Snir.tzachar@gmail.com "changes were NOT saved."), 764*692d97c3Snir.tzachar@gmail.com 1, 765*692d97c3Snir.tzachar@gmail.com "<OK>"); 766*692d97c3Snir.tzachar@gmail.com else { 767*692d97c3Snir.tzachar@gmail.com char buf[1024]; 768*692d97c3Snir.tzachar@gmail.com snprintf(buf, 1024, 769*692d97c3Snir.tzachar@gmail.com _("Configuration written to %s\n" 770*692d97c3Snir.tzachar@gmail.com "End of Linux kernel configuration.\n" 771*692d97c3Snir.tzachar@gmail.com "Execute 'make' to build the kernel or try" 772*692d97c3Snir.tzachar@gmail.com " 'make help'."), filename); 773*692d97c3Snir.tzachar@gmail.com btn_dialog( 774*692d97c3Snir.tzachar@gmail.com main_window, 775*692d97c3Snir.tzachar@gmail.com buf, 776*692d97c3Snir.tzachar@gmail.com 1, 777*692d97c3Snir.tzachar@gmail.com "<OK>"); 778*692d97c3Snir.tzachar@gmail.com } 779*692d97c3Snir.tzachar@gmail.com break; 780*692d97c3Snir.tzachar@gmail.com default: 781*692d97c3Snir.tzachar@gmail.com btn_dialog( 782*692d97c3Snir.tzachar@gmail.com main_window, 783*692d97c3Snir.tzachar@gmail.com _("Your kernel configuration changes were NOT saved."), 784*692d97c3Snir.tzachar@gmail.com 1, 785*692d97c3Snir.tzachar@gmail.com "<OK>"); 786*692d97c3Snir.tzachar@gmail.com break; 787*692d97c3Snir.tzachar@gmail.com } 788*692d97c3Snir.tzachar@gmail.com global_exit = 1; 789*692d97c3Snir.tzachar@gmail.com return 0; 790*692d97c3Snir.tzachar@gmail.com } 791*692d97c3Snir.tzachar@gmail.com 792*692d97c3Snir.tzachar@gmail.com 793*692d97c3Snir.tzachar@gmail.com static void search_conf(void) 794*692d97c3Snir.tzachar@gmail.com { 795*692d97c3Snir.tzachar@gmail.com struct symbol **sym_arr; 796*692d97c3Snir.tzachar@gmail.com struct gstr res; 797*692d97c3Snir.tzachar@gmail.com char dialog_input_result[100]; 798*692d97c3Snir.tzachar@gmail.com char *dialog_input; 799*692d97c3Snir.tzachar@gmail.com int dres; 800*692d97c3Snir.tzachar@gmail.com again: 801*692d97c3Snir.tzachar@gmail.com dres = dialog_inputbox(main_window, 802*692d97c3Snir.tzachar@gmail.com _("Search Configuration Parameter"), 803*692d97c3Snir.tzachar@gmail.com _("Enter CONFIG_ (sub)string to search for " 804*692d97c3Snir.tzachar@gmail.com "(with or without \"CONFIG\")"), 805*692d97c3Snir.tzachar@gmail.com "", dialog_input_result, 99); 806*692d97c3Snir.tzachar@gmail.com switch (dres) { 807*692d97c3Snir.tzachar@gmail.com case 0: 808*692d97c3Snir.tzachar@gmail.com break; 809*692d97c3Snir.tzachar@gmail.com case 1: 810*692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 811*692d97c3Snir.tzachar@gmail.com _("Search Configuration"), search_help); 812*692d97c3Snir.tzachar@gmail.com goto again; 813*692d97c3Snir.tzachar@gmail.com default: 814*692d97c3Snir.tzachar@gmail.com return; 815*692d97c3Snir.tzachar@gmail.com } 816*692d97c3Snir.tzachar@gmail.com 817*692d97c3Snir.tzachar@gmail.com /* strip CONFIG_ if necessary */ 818*692d97c3Snir.tzachar@gmail.com dialog_input = dialog_input_result; 819*692d97c3Snir.tzachar@gmail.com if (strncasecmp(dialog_input_result, "CONFIG_", 7) == 0) 820*692d97c3Snir.tzachar@gmail.com dialog_input += 7; 821*692d97c3Snir.tzachar@gmail.com 822*692d97c3Snir.tzachar@gmail.com sym_arr = sym_re_search(dialog_input); 823*692d97c3Snir.tzachar@gmail.com res = get_relations_str(sym_arr); 824*692d97c3Snir.tzachar@gmail.com free(sym_arr); 825*692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 826*692d97c3Snir.tzachar@gmail.com _("Search Results"), str_get(&res)); 827*692d97c3Snir.tzachar@gmail.com str_free(&res); 828*692d97c3Snir.tzachar@gmail.com } 829*692d97c3Snir.tzachar@gmail.com 830*692d97c3Snir.tzachar@gmail.com 831*692d97c3Snir.tzachar@gmail.com static void build_conf(struct menu *menu) 832*692d97c3Snir.tzachar@gmail.com { 833*692d97c3Snir.tzachar@gmail.com struct symbol *sym; 834*692d97c3Snir.tzachar@gmail.com struct property *prop; 835*692d97c3Snir.tzachar@gmail.com struct menu *child; 836*692d97c3Snir.tzachar@gmail.com int type, tmp, doint = 2; 837*692d97c3Snir.tzachar@gmail.com tristate val; 838*692d97c3Snir.tzachar@gmail.com char ch; 839*692d97c3Snir.tzachar@gmail.com 840*692d97c3Snir.tzachar@gmail.com if (!menu || (!show_all_items && !menu_is_visible(menu))) 841*692d97c3Snir.tzachar@gmail.com return; 842*692d97c3Snir.tzachar@gmail.com 843*692d97c3Snir.tzachar@gmail.com sym = menu->sym; 844*692d97c3Snir.tzachar@gmail.com prop = menu->prompt; 845*692d97c3Snir.tzachar@gmail.com if (!sym) { 846*692d97c3Snir.tzachar@gmail.com if (prop && menu != current_menu) { 847*692d97c3Snir.tzachar@gmail.com const char *prompt = menu_get_prompt(menu); 848*692d97c3Snir.tzachar@gmail.com enum prop_type ptype; 849*692d97c3Snir.tzachar@gmail.com ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 850*692d97c3Snir.tzachar@gmail.com switch (ptype) { 851*692d97c3Snir.tzachar@gmail.com case P_MENU: 852*692d97c3Snir.tzachar@gmail.com child_count++; 853*692d97c3Snir.tzachar@gmail.com prompt = _(prompt); 854*692d97c3Snir.tzachar@gmail.com if (single_menu_mode) { 855*692d97c3Snir.tzachar@gmail.com item_make(menu, 'm', 856*692d97c3Snir.tzachar@gmail.com "%s%*c%s", 857*692d97c3Snir.tzachar@gmail.com menu->data ? "-->" : "++>", 858*692d97c3Snir.tzachar@gmail.com indent + 1, ' ', prompt); 859*692d97c3Snir.tzachar@gmail.com } else 860*692d97c3Snir.tzachar@gmail.com item_make(menu, 'm', 861*692d97c3Snir.tzachar@gmail.com " %*c%s --->", 862*692d97c3Snir.tzachar@gmail.com indent + 1, 863*692d97c3Snir.tzachar@gmail.com ' ', prompt); 864*692d97c3Snir.tzachar@gmail.com 865*692d97c3Snir.tzachar@gmail.com if (single_menu_mode && menu->data) 866*692d97c3Snir.tzachar@gmail.com goto conf_childs; 867*692d97c3Snir.tzachar@gmail.com return; 868*692d97c3Snir.tzachar@gmail.com case P_COMMENT: 869*692d97c3Snir.tzachar@gmail.com if (prompt) { 870*692d97c3Snir.tzachar@gmail.com child_count++; 871*692d97c3Snir.tzachar@gmail.com item_make(menu, ':', 872*692d97c3Snir.tzachar@gmail.com " %*c*** %s ***", 873*692d97c3Snir.tzachar@gmail.com indent + 1, ' ', 874*692d97c3Snir.tzachar@gmail.com _(prompt)); 875*692d97c3Snir.tzachar@gmail.com } 876*692d97c3Snir.tzachar@gmail.com break; 877*692d97c3Snir.tzachar@gmail.com default: 878*692d97c3Snir.tzachar@gmail.com if (prompt) { 879*692d97c3Snir.tzachar@gmail.com child_count++; 880*692d97c3Snir.tzachar@gmail.com item_make(menu, ':', "---%*c%s", 881*692d97c3Snir.tzachar@gmail.com indent + 1, ' ', 882*692d97c3Snir.tzachar@gmail.com _(prompt)); 883*692d97c3Snir.tzachar@gmail.com } 884*692d97c3Snir.tzachar@gmail.com } 885*692d97c3Snir.tzachar@gmail.com } else 886*692d97c3Snir.tzachar@gmail.com doint = 0; 887*692d97c3Snir.tzachar@gmail.com goto conf_childs; 888*692d97c3Snir.tzachar@gmail.com } 889*692d97c3Snir.tzachar@gmail.com 890*692d97c3Snir.tzachar@gmail.com type = sym_get_type(sym); 891*692d97c3Snir.tzachar@gmail.com if (sym_is_choice(sym)) { 892*692d97c3Snir.tzachar@gmail.com struct symbol *def_sym = sym_get_choice_value(sym); 893*692d97c3Snir.tzachar@gmail.com struct menu *def_menu = NULL; 894*692d97c3Snir.tzachar@gmail.com 895*692d97c3Snir.tzachar@gmail.com child_count++; 896*692d97c3Snir.tzachar@gmail.com for (child = menu->list; child; child = child->next) { 897*692d97c3Snir.tzachar@gmail.com if (menu_is_visible(child) && child->sym == def_sym) 898*692d97c3Snir.tzachar@gmail.com def_menu = child; 899*692d97c3Snir.tzachar@gmail.com } 900*692d97c3Snir.tzachar@gmail.com 901*692d97c3Snir.tzachar@gmail.com val = sym_get_tristate_value(sym); 902*692d97c3Snir.tzachar@gmail.com if (sym_is_changable(sym)) { 903*692d97c3Snir.tzachar@gmail.com switch (type) { 904*692d97c3Snir.tzachar@gmail.com case S_BOOLEAN: 905*692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "[%c]", 906*692d97c3Snir.tzachar@gmail.com val == no ? ' ' : '*'); 907*692d97c3Snir.tzachar@gmail.com break; 908*692d97c3Snir.tzachar@gmail.com case S_TRISTATE: 909*692d97c3Snir.tzachar@gmail.com switch (val) { 910*692d97c3Snir.tzachar@gmail.com case yes: 911*692d97c3Snir.tzachar@gmail.com ch = '*'; 912*692d97c3Snir.tzachar@gmail.com break; 913*692d97c3Snir.tzachar@gmail.com case mod: 914*692d97c3Snir.tzachar@gmail.com ch = 'M'; 915*692d97c3Snir.tzachar@gmail.com break; 916*692d97c3Snir.tzachar@gmail.com default: 917*692d97c3Snir.tzachar@gmail.com ch = ' '; 918*692d97c3Snir.tzachar@gmail.com break; 919*692d97c3Snir.tzachar@gmail.com } 920*692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "<%c>", ch); 921*692d97c3Snir.tzachar@gmail.com break; 922*692d97c3Snir.tzachar@gmail.com } 923*692d97c3Snir.tzachar@gmail.com } else { 924*692d97c3Snir.tzachar@gmail.com item_make(menu, def_menu ? 't' : ':', " "); 925*692d97c3Snir.tzachar@gmail.com } 926*692d97c3Snir.tzachar@gmail.com 927*692d97c3Snir.tzachar@gmail.com item_add_str("%*c%s", indent + 1, 928*692d97c3Snir.tzachar@gmail.com ' ', _(menu_get_prompt(menu))); 929*692d97c3Snir.tzachar@gmail.com if (val == yes) { 930*692d97c3Snir.tzachar@gmail.com if (def_menu) { 931*692d97c3Snir.tzachar@gmail.com item_add_str(" (%s)", 932*692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(def_menu))); 933*692d97c3Snir.tzachar@gmail.com item_add_str(" --->"); 934*692d97c3Snir.tzachar@gmail.com if (def_menu->list) { 935*692d97c3Snir.tzachar@gmail.com indent += 2; 936*692d97c3Snir.tzachar@gmail.com build_conf(def_menu); 937*692d97c3Snir.tzachar@gmail.com indent -= 2; 938*692d97c3Snir.tzachar@gmail.com } 939*692d97c3Snir.tzachar@gmail.com } 940*692d97c3Snir.tzachar@gmail.com return; 941*692d97c3Snir.tzachar@gmail.com } 942*692d97c3Snir.tzachar@gmail.com } else { 943*692d97c3Snir.tzachar@gmail.com if (menu == current_menu) { 944*692d97c3Snir.tzachar@gmail.com item_make(menu, ':', 945*692d97c3Snir.tzachar@gmail.com "---%*c%s", indent + 1, 946*692d97c3Snir.tzachar@gmail.com ' ', _(menu_get_prompt(menu))); 947*692d97c3Snir.tzachar@gmail.com goto conf_childs; 948*692d97c3Snir.tzachar@gmail.com } 949*692d97c3Snir.tzachar@gmail.com child_count++; 950*692d97c3Snir.tzachar@gmail.com val = sym_get_tristate_value(sym); 951*692d97c3Snir.tzachar@gmail.com if (sym_is_choice_value(sym) && val == yes) { 952*692d97c3Snir.tzachar@gmail.com item_make(menu, ':', " "); 953*692d97c3Snir.tzachar@gmail.com } else { 954*692d97c3Snir.tzachar@gmail.com switch (type) { 955*692d97c3Snir.tzachar@gmail.com case S_BOOLEAN: 956*692d97c3Snir.tzachar@gmail.com if (sym_is_changable(sym)) 957*692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "[%c]", 958*692d97c3Snir.tzachar@gmail.com val == no ? ' ' : '*'); 959*692d97c3Snir.tzachar@gmail.com else 960*692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "-%c-", 961*692d97c3Snir.tzachar@gmail.com val == no ? ' ' : '*'); 962*692d97c3Snir.tzachar@gmail.com break; 963*692d97c3Snir.tzachar@gmail.com case S_TRISTATE: 964*692d97c3Snir.tzachar@gmail.com switch (val) { 965*692d97c3Snir.tzachar@gmail.com case yes: 966*692d97c3Snir.tzachar@gmail.com ch = '*'; 967*692d97c3Snir.tzachar@gmail.com break; 968*692d97c3Snir.tzachar@gmail.com case mod: 969*692d97c3Snir.tzachar@gmail.com ch = 'M'; 970*692d97c3Snir.tzachar@gmail.com break; 971*692d97c3Snir.tzachar@gmail.com default: 972*692d97c3Snir.tzachar@gmail.com ch = ' '; 973*692d97c3Snir.tzachar@gmail.com break; 974*692d97c3Snir.tzachar@gmail.com } 975*692d97c3Snir.tzachar@gmail.com if (sym_is_changable(sym)) { 976*692d97c3Snir.tzachar@gmail.com if (sym->rev_dep.tri == mod) 977*692d97c3Snir.tzachar@gmail.com item_make(menu, 978*692d97c3Snir.tzachar@gmail.com 't', "{%c}", ch); 979*692d97c3Snir.tzachar@gmail.com else 980*692d97c3Snir.tzachar@gmail.com item_make(menu, 981*692d97c3Snir.tzachar@gmail.com 't', "<%c>", ch); 982*692d97c3Snir.tzachar@gmail.com } else 983*692d97c3Snir.tzachar@gmail.com item_make(menu, 't', "-%c-", ch); 984*692d97c3Snir.tzachar@gmail.com break; 985*692d97c3Snir.tzachar@gmail.com default: 986*692d97c3Snir.tzachar@gmail.com tmp = 2 + strlen(sym_get_string_value(sym)); 987*692d97c3Snir.tzachar@gmail.com item_make(menu, 's', "(%s)", 988*692d97c3Snir.tzachar@gmail.com sym_get_string_value(sym)); 989*692d97c3Snir.tzachar@gmail.com tmp = indent - tmp + 4; 990*692d97c3Snir.tzachar@gmail.com if (tmp < 0) 991*692d97c3Snir.tzachar@gmail.com tmp = 0; 992*692d97c3Snir.tzachar@gmail.com item_add_str("%*c%s%s", tmp, ' ', 993*692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(menu)), 994*692d97c3Snir.tzachar@gmail.com (sym_has_value(sym) || 995*692d97c3Snir.tzachar@gmail.com !sym_is_changable(sym)) ? "" : 996*692d97c3Snir.tzachar@gmail.com _(" (NEW)")); 997*692d97c3Snir.tzachar@gmail.com goto conf_childs; 998*692d97c3Snir.tzachar@gmail.com } 999*692d97c3Snir.tzachar@gmail.com } 1000*692d97c3Snir.tzachar@gmail.com item_add_str("%*c%s%s", indent + 1, ' ', 1001*692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(menu)), 1002*692d97c3Snir.tzachar@gmail.com (sym_has_value(sym) || !sym_is_changable(sym)) ? 1003*692d97c3Snir.tzachar@gmail.com "" : _(" (NEW)")); 1004*692d97c3Snir.tzachar@gmail.com if (menu->prompt && menu->prompt->type == P_MENU) { 1005*692d97c3Snir.tzachar@gmail.com item_add_str(" --->"); 1006*692d97c3Snir.tzachar@gmail.com return; 1007*692d97c3Snir.tzachar@gmail.com } 1008*692d97c3Snir.tzachar@gmail.com } 1009*692d97c3Snir.tzachar@gmail.com 1010*692d97c3Snir.tzachar@gmail.com conf_childs: 1011*692d97c3Snir.tzachar@gmail.com indent += doint; 1012*692d97c3Snir.tzachar@gmail.com for (child = menu->list; child; child = child->next) 1013*692d97c3Snir.tzachar@gmail.com build_conf(child); 1014*692d97c3Snir.tzachar@gmail.com indent -= doint; 1015*692d97c3Snir.tzachar@gmail.com } 1016*692d97c3Snir.tzachar@gmail.com 1017*692d97c3Snir.tzachar@gmail.com static void reset_menu(void) 1018*692d97c3Snir.tzachar@gmail.com { 1019*692d97c3Snir.tzachar@gmail.com unpost_menu(curses_menu); 1020*692d97c3Snir.tzachar@gmail.com clean_items(); 1021*692d97c3Snir.tzachar@gmail.com } 1022*692d97c3Snir.tzachar@gmail.com 1023*692d97c3Snir.tzachar@gmail.com /* adjust the menu to show this item. 1024*692d97c3Snir.tzachar@gmail.com * prefer not to scroll the menu if possible*/ 1025*692d97c3Snir.tzachar@gmail.com static void center_item(int selected_index, int *last_top_row) 1026*692d97c3Snir.tzachar@gmail.com { 1027*692d97c3Snir.tzachar@gmail.com int toprow; 1028*692d97c3Snir.tzachar@gmail.com int maxy, maxx; 1029*692d97c3Snir.tzachar@gmail.com 1030*692d97c3Snir.tzachar@gmail.com scale_menu(curses_menu, &maxy, &maxx); 1031*692d97c3Snir.tzachar@gmail.com set_top_row(curses_menu, *last_top_row); 1032*692d97c3Snir.tzachar@gmail.com toprow = top_row(curses_menu); 1033*692d97c3Snir.tzachar@gmail.com if (selected_index >= toprow && selected_index < toprow+maxy) { 1034*692d97c3Snir.tzachar@gmail.com /* we can only move the selected item. no need to scroll */ 1035*692d97c3Snir.tzachar@gmail.com set_current_item(curses_menu, 1036*692d97c3Snir.tzachar@gmail.com curses_menu_items[selected_index]); 1037*692d97c3Snir.tzachar@gmail.com } else { 1038*692d97c3Snir.tzachar@gmail.com toprow = max(selected_index-maxy/2, 0); 1039*692d97c3Snir.tzachar@gmail.com if (toprow >= item_count(curses_menu)-maxy) 1040*692d97c3Snir.tzachar@gmail.com toprow = item_count(curses_menu)-mwin_max_lines; 1041*692d97c3Snir.tzachar@gmail.com set_top_row(curses_menu, toprow); 1042*692d97c3Snir.tzachar@gmail.com set_current_item(curses_menu, 1043*692d97c3Snir.tzachar@gmail.com curses_menu_items[selected_index]); 1044*692d97c3Snir.tzachar@gmail.com } 1045*692d97c3Snir.tzachar@gmail.com *last_top_row = toprow; 1046*692d97c3Snir.tzachar@gmail.com post_menu(curses_menu); 1047*692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1048*692d97c3Snir.tzachar@gmail.com } 1049*692d97c3Snir.tzachar@gmail.com 1050*692d97c3Snir.tzachar@gmail.com /* this function assumes reset_menu has been called before */ 1051*692d97c3Snir.tzachar@gmail.com static void show_menu(const char *prompt, const char *instructions, 1052*692d97c3Snir.tzachar@gmail.com int selected_index, int *last_top_row) 1053*692d97c3Snir.tzachar@gmail.com { 1054*692d97c3Snir.tzachar@gmail.com int maxx, maxy; 1055*692d97c3Snir.tzachar@gmail.com WINDOW *menu_window; 1056*692d97c3Snir.tzachar@gmail.com 1057*692d97c3Snir.tzachar@gmail.com current_instructions = instructions; 1058*692d97c3Snir.tzachar@gmail.com 1059*692d97c3Snir.tzachar@gmail.com clear(); 1060*692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[NORMAL]); 1061*692d97c3Snir.tzachar@gmail.com print_in_middle(stdscr, 1, 0, COLS, 1062*692d97c3Snir.tzachar@gmail.com menu_backtitle, 1063*692d97c3Snir.tzachar@gmail.com attributes[MAIN_HEADING]); 1064*692d97c3Snir.tzachar@gmail.com 1065*692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[MAIN_MENU_BOX]); 1066*692d97c3Snir.tzachar@gmail.com box(main_window, 0, 0); 1067*692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[MAIN_MENU_HEADING]); 1068*692d97c3Snir.tzachar@gmail.com mvwprintw(main_window, 0, 3, " %s ", prompt); 1069*692d97c3Snir.tzachar@gmail.com wattrset(main_window, attributes[NORMAL]); 1070*692d97c3Snir.tzachar@gmail.com 1071*692d97c3Snir.tzachar@gmail.com set_menu_items(curses_menu, curses_menu_items); 1072*692d97c3Snir.tzachar@gmail.com 1073*692d97c3Snir.tzachar@gmail.com /* position the menu at the middle of the screen */ 1074*692d97c3Snir.tzachar@gmail.com scale_menu(curses_menu, &maxy, &maxx); 1075*692d97c3Snir.tzachar@gmail.com maxx = min(maxx, mwin_max_cols); 1076*692d97c3Snir.tzachar@gmail.com maxy = mwin_max_lines-1; 1077*692d97c3Snir.tzachar@gmail.com menu_window = derwin(main_window, 1078*692d97c3Snir.tzachar@gmail.com maxy, 1079*692d97c3Snir.tzachar@gmail.com maxx, 1080*692d97c3Snir.tzachar@gmail.com 2, 1081*692d97c3Snir.tzachar@gmail.com (mwin_max_cols-maxx)/2); 1082*692d97c3Snir.tzachar@gmail.com keypad(menu_window, TRUE); 1083*692d97c3Snir.tzachar@gmail.com set_menu_win(curses_menu, menu_window); 1084*692d97c3Snir.tzachar@gmail.com set_menu_sub(curses_menu, menu_window); 1085*692d97c3Snir.tzachar@gmail.com 1086*692d97c3Snir.tzachar@gmail.com /* must reassert this after changing items, otherwise returns to a 1087*692d97c3Snir.tzachar@gmail.com * default of 16 1088*692d97c3Snir.tzachar@gmail.com */ 1089*692d97c3Snir.tzachar@gmail.com set_menu_format(curses_menu, maxy, 1); 1090*692d97c3Snir.tzachar@gmail.com center_item(selected_index, last_top_row); 1091*692d97c3Snir.tzachar@gmail.com set_menu_format(curses_menu, maxy, 1); 1092*692d97c3Snir.tzachar@gmail.com 1093*692d97c3Snir.tzachar@gmail.com print_function_line(); 1094*692d97c3Snir.tzachar@gmail.com 1095*692d97c3Snir.tzachar@gmail.com /* Post the menu */ 1096*692d97c3Snir.tzachar@gmail.com post_menu(curses_menu); 1097*692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1098*692d97c3Snir.tzachar@gmail.com } 1099*692d97c3Snir.tzachar@gmail.com 1100*692d97c3Snir.tzachar@gmail.com 1101*692d97c3Snir.tzachar@gmail.com static void conf(struct menu *menu) 1102*692d97c3Snir.tzachar@gmail.com { 1103*692d97c3Snir.tzachar@gmail.com char pattern[256]; 1104*692d97c3Snir.tzachar@gmail.com struct menu *submenu = 0; 1105*692d97c3Snir.tzachar@gmail.com const char *prompt = menu_get_prompt(menu); 1106*692d97c3Snir.tzachar@gmail.com struct symbol *sym; 1107*692d97c3Snir.tzachar@gmail.com struct menu *active_menu = NULL; 1108*692d97c3Snir.tzachar@gmail.com int res; 1109*692d97c3Snir.tzachar@gmail.com int current_index = 0; 1110*692d97c3Snir.tzachar@gmail.com int last_top_row = 0; 1111*692d97c3Snir.tzachar@gmail.com 1112*692d97c3Snir.tzachar@gmail.com bzero(pattern, sizeof(pattern)); 1113*692d97c3Snir.tzachar@gmail.com 1114*692d97c3Snir.tzachar@gmail.com while (!global_exit) { 1115*692d97c3Snir.tzachar@gmail.com reset_menu(); 1116*692d97c3Snir.tzachar@gmail.com current_menu = menu; 1117*692d97c3Snir.tzachar@gmail.com build_conf(menu); 1118*692d97c3Snir.tzachar@gmail.com if (!child_count) 1119*692d97c3Snir.tzachar@gmail.com break; 1120*692d97c3Snir.tzachar@gmail.com 1121*692d97c3Snir.tzachar@gmail.com show_menu(prompt ? _(prompt) : _("Main Menu"), 1122*692d97c3Snir.tzachar@gmail.com _(menu_instructions), 1123*692d97c3Snir.tzachar@gmail.com current_index, &last_top_row); 1124*692d97c3Snir.tzachar@gmail.com keypad((menu_win(curses_menu)), TRUE); 1125*692d97c3Snir.tzachar@gmail.com while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { 1126*692d97c3Snir.tzachar@gmail.com if (process_special_keys(&res, 1127*692d97c3Snir.tzachar@gmail.com (struct menu *) item_data())) 1128*692d97c3Snir.tzachar@gmail.com break; 1129*692d97c3Snir.tzachar@gmail.com switch (res) { 1130*692d97c3Snir.tzachar@gmail.com case KEY_DOWN: 1131*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_DOWN_ITEM); 1132*692d97c3Snir.tzachar@gmail.com break; 1133*692d97c3Snir.tzachar@gmail.com case KEY_UP: 1134*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_UP_ITEM); 1135*692d97c3Snir.tzachar@gmail.com break; 1136*692d97c3Snir.tzachar@gmail.com case KEY_NPAGE: 1137*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_SCR_DPAGE); 1138*692d97c3Snir.tzachar@gmail.com break; 1139*692d97c3Snir.tzachar@gmail.com case KEY_PPAGE: 1140*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_SCR_UPAGE); 1141*692d97c3Snir.tzachar@gmail.com break; 1142*692d97c3Snir.tzachar@gmail.com case KEY_HOME: 1143*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_FIRST_ITEM); 1144*692d97c3Snir.tzachar@gmail.com break; 1145*692d97c3Snir.tzachar@gmail.com case KEY_END: 1146*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_LAST_ITEM); 1147*692d97c3Snir.tzachar@gmail.com break; 1148*692d97c3Snir.tzachar@gmail.com case 'h': 1149*692d97c3Snir.tzachar@gmail.com case '?': 1150*692d97c3Snir.tzachar@gmail.com show_help((struct menu *) item_data()); 1151*692d97c3Snir.tzachar@gmail.com break; 1152*692d97c3Snir.tzachar@gmail.com } 1153*692d97c3Snir.tzachar@gmail.com if (res == 10 || res == 27 || 1154*692d97c3Snir.tzachar@gmail.com res == 32 || res == 'n' || res == 'y' || 1155*692d97c3Snir.tzachar@gmail.com res == KEY_LEFT || res == KEY_RIGHT || 1156*692d97c3Snir.tzachar@gmail.com res == 'm' || res == '/') 1157*692d97c3Snir.tzachar@gmail.com break; 1158*692d97c3Snir.tzachar@gmail.com else if (canbhot(res)) { 1159*692d97c3Snir.tzachar@gmail.com /* check for hot keys: */ 1160*692d97c3Snir.tzachar@gmail.com int tmp = get_next_hot(res); 1161*692d97c3Snir.tzachar@gmail.com if (tmp != -1) 1162*692d97c3Snir.tzachar@gmail.com center_item(tmp, &last_top_row); 1163*692d97c3Snir.tzachar@gmail.com } 1164*692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1165*692d97c3Snir.tzachar@gmail.com } 1166*692d97c3Snir.tzachar@gmail.com 1167*692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1168*692d97c3Snir.tzachar@gmail.com /* if ESC or left*/ 1169*692d97c3Snir.tzachar@gmail.com if (res == 27 || (menu != &rootmenu && res == KEY_LEFT)) 1170*692d97c3Snir.tzachar@gmail.com break; 1171*692d97c3Snir.tzachar@gmail.com 1172*692d97c3Snir.tzachar@gmail.com /* remember location in the menu */ 1173*692d97c3Snir.tzachar@gmail.com last_top_row = top_row(curses_menu); 1174*692d97c3Snir.tzachar@gmail.com current_index = curses_item_index(); 1175*692d97c3Snir.tzachar@gmail.com 1176*692d97c3Snir.tzachar@gmail.com if (!item_tag()) 1177*692d97c3Snir.tzachar@gmail.com continue; 1178*692d97c3Snir.tzachar@gmail.com 1179*692d97c3Snir.tzachar@gmail.com submenu = (struct menu *) item_data(); 1180*692d97c3Snir.tzachar@gmail.com active_menu = (struct menu *)item_data(); 1181*692d97c3Snir.tzachar@gmail.com if (!submenu || !menu_is_visible(submenu)) 1182*692d97c3Snir.tzachar@gmail.com continue; 1183*692d97c3Snir.tzachar@gmail.com if (submenu) 1184*692d97c3Snir.tzachar@gmail.com sym = submenu->sym; 1185*692d97c3Snir.tzachar@gmail.com else 1186*692d97c3Snir.tzachar@gmail.com sym = NULL; 1187*692d97c3Snir.tzachar@gmail.com 1188*692d97c3Snir.tzachar@gmail.com switch (res) { 1189*692d97c3Snir.tzachar@gmail.com case ' ': 1190*692d97c3Snir.tzachar@gmail.com if (item_is_tag('t')) 1191*692d97c3Snir.tzachar@gmail.com sym_toggle_tristate_value(sym); 1192*692d97c3Snir.tzachar@gmail.com else if (item_is_tag('m')) 1193*692d97c3Snir.tzachar@gmail.com conf(submenu); 1194*692d97c3Snir.tzachar@gmail.com break; 1195*692d97c3Snir.tzachar@gmail.com case KEY_RIGHT: 1196*692d97c3Snir.tzachar@gmail.com case 10: /* ENTER WAS PRESSED */ 1197*692d97c3Snir.tzachar@gmail.com switch (item_tag()) { 1198*692d97c3Snir.tzachar@gmail.com case 'm': 1199*692d97c3Snir.tzachar@gmail.com if (single_menu_mode) 1200*692d97c3Snir.tzachar@gmail.com submenu->data = 1201*692d97c3Snir.tzachar@gmail.com (void *) (long) !submenu->data; 1202*692d97c3Snir.tzachar@gmail.com else 1203*692d97c3Snir.tzachar@gmail.com conf(submenu); 1204*692d97c3Snir.tzachar@gmail.com break; 1205*692d97c3Snir.tzachar@gmail.com case 't': 1206*692d97c3Snir.tzachar@gmail.com if (sym_is_choice(sym) && 1207*692d97c3Snir.tzachar@gmail.com sym_get_tristate_value(sym) == yes) 1208*692d97c3Snir.tzachar@gmail.com conf_choice(submenu); 1209*692d97c3Snir.tzachar@gmail.com else if (submenu->prompt && 1210*692d97c3Snir.tzachar@gmail.com submenu->prompt->type == P_MENU) 1211*692d97c3Snir.tzachar@gmail.com conf(submenu); 1212*692d97c3Snir.tzachar@gmail.com else if (res == 10) 1213*692d97c3Snir.tzachar@gmail.com sym_toggle_tristate_value(sym); 1214*692d97c3Snir.tzachar@gmail.com break; 1215*692d97c3Snir.tzachar@gmail.com case 's': 1216*692d97c3Snir.tzachar@gmail.com conf_string(submenu); 1217*692d97c3Snir.tzachar@gmail.com break; 1218*692d97c3Snir.tzachar@gmail.com } 1219*692d97c3Snir.tzachar@gmail.com break; 1220*692d97c3Snir.tzachar@gmail.com case 'y': 1221*692d97c3Snir.tzachar@gmail.com if (item_is_tag('t')) { 1222*692d97c3Snir.tzachar@gmail.com if (sym_set_tristate_value(sym, yes)) 1223*692d97c3Snir.tzachar@gmail.com break; 1224*692d97c3Snir.tzachar@gmail.com if (sym_set_tristate_value(sym, mod)) 1225*692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, setmod_text, 0); 1226*692d97c3Snir.tzachar@gmail.com } 1227*692d97c3Snir.tzachar@gmail.com break; 1228*692d97c3Snir.tzachar@gmail.com case 'n': 1229*692d97c3Snir.tzachar@gmail.com if (item_is_tag('t')) 1230*692d97c3Snir.tzachar@gmail.com sym_set_tristate_value(sym, no); 1231*692d97c3Snir.tzachar@gmail.com break; 1232*692d97c3Snir.tzachar@gmail.com case 'm': 1233*692d97c3Snir.tzachar@gmail.com if (item_is_tag('t')) 1234*692d97c3Snir.tzachar@gmail.com sym_set_tristate_value(sym, mod); 1235*692d97c3Snir.tzachar@gmail.com break; 1236*692d97c3Snir.tzachar@gmail.com case '/': 1237*692d97c3Snir.tzachar@gmail.com search_conf(); 1238*692d97c3Snir.tzachar@gmail.com break; 1239*692d97c3Snir.tzachar@gmail.com } 1240*692d97c3Snir.tzachar@gmail.com } 1241*692d97c3Snir.tzachar@gmail.com } 1242*692d97c3Snir.tzachar@gmail.com 1243*692d97c3Snir.tzachar@gmail.com static void show_help(struct menu *menu) 1244*692d97c3Snir.tzachar@gmail.com { 1245*692d97c3Snir.tzachar@gmail.com struct gstr help = str_new(); 1246*692d97c3Snir.tzachar@gmail.com 1247*692d97c3Snir.tzachar@gmail.com if (menu && menu->sym && menu_has_help(menu)) { 1248*692d97c3Snir.tzachar@gmail.com if (menu->sym->name) { 1249*692d97c3Snir.tzachar@gmail.com str_printf(&help, "CONFIG_%s:\n\n", menu->sym->name); 1250*692d97c3Snir.tzachar@gmail.com str_append(&help, _(menu_get_help(menu))); 1251*692d97c3Snir.tzachar@gmail.com str_append(&help, "\n"); 1252*692d97c3Snir.tzachar@gmail.com get_symbol_str(&help, menu->sym); 1253*692d97c3Snir.tzachar@gmail.com } 1254*692d97c3Snir.tzachar@gmail.com } else { 1255*692d97c3Snir.tzachar@gmail.com str_append(&help, nohelp_text); 1256*692d97c3Snir.tzachar@gmail.com } 1257*692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, _(menu_get_prompt(menu)), str_get(&help)); 1258*692d97c3Snir.tzachar@gmail.com str_free(&help); 1259*692d97c3Snir.tzachar@gmail.com } 1260*692d97c3Snir.tzachar@gmail.com 1261*692d97c3Snir.tzachar@gmail.com static void conf_choice(struct menu *menu) 1262*692d97c3Snir.tzachar@gmail.com { 1263*692d97c3Snir.tzachar@gmail.com const char *prompt = _(menu_get_prompt(menu)); 1264*692d97c3Snir.tzachar@gmail.com struct menu *child = 0; 1265*692d97c3Snir.tzachar@gmail.com struct symbol *active; 1266*692d97c3Snir.tzachar@gmail.com int selected_index = 0; 1267*692d97c3Snir.tzachar@gmail.com int last_top_row = 0; 1268*692d97c3Snir.tzachar@gmail.com int res, i = 0; 1269*692d97c3Snir.tzachar@gmail.com 1270*692d97c3Snir.tzachar@gmail.com active = sym_get_choice_value(menu->sym); 1271*692d97c3Snir.tzachar@gmail.com /* this is mostly duplicated from the conf() function. */ 1272*692d97c3Snir.tzachar@gmail.com while (!global_exit) { 1273*692d97c3Snir.tzachar@gmail.com reset_menu(); 1274*692d97c3Snir.tzachar@gmail.com 1275*692d97c3Snir.tzachar@gmail.com for (i = 0, child = menu->list; child; child = child->next) { 1276*692d97c3Snir.tzachar@gmail.com if (!show_all_items && !menu_is_visible(child)) 1277*692d97c3Snir.tzachar@gmail.com continue; 1278*692d97c3Snir.tzachar@gmail.com 1279*692d97c3Snir.tzachar@gmail.com if (child->sym == sym_get_choice_value(menu->sym)) 1280*692d97c3Snir.tzachar@gmail.com item_make(child, ':', "<X> %s", 1281*692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(child))); 1282*692d97c3Snir.tzachar@gmail.com else 1283*692d97c3Snir.tzachar@gmail.com item_make(child, ':', " %s", 1284*692d97c3Snir.tzachar@gmail.com _(menu_get_prompt(child))); 1285*692d97c3Snir.tzachar@gmail.com if (child->sym == active){ 1286*692d97c3Snir.tzachar@gmail.com last_top_row = top_row(curses_menu); 1287*692d97c3Snir.tzachar@gmail.com selected_index = i; 1288*692d97c3Snir.tzachar@gmail.com } 1289*692d97c3Snir.tzachar@gmail.com i++; 1290*692d97c3Snir.tzachar@gmail.com } 1291*692d97c3Snir.tzachar@gmail.com show_menu(prompt ? _(prompt) : _("Choice Menu"), 1292*692d97c3Snir.tzachar@gmail.com _(radiolist_instructions), 1293*692d97c3Snir.tzachar@gmail.com selected_index, 1294*692d97c3Snir.tzachar@gmail.com &last_top_row); 1295*692d97c3Snir.tzachar@gmail.com while (!global_exit && (res = wgetch(menu_win(curses_menu)))) { 1296*692d97c3Snir.tzachar@gmail.com if (process_special_keys( 1297*692d97c3Snir.tzachar@gmail.com &res, 1298*692d97c3Snir.tzachar@gmail.com (struct menu *) item_data())) 1299*692d97c3Snir.tzachar@gmail.com break; 1300*692d97c3Snir.tzachar@gmail.com switch (res) { 1301*692d97c3Snir.tzachar@gmail.com case KEY_DOWN: 1302*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_DOWN_ITEM); 1303*692d97c3Snir.tzachar@gmail.com break; 1304*692d97c3Snir.tzachar@gmail.com case KEY_UP: 1305*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_UP_ITEM); 1306*692d97c3Snir.tzachar@gmail.com break; 1307*692d97c3Snir.tzachar@gmail.com case KEY_NPAGE: 1308*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_SCR_DPAGE); 1309*692d97c3Snir.tzachar@gmail.com break; 1310*692d97c3Snir.tzachar@gmail.com case KEY_PPAGE: 1311*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_SCR_UPAGE); 1312*692d97c3Snir.tzachar@gmail.com break; 1313*692d97c3Snir.tzachar@gmail.com case KEY_HOME: 1314*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_FIRST_ITEM); 1315*692d97c3Snir.tzachar@gmail.com break; 1316*692d97c3Snir.tzachar@gmail.com case KEY_END: 1317*692d97c3Snir.tzachar@gmail.com menu_driver(curses_menu, REQ_LAST_ITEM); 1318*692d97c3Snir.tzachar@gmail.com break; 1319*692d97c3Snir.tzachar@gmail.com case 'h': 1320*692d97c3Snir.tzachar@gmail.com case '?': 1321*692d97c3Snir.tzachar@gmail.com show_help((struct menu *) item_data()); 1322*692d97c3Snir.tzachar@gmail.com break; 1323*692d97c3Snir.tzachar@gmail.com } 1324*692d97c3Snir.tzachar@gmail.com if (res == 10 || res == 27 || res == ' ' || 1325*692d97c3Snir.tzachar@gmail.com res == KEY_LEFT) 1326*692d97c3Snir.tzachar@gmail.com break; 1327*692d97c3Snir.tzachar@gmail.com else if (canbhot(res)) { 1328*692d97c3Snir.tzachar@gmail.com /* check for hot keys: */ 1329*692d97c3Snir.tzachar@gmail.com int tmp = get_next_hot(res); 1330*692d97c3Snir.tzachar@gmail.com if (tmp != -1) 1331*692d97c3Snir.tzachar@gmail.com center_item(tmp, &last_top_row); 1332*692d97c3Snir.tzachar@gmail.com } 1333*692d97c3Snir.tzachar@gmail.com refresh_all_windows(main_window); 1334*692d97c3Snir.tzachar@gmail.com } 1335*692d97c3Snir.tzachar@gmail.com /* if ESC or left */ 1336*692d97c3Snir.tzachar@gmail.com if (res == 27 || res == KEY_LEFT) 1337*692d97c3Snir.tzachar@gmail.com break; 1338*692d97c3Snir.tzachar@gmail.com 1339*692d97c3Snir.tzachar@gmail.com child = item_data(); 1340*692d97c3Snir.tzachar@gmail.com if (!child || !menu_is_visible(child)) 1341*692d97c3Snir.tzachar@gmail.com continue; 1342*692d97c3Snir.tzachar@gmail.com switch (res) { 1343*692d97c3Snir.tzachar@gmail.com case ' ': 1344*692d97c3Snir.tzachar@gmail.com case 10: 1345*692d97c3Snir.tzachar@gmail.com case KEY_RIGHT: 1346*692d97c3Snir.tzachar@gmail.com sym_set_tristate_value(child->sym, yes); 1347*692d97c3Snir.tzachar@gmail.com return; 1348*692d97c3Snir.tzachar@gmail.com case 'h': 1349*692d97c3Snir.tzachar@gmail.com case '?': 1350*692d97c3Snir.tzachar@gmail.com show_help(child); 1351*692d97c3Snir.tzachar@gmail.com active = child->sym; 1352*692d97c3Snir.tzachar@gmail.com break; 1353*692d97c3Snir.tzachar@gmail.com case KEY_EXIT: 1354*692d97c3Snir.tzachar@gmail.com return; 1355*692d97c3Snir.tzachar@gmail.com } 1356*692d97c3Snir.tzachar@gmail.com } 1357*692d97c3Snir.tzachar@gmail.com } 1358*692d97c3Snir.tzachar@gmail.com 1359*692d97c3Snir.tzachar@gmail.com static void conf_string(struct menu *menu) 1360*692d97c3Snir.tzachar@gmail.com { 1361*692d97c3Snir.tzachar@gmail.com const char *prompt = menu_get_prompt(menu); 1362*692d97c3Snir.tzachar@gmail.com char dialog_input_result[256]; 1363*692d97c3Snir.tzachar@gmail.com 1364*692d97c3Snir.tzachar@gmail.com while (1) { 1365*692d97c3Snir.tzachar@gmail.com int res; 1366*692d97c3Snir.tzachar@gmail.com const char *heading; 1367*692d97c3Snir.tzachar@gmail.com 1368*692d97c3Snir.tzachar@gmail.com switch (sym_get_type(menu->sym)) { 1369*692d97c3Snir.tzachar@gmail.com case S_INT: 1370*692d97c3Snir.tzachar@gmail.com heading = _(inputbox_instructions_int); 1371*692d97c3Snir.tzachar@gmail.com break; 1372*692d97c3Snir.tzachar@gmail.com case S_HEX: 1373*692d97c3Snir.tzachar@gmail.com heading = _(inputbox_instructions_hex); 1374*692d97c3Snir.tzachar@gmail.com break; 1375*692d97c3Snir.tzachar@gmail.com case S_STRING: 1376*692d97c3Snir.tzachar@gmail.com heading = _(inputbox_instructions_string); 1377*692d97c3Snir.tzachar@gmail.com break; 1378*692d97c3Snir.tzachar@gmail.com default: 1379*692d97c3Snir.tzachar@gmail.com heading = _("Internal nconf error!"); 1380*692d97c3Snir.tzachar@gmail.com } 1381*692d97c3Snir.tzachar@gmail.com res = dialog_inputbox(main_window, 1382*692d97c3Snir.tzachar@gmail.com prompt ? _(prompt) : _("Main Menu"), 1383*692d97c3Snir.tzachar@gmail.com heading, 1384*692d97c3Snir.tzachar@gmail.com sym_get_string_value(menu->sym), 1385*692d97c3Snir.tzachar@gmail.com dialog_input_result, 1386*692d97c3Snir.tzachar@gmail.com sizeof(dialog_input_result)); 1387*692d97c3Snir.tzachar@gmail.com switch (res) { 1388*692d97c3Snir.tzachar@gmail.com case 0: 1389*692d97c3Snir.tzachar@gmail.com if (sym_set_string_value(menu->sym, 1390*692d97c3Snir.tzachar@gmail.com dialog_input_result)) 1391*692d97c3Snir.tzachar@gmail.com return; 1392*692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, 1393*692d97c3Snir.tzachar@gmail.com _("You have made an invalid entry."), 0); 1394*692d97c3Snir.tzachar@gmail.com break; 1395*692d97c3Snir.tzachar@gmail.com case 1: 1396*692d97c3Snir.tzachar@gmail.com show_help(menu); 1397*692d97c3Snir.tzachar@gmail.com break; 1398*692d97c3Snir.tzachar@gmail.com case KEY_EXIT: 1399*692d97c3Snir.tzachar@gmail.com return; 1400*692d97c3Snir.tzachar@gmail.com } 1401*692d97c3Snir.tzachar@gmail.com } 1402*692d97c3Snir.tzachar@gmail.com } 1403*692d97c3Snir.tzachar@gmail.com 1404*692d97c3Snir.tzachar@gmail.com static void conf_load(void) 1405*692d97c3Snir.tzachar@gmail.com { 1406*692d97c3Snir.tzachar@gmail.com char dialog_input_result[256]; 1407*692d97c3Snir.tzachar@gmail.com while (1) { 1408*692d97c3Snir.tzachar@gmail.com int res; 1409*692d97c3Snir.tzachar@gmail.com res = dialog_inputbox(main_window, 1410*692d97c3Snir.tzachar@gmail.com NULL, load_config_text, 1411*692d97c3Snir.tzachar@gmail.com filename, 1412*692d97c3Snir.tzachar@gmail.com dialog_input_result, 1413*692d97c3Snir.tzachar@gmail.com sizeof(dialog_input_result)); 1414*692d97c3Snir.tzachar@gmail.com switch (res) { 1415*692d97c3Snir.tzachar@gmail.com case 0: 1416*692d97c3Snir.tzachar@gmail.com if (!dialog_input_result[0]) 1417*692d97c3Snir.tzachar@gmail.com return; 1418*692d97c3Snir.tzachar@gmail.com if (!conf_read(dialog_input_result)) { 1419*692d97c3Snir.tzachar@gmail.com set_config_filename(dialog_input_result); 1420*692d97c3Snir.tzachar@gmail.com sym_set_change_count(1); 1421*692d97c3Snir.tzachar@gmail.com return; 1422*692d97c3Snir.tzachar@gmail.com } 1423*692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, _("File does not exist!"), 0); 1424*692d97c3Snir.tzachar@gmail.com break; 1425*692d97c3Snir.tzachar@gmail.com case 1: 1426*692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 1427*692d97c3Snir.tzachar@gmail.com _("Load Alternate Configuration"), 1428*692d97c3Snir.tzachar@gmail.com load_config_help); 1429*692d97c3Snir.tzachar@gmail.com break; 1430*692d97c3Snir.tzachar@gmail.com case KEY_EXIT: 1431*692d97c3Snir.tzachar@gmail.com return; 1432*692d97c3Snir.tzachar@gmail.com } 1433*692d97c3Snir.tzachar@gmail.com } 1434*692d97c3Snir.tzachar@gmail.com } 1435*692d97c3Snir.tzachar@gmail.com 1436*692d97c3Snir.tzachar@gmail.com static void conf_save(void) 1437*692d97c3Snir.tzachar@gmail.com { 1438*692d97c3Snir.tzachar@gmail.com char dialog_input_result[256]; 1439*692d97c3Snir.tzachar@gmail.com while (1) { 1440*692d97c3Snir.tzachar@gmail.com int res; 1441*692d97c3Snir.tzachar@gmail.com res = dialog_inputbox(main_window, 1442*692d97c3Snir.tzachar@gmail.com NULL, save_config_text, 1443*692d97c3Snir.tzachar@gmail.com filename, 1444*692d97c3Snir.tzachar@gmail.com dialog_input_result, 1445*692d97c3Snir.tzachar@gmail.com sizeof(dialog_input_result)); 1446*692d97c3Snir.tzachar@gmail.com switch (res) { 1447*692d97c3Snir.tzachar@gmail.com case 0: 1448*692d97c3Snir.tzachar@gmail.com if (!dialog_input_result[0]) 1449*692d97c3Snir.tzachar@gmail.com return; 1450*692d97c3Snir.tzachar@gmail.com supress_stdout(0); 1451*692d97c3Snir.tzachar@gmail.com res = conf_write(dialog_input_result); 1452*692d97c3Snir.tzachar@gmail.com supress_stdout(1); 1453*692d97c3Snir.tzachar@gmail.com if (!res) { 1454*692d97c3Snir.tzachar@gmail.com char buf[1024]; 1455*692d97c3Snir.tzachar@gmail.com sprintf(buf, "%s %s", 1456*692d97c3Snir.tzachar@gmail.com _("configuration file saved to: "), 1457*692d97c3Snir.tzachar@gmail.com dialog_input_result); 1458*692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, 1459*692d97c3Snir.tzachar@gmail.com buf, 1, "<OK>"); 1460*692d97c3Snir.tzachar@gmail.com set_config_filename(dialog_input_result); 1461*692d97c3Snir.tzachar@gmail.com return; 1462*692d97c3Snir.tzachar@gmail.com } 1463*692d97c3Snir.tzachar@gmail.com btn_dialog(main_window, _("Can't create file! " 1464*692d97c3Snir.tzachar@gmail.com "Probably a nonexistent directory."), 1465*692d97c3Snir.tzachar@gmail.com 1, "<OK>"); 1466*692d97c3Snir.tzachar@gmail.com break; 1467*692d97c3Snir.tzachar@gmail.com case 1: 1468*692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 1469*692d97c3Snir.tzachar@gmail.com _("Save Alternate Configuration"), 1470*692d97c3Snir.tzachar@gmail.com save_config_help); 1471*692d97c3Snir.tzachar@gmail.com break; 1472*692d97c3Snir.tzachar@gmail.com case KEY_EXIT: 1473*692d97c3Snir.tzachar@gmail.com return; 1474*692d97c3Snir.tzachar@gmail.com } 1475*692d97c3Snir.tzachar@gmail.com } 1476*692d97c3Snir.tzachar@gmail.com } 1477*692d97c3Snir.tzachar@gmail.com 1478*692d97c3Snir.tzachar@gmail.com void setup_windows(void) 1479*692d97c3Snir.tzachar@gmail.com { 1480*692d97c3Snir.tzachar@gmail.com if (main_window != NULL) 1481*692d97c3Snir.tzachar@gmail.com delwin(main_window); 1482*692d97c3Snir.tzachar@gmail.com 1483*692d97c3Snir.tzachar@gmail.com /* set up the menu and menu window */ 1484*692d97c3Snir.tzachar@gmail.com main_window = newwin(LINES-2, COLS-2, 2, 1); 1485*692d97c3Snir.tzachar@gmail.com keypad(main_window, TRUE); 1486*692d97c3Snir.tzachar@gmail.com mwin_max_lines = LINES-6; 1487*692d97c3Snir.tzachar@gmail.com mwin_max_cols = COLS-6; 1488*692d97c3Snir.tzachar@gmail.com 1489*692d97c3Snir.tzachar@gmail.com /* panels order is from bottom to top */ 1490*692d97c3Snir.tzachar@gmail.com new_panel(main_window); 1491*692d97c3Snir.tzachar@gmail.com } 1492*692d97c3Snir.tzachar@gmail.com 1493*692d97c3Snir.tzachar@gmail.com int main(int ac, char **av) 1494*692d97c3Snir.tzachar@gmail.com { 1495*692d97c3Snir.tzachar@gmail.com char *mode; 1496*692d97c3Snir.tzachar@gmail.com 1497*692d97c3Snir.tzachar@gmail.com setlocale(LC_ALL, ""); 1498*692d97c3Snir.tzachar@gmail.com bindtextdomain(PACKAGE, LOCALEDIR); 1499*692d97c3Snir.tzachar@gmail.com textdomain(PACKAGE); 1500*692d97c3Snir.tzachar@gmail.com 1501*692d97c3Snir.tzachar@gmail.com conf_parse(av[1]); 1502*692d97c3Snir.tzachar@gmail.com conf_read(NULL); 1503*692d97c3Snir.tzachar@gmail.com 1504*692d97c3Snir.tzachar@gmail.com mode = getenv("NCONFIG_MODE"); 1505*692d97c3Snir.tzachar@gmail.com if (mode) { 1506*692d97c3Snir.tzachar@gmail.com if (!strcasecmp(mode, "single_menu")) 1507*692d97c3Snir.tzachar@gmail.com single_menu_mode = 1; 1508*692d97c3Snir.tzachar@gmail.com } 1509*692d97c3Snir.tzachar@gmail.com 1510*692d97c3Snir.tzachar@gmail.com /* Initialize curses */ 1511*692d97c3Snir.tzachar@gmail.com initscr(); 1512*692d97c3Snir.tzachar@gmail.com /* set color theme */ 1513*692d97c3Snir.tzachar@gmail.com set_colors(); 1514*692d97c3Snir.tzachar@gmail.com 1515*692d97c3Snir.tzachar@gmail.com cbreak(); 1516*692d97c3Snir.tzachar@gmail.com noecho(); 1517*692d97c3Snir.tzachar@gmail.com keypad(stdscr, TRUE); 1518*692d97c3Snir.tzachar@gmail.com curs_set(0); 1519*692d97c3Snir.tzachar@gmail.com 1520*692d97c3Snir.tzachar@gmail.com if (COLS < 75 || LINES < 20) { 1521*692d97c3Snir.tzachar@gmail.com endwin(); 1522*692d97c3Snir.tzachar@gmail.com printf("Your terminal should have at " 1523*692d97c3Snir.tzachar@gmail.com "least 20 lines and 75 columns\n"); 1524*692d97c3Snir.tzachar@gmail.com return 1; 1525*692d97c3Snir.tzachar@gmail.com } 1526*692d97c3Snir.tzachar@gmail.com 1527*692d97c3Snir.tzachar@gmail.com notimeout(stdscr, FALSE); 1528*692d97c3Snir.tzachar@gmail.com ESCDELAY = 1; 1529*692d97c3Snir.tzachar@gmail.com 1530*692d97c3Snir.tzachar@gmail.com /* set btns menu */ 1531*692d97c3Snir.tzachar@gmail.com curses_menu = new_menu(curses_menu_items); 1532*692d97c3Snir.tzachar@gmail.com menu_opts_off(curses_menu, O_SHOWDESC); 1533*692d97c3Snir.tzachar@gmail.com menu_opts_off(curses_menu, O_SHOWMATCH); 1534*692d97c3Snir.tzachar@gmail.com menu_opts_on(curses_menu, O_ONEVALUE); 1535*692d97c3Snir.tzachar@gmail.com menu_opts_on(curses_menu, O_NONCYCLIC); 1536*692d97c3Snir.tzachar@gmail.com set_menu_mark(curses_menu, " "); 1537*692d97c3Snir.tzachar@gmail.com set_menu_fore(curses_menu, attributes[MAIN_MENU_FORE]); 1538*692d97c3Snir.tzachar@gmail.com set_menu_back(curses_menu, attributes[MAIN_MENU_BACK]); 1539*692d97c3Snir.tzachar@gmail.com set_menu_grey(curses_menu, attributes[MAIN_MENU_GREY]); 1540*692d97c3Snir.tzachar@gmail.com 1541*692d97c3Snir.tzachar@gmail.com set_config_filename(conf_get_configname()); 1542*692d97c3Snir.tzachar@gmail.com setup_windows(); 1543*692d97c3Snir.tzachar@gmail.com 1544*692d97c3Snir.tzachar@gmail.com /* check for KEY_FUNC(1) */ 1545*692d97c3Snir.tzachar@gmail.com if (has_key(KEY_F(1)) == FALSE) { 1546*692d97c3Snir.tzachar@gmail.com show_scroll_win(main_window, 1547*692d97c3Snir.tzachar@gmail.com _("Instructions"), 1548*692d97c3Snir.tzachar@gmail.com _(menu_no_f_instructions)); 1549*692d97c3Snir.tzachar@gmail.com } 1550*692d97c3Snir.tzachar@gmail.com 1551*692d97c3Snir.tzachar@gmail.com 1552*692d97c3Snir.tzachar@gmail.com 1553*692d97c3Snir.tzachar@gmail.com /* do the work */ 1554*692d97c3Snir.tzachar@gmail.com while (!global_exit) { 1555*692d97c3Snir.tzachar@gmail.com conf(&rootmenu); 1556*692d97c3Snir.tzachar@gmail.com if (!global_exit && do_exit() == 0) 1557*692d97c3Snir.tzachar@gmail.com break; 1558*692d97c3Snir.tzachar@gmail.com } 1559*692d97c3Snir.tzachar@gmail.com /* ok, we are done */ 1560*692d97c3Snir.tzachar@gmail.com unpost_menu(curses_menu); 1561*692d97c3Snir.tzachar@gmail.com free_menu(curses_menu); 1562*692d97c3Snir.tzachar@gmail.com delwin(main_window); 1563*692d97c3Snir.tzachar@gmail.com clear(); 1564*692d97c3Snir.tzachar@gmail.com refresh(); 1565*692d97c3Snir.tzachar@gmail.com endwin(); 1566*692d97c3Snir.tzachar@gmail.com return 0; 1567*692d97c3Snir.tzachar@gmail.com } 1568*692d97c3Snir.tzachar@gmail.com 1569