2001-06-08 11:20:07 +04:00
/*
* gui / control . cc
2001-06-18 18:11:55 +04:00
* $ Id : control . cc , v 1.22 2001 - 06 - 18 14 : 11 : 55 bdenney Exp $
2001-06-08 11:20:07 +04:00
*
* This is code for a text - mode control panel . Note that this file
* does NOT include bochs . h . Instead , it does all of its contact with
* the simulator through an object called SIM , defined in siminterface . cc
* and siminterface . h . This separation adds an extra layer of method
* calls before any work can be done , but the benefit is that the compiler
* enforces the rules . I can guarantee that control . cc doesn ' t call any
* I / O device objects directly , for example , because the bx_devices symbol
* isn ' t even defined in this context .
*
2001-06-08 00:42:00 +04:00
2001-06-08 11:20:07 +04:00
Musings by Bryce :
2001-06-08 00:42:00 +04:00
2001-06-08 11:20:07 +04:00
Now that there are some capabilities here , start moving toward the desired
model of separation of gui and simulator . Design a method - call interface
between objects which could later be turned into a network protocol .
2001-06-08 00:42:00 +04:00
2001-06-08 11:20:07 +04:00
Most messages go from the control panel to bochs , with bochs sending a response
back . Examples : turn on debug event logging for the PIC , or set IPS to
1.5 million . Others kinds of messages go from bochs to the control panel .
Example : errors such as " disk image not found " , status information such as the
current CPU state .
But because of the nature of a control panel , most information flows from
the control panel to Bochs . I think we can take advantage of this to
simplify the protocol . The GUI can ask bochs to do things and get a
response back . Bochs can tell the GUI something , but will not get a
response back .
The control panel should exist before the Bochs simulator starts , so that the
user can get their settings right before booting up a simulator . Once
bochs has begun , some settings can no longer be changed , such as how much
memory there is . Others can be changed at any time , like the value of IPS
or the name of the floppy disk images . If you had the bochs simulator
as a shared library , the GUI could let you choose which version of the
simulator library to load ( one with debugging or SMP support or not ,
for example ) .
When the control panel connects to Bochs , each needs to learn what the other
can do . Some versions of Bochs will have cdrom support , others will not .
Design a simple and general way for the two parties to describe what they
can do , so that the GUI can grey - out some menu choices , and Bochs knows
what the GUI can handle . I think Bochs should provide a list of
capabilities in something like the form of :
typedef struct { Bit16u id ; String name ; } bx_capability_t ;
Only the negotiation of capabilities uses the string name , and for everything
else the 16 - bit id is used ( use htons ( ) if sending over network ) . Each
capability is like a function that can be called on the remote object ,
and each function needs an input list and a return value .
Hmm . . . . This sounds like reinventing function calls . Next I ' m going to
2001-06-10 00:01:12 +04:00
say we need to implement prototypes and type checking . Why not just
write a compiler !
2001-06-08 11:20:07 +04:00
*/
2001-06-11 10:48:37 +04:00
# include "config.h"
# if BX_USE_CONTROL_PANEL
2001-06-08 11:20:07 +04:00
extern " C " {
# include <stdio.h>
# include <ctype.h>
# include <string.h>
2001-06-10 00:01:12 +04:00
# include <assert.h>
2001-06-08 00:42:00 +04:00
}
2001-06-10 07:53:43 +04:00
# include "osdep.h"
2001-06-10 00:01:12 +04:00
# include "control.h"
2001-06-08 11:20:07 +04:00
# include "siminterface.h"
2001-06-11 10:35:18 +04:00
# define CPANEL_PATH_LEN 512
2001-06-08 00:42:00 +04:00
2001-06-10 00:01:12 +04:00
/* functions for changing particular options */
2001-06-11 18:03:35 +04:00
void bx_control_panel_init ( ) ;
2001-06-10 00:01:12 +04:00
void bx_edit_floppy ( int drive ) ;
void bx_edit_hard_disk ( int drive ) ;
void bx_edit_cdrom ( ) ;
void bx_newhd_support ( ) ;
2001-06-10 01:29:07 +04:00
void bx_private_colormap ( ) ;
2001-06-10 00:01:12 +04:00
void bx_boot_from ( ) ;
2001-06-08 11:20:07 +04:00
void bx_ips_change ( ) ;
2001-06-10 00:01:12 +04:00
int bx_read_rc ( char * rc ) ;
2001-06-11 10:35:18 +04:00
int bx_write_rc ( char * rc ) ;
2001-06-10 00:01:12 +04:00
void bx_log_file ( ) ;
void bx_log_options ( int individual ) ;
void bx_vga_update_interval ( ) ;
void bx_mouse_enable ( ) ;
2001-06-08 00:42:00 +04:00
/******************************************************************/
/* lots of code stolen from bximage.c */
/* remove leading spaces, newline junk at end. returns pointer to
cleaned string , which is between s0 and the null */
char *
clean_string ( char * s0 )
{
char * s = s0 ;
char * ptr ;
/* find first nonblank */
while ( isspace ( * s ) )
s + + ;
/* truncate string at first non-alphanumeric */
ptr = s ;
while ( isprint ( * ptr ) )
ptr + + ;
* ptr = 0 ;
return s ;
}
/* returns 0 on success, -1 on failure. The value goes into out. */
int
2001-06-18 18:11:55 +04:00
ask_uint ( char * prompt , Bit32u min , Bit32u max , Bit32u the_default , Bit32u * out , int base )
{
int n = max + 1 ;
char buffer [ 1024 ] ;
char * clean ;
int illegal ;
assert ( base = = 10 | | base = = 16 ) ;
while ( 1 ) {
printf ( prompt , the_default ) ;
if ( ! fgets ( buffer , sizeof ( buffer ) , stdin ) )
return - 1 ;
clean = clean_string ( buffer ) ;
if ( strlen ( clean ) < 1 ) {
// empty line, use the default
* out = the_default ;
return 0 ;
}
char * format = ( base = = 10 ) ? " %d " : " %x " ;
illegal = ( 1 ! = sscanf ( buffer , format , & n ) ) ;
if ( illegal | | n < min | | n > max ) {
printf ( " Your choice (%s) was not an integer between %u and %u. \n \n " ,
clean , min , max ) ;
} else {
// choice is okay
* out = n ;
return 0 ;
}
}
}
// identical to ask_uint, but uses signed comparisons
int
ask_int ( char * prompt , Bit32s min , Bit32s max , Bit32s the_default , Bit32s * out )
2001-06-08 00:42:00 +04:00
{
int n = max + 1 ;
char buffer [ 1024 ] ;
char * clean ;
int illegal ;
while ( 1 ) {
2001-06-10 00:01:12 +04:00
printf ( prompt , the_default ) ;
2001-06-08 00:42:00 +04:00
if ( ! fgets ( buffer , sizeof ( buffer ) , stdin ) )
return - 1 ;
clean = clean_string ( buffer ) ;
if ( strlen ( clean ) < 1 ) {
// empty line, use the default
* out = the_default ;
return 0 ;
}
illegal = ( 1 ! = sscanf ( buffer , " %d " , & n ) ) ;
if ( illegal | | n < min | | n > max ) {
printf ( " Your choice (%s) was not an integer between %d and %d. \n \n " ,
clean , min , max ) ;
} else {
// choice is okay
* out = n ;
return 0 ;
}
}
}
int
ask_menu ( char * prompt , int n_choices , char * choice [ ] , int the_default , int * out )
{
char buffer [ 1024 ] ;
char * clean ;
int i ;
* out = - 1 ;
while ( 1 ) {
2001-06-10 00:01:12 +04:00
printf ( prompt , choice [ the_default ] ) ;
2001-06-08 00:42:00 +04:00
if ( ! fgets ( buffer , sizeof ( buffer ) , stdin ) )
return - 1 ;
clean = clean_string ( buffer ) ;
if ( strlen ( clean ) < 1 ) {
// empty line, use the default
* out = the_default ;
return 0 ;
}
for ( i = 0 ; i < n_choices ; i + + ) {
if ( ! strcmp ( choice [ i ] , clean ) ) {
// matched, return the choice number
* out = i ;
return 0 ;
}
}
printf ( " Your choice (%s) did not match any of the choices: \n " , clean ) ;
for ( i = 0 ; i < n_choices ; i + + ) {
if ( i > 0 ) printf ( " , " ) ;
printf ( " %s " , choice [ i ] ) ;
}
printf ( " \n " ) ;
}
}
int
2001-06-18 18:11:55 +04:00
ask_yn ( char * prompt , Bit32u the_default , Bit32u * out )
2001-06-08 00:42:00 +04:00
{
char buffer [ 16 ] ;
char * clean ;
2001-06-18 18:11:55 +04:00
* out = 1 < < 31 ;
2001-06-08 00:42:00 +04:00
while ( 1 ) {
2001-06-10 00:01:12 +04:00
// if there's a %s field, substitute in the default yes/no.
printf ( prompt , the_default ? " yes " : " no " ) ;
2001-06-08 00:42:00 +04:00
if ( ! fgets ( buffer , sizeof ( buffer ) , stdin ) )
return - 1 ;
clean = clean_string ( buffer ) ;
if ( strlen ( clean ) < 1 ) {
// empty line, use the default
* out = the_default ;
return 0 ;
}
switch ( tolower ( clean [ 0 ] ) ) {
case ' y ' : * out = 1 ; return 0 ;
case ' n ' : * out = 0 ; return 0 ;
}
printf ( " Please type either yes or no. \n " ) ;
}
}
int
ask_string ( char * prompt , char * the_default , char * out )
{
char buffer [ 1024 ] ;
char * clean ;
out [ 0 ] = 0 ;
2001-06-10 00:01:12 +04:00
printf ( prompt , the_default ) ;
2001-06-08 00:42:00 +04:00
if ( ! fgets ( buffer , sizeof ( buffer ) , stdin ) )
return - 1 ;
clean = clean_string ( buffer ) ;
if ( strlen ( clean ) < 1 ) {
// empty line, use the default
strcpy ( out , the_default ) ;
return 0 ;
}
strcpy ( out , clean ) ;
return 0 ;
}
/******************************************************************/
2001-06-10 00:01:12 +04:00
static char * ask_about_control_panel =
2001-06-12 01:03:05 +04:00
" \n "
" This version of Bochs has a prototype configuration interface. Would \n "
" you like to try it? \n "
" \n "
" If you choose yes, you can use a menu to choose configuration options. \n "
" If you choose no, Bochs will read a bochsrc file and run as usual. \n "
" Type yes or no: [yes] " ;
2001-06-10 00:01:12 +04:00
static char * startup_menu_prompt =
2001-06-12 01:03:05 +04:00
" ------------------ \n "
" Bochs Startup Menu \n "
" ------------------ \n "
" 1. Read options from... \n "
" 2. Edit options \n "
" 3. Save options to... \n "
" 4. Begin simulation \n "
" 5. Quit now \n "
" \n "
" Please choose one: [%d] " ;
2001-06-10 00:01:12 +04:00
static char * startup_options_prompt =
2001-06-12 01:03:05 +04:00
" ------------------ \n "
" Bochs Options Menu \n "
" ------------------ \n "
" 0. Return to previous menu \n "
" 1. Log file: %s \n "
" 2. Log options for all devices \n "
" 3. Log options for individual devices \n "
2001-06-13 19:52:04 +04:00
" 4. Memory options \n "
2001-06-12 01:03:05 +04:00
" 5. Interface options \n "
" 6. Disk options \n "
" 7. Sound options \n "
" 8. Other options \n "
" \n "
" Please choose one: [0] " ;
2001-06-10 00:01:12 +04:00
2001-06-13 12:14:49 +04:00
static char * startup_mem_options_prompt =
" -------------------- \n "
" Bochs Memory Options \n "
" -------------------- \n "
2001-06-12 01:03:05 +04:00
" 0. Return to previous menu \n "
" 1. Memory in Megabytes: %d \n "
" 2. VGA ROM image: %s \n "
" 3. ROM image: %s \n "
" 4. ROM address: 0x%05x \n "
" \n "
" Please choose one: [0] " ;
2001-06-10 00:01:12 +04:00
static char * startup_interface_options =
2001-06-12 01:03:05 +04:00
" ------------------ \n "
" Bochs Interface Options \n "
" ------------------ \n "
" 0. Return to previous menu \n "
" 1. VGA Update Interval: %d \n "
" 2. Mouse: %s \n "
2001-06-13 12:14:49 +04:00
" 3. Emulated instructions per second (IPS): %u \n "
2001-06-12 01:03:05 +04:00
" 4. Private Colormap: %s \n "
" \n "
" Please choose one: [0] " ;
2001-06-10 00:01:12 +04:00
static char * startup_disk_options_prompt =
2001-06-12 01:03:05 +04:00
" ------------------ \n "
" Bochs Disk Options \n "
" ------------------ \n "
" 0. Return to previous menu \n "
" 1. Floppy disk 0: %s \n "
" 2. Floppy disk 1: %s \n "
" 3. Hard disk 0: %s \n "
" 4. Hard disk 1: %s \n "
" 5. CDROM: %s \n "
" 6. New Hard Drive Support: %s \n "
" 7. Boot from: %s \n "
" %s \n "
" Please choose one: [0] " ;
2001-06-10 00:01:12 +04:00
static char * startup_sound_options_prompt =
2001-06-12 01:03:05 +04:00
" ------------------ \n "
" Bochs Sound Options \n "
" ------------------ \n "
" 0. Return to previous menu \n "
" 1. Sound Blaster 16: disabled \n "
" 2. MIDI mode: 1, \n "
" 3. MIDI output file: /dev/midi00 \n "
" 4. Wave mode: 1 \n "
" 5. Wave output file: dev/dsp \n "
" 6. SB16 log level: 2 \n "
" 7. SB16 log file: sb16.log \n "
" 8. DMA Timer: 600000 \n "
" \n "
" Please choose one: [0] " ;
2001-06-10 00:01:12 +04:00
static char * startup_misc_options_prompt =
2001-06-12 01:03:05 +04:00
" --------------------------- \n "
" Bochs Miscellaneous Options \n "
" --------------------------- \n "
" 1. Keyboard Serial Delay: 250 \n "
" 2. Floppy command delay: 500 \n "
" To be added someday: magic_break, ne2k, load32bitOSImage,i440fxsupport,time0 "
" \n "
" Please choose one: [0] " ;
2001-06-08 00:42:00 +04:00
2001-06-10 00:01:12 +04:00
static char * runtime_menu_prompt =
2001-06-12 01:03:05 +04:00
" --------------------- \n "
" Bochs Runtime Options \n "
" --------------------- \n "
2001-06-13 12:14:49 +04:00
" 1. Floppy disk 0: %s \n "
" 2. Floppy disk 1: %s \n "
" 3. CDROM: %s \n "
" 4. Emulated instructions per second (IPS): %u \n "
" 5. Log options for all devices \n "
" 6. Log options for individual devices \n "
" 7. VGA Update Interval: %d \n "
" 8. Mouse: %s \n "
" 9. Instruction tracing: off (doesn't exist yet) \n "
" 10. Continue simulation \n "
" 11. Quit now \n "
2001-06-12 01:03:05 +04:00
" \n "
2001-06-13 17:31:53 +04:00
" Please choose one: [10] " ;
2001-06-10 00:01:12 +04:00
char * menu_prompt_list [ BX_CPANEL_N_MENUS ] = {
ask_about_control_panel ,
startup_menu_prompt ,
startup_options_prompt ,
2001-06-13 12:14:49 +04:00
startup_mem_options_prompt ,
2001-06-10 00:01:12 +04:00
startup_interface_options ,
startup_disk_options_prompt ,
startup_sound_options_prompt ,
startup_misc_options_prompt ,
runtime_menu_prompt
} ;
# define NOT_IMPLEMENTED(choice) \
fprintf ( stderr , " ERROR: choice %d not implemented \n " , choice ) ;
# define BAD_OPTION(menu,choice) \
do { fprintf ( stderr , " ERROR: control panel menu %d has no choice %d \n " , menu , choice ) ; \
assert ( 0 ) ; } while ( 0 )
char * fdsize_choices [ ] = { " 0.72 " , " 1.2 " , " 1.44 " , " 2.88 " } ;
int fdsize_n_choices = 4 ;
void build_disk_options_prompt ( char * format , char * buf , int size )
2001-06-08 00:42:00 +04:00
{
2001-06-10 00:01:12 +04:00
bx_floppy_options floppyop ;
bx_disk_options diskop ;
bx_cdrom_options cdromop ;
2001-06-10 01:12:16 +04:00
char buffer [ 7 ] [ 128 ] ;
2001-06-10 00:01:12 +04:00
for ( int i = 0 ; i < 2 ; i + + ) {
SIM - > get_floppy_options ( i , & floppyop ) ;
sprintf ( buffer [ i ] , " %s, size=%s, %s " , floppyop . path ,
SIM - > get_floppy_type_name ( floppyop . type ) ,
floppyop . initial_status ? " inserted " : " ejected " ) ;
if ( ! floppyop . path [ 0 ] ) strcpy ( buffer [ i ] , " none " ) ;
SIM - > get_disk_options ( i , & diskop ) ;
sprintf ( buffer [ 2 + i ] , " %s, %d cylinders, %d heads, %d sectors/track " ,
diskop . path , diskop . cylinders , diskop . heads , diskop . spt ) ;
2001-06-10 01:12:16 +04:00
if ( ! diskop . present ) strcpy ( buffer [ 2 + i ] , " none " ) ;
2001-06-08 00:42:00 +04:00
}
2001-06-10 00:01:12 +04:00
SIM - > get_cdrom_options ( 0 , & cdromop ) ;
sprintf ( buffer [ 4 ] , " %s, %spresent, %s " ,
cdromop . dev , cdromop . present ? " " : " not " ,
cdromop . inserted ? " inserted " : " ejected " ) ;
if ( ! cdromop . dev [ 0 ] ) strcpy ( buffer [ 4 ] , " none " ) ;
sprintf ( buffer [ 5 ] , " %s " , SIM - > get_newhd_support ( ) ? " yes " : " no " ) ;
sprintf ( buffer [ 6 ] , " %s " , SIM - > get_boot_hard_disk ( ) ? " hard drive " : " floppy drive " ) ;
2001-06-10 01:12:16 +04:00
// check if diskd and cdromd are on at once
SIM - > get_disk_options ( 1 , & diskop ) ;
int conflict = ( diskop . present & & cdromop . present ) ;
char * diskd_cdromd_conflict_msg = " \n ERROR: \n This configuration has both a cdrom and a hard disk enabled. \n You cannot have both! " ;
snprintf ( buf , size , format , buffer [ 0 ] , buffer [ 1 ] , buffer [ 2 ] , buffer [ 3 ] , buffer [ 4 ] , buffer [ 5 ] , buffer [ 6 ] , conflict ? diskd_cdromd_conflict_msg : " " ) ;
2001-06-08 00:42:00 +04:00
}
2001-06-13 12:14:49 +04:00
void build_runtime_options_prompt ( char * format , char * buf , int size )
{
bx_floppy_options floppyop ;
bx_cdrom_options cdromop ;
2001-06-16 23:29:59 +04:00
bx_param_num_c * ips = SIM - > get_param_num ( BXP_IPS ) ;
2001-06-13 12:14:49 +04:00
char buffer [ 3 ] [ 128 ] ;
for ( int i = 0 ; i < 2 ; i + + ) {
SIM - > get_floppy_options ( i , & floppyop ) ;
sprintf ( buffer [ i ] , " %s, size=%s, %s " , floppyop . path ,
SIM - > get_floppy_type_name ( floppyop . type ) ,
floppyop . initial_status ? " inserted " : " ejected " ) ;
if ( ! floppyop . path [ 0 ] ) strcpy ( buffer [ i ] , " none " ) ;
}
SIM - > get_cdrom_options ( 0 , & cdromop ) ;
sprintf ( buffer [ 2 ] , " %s, %spresent, %s " ,
cdromop . dev , cdromop . present ? " " : " not " ,
cdromop . inserted ? " inserted " : " ejected " ) ;
snprintf ( buf , size , format , buffer [ 0 ] , buffer [ 1 ] , buffer [ 2 ] ,
2001-06-16 23:29:59 +04:00
ips - > get ( ) ,
SIM - > get_param_num ( BXP_VGA_UPDATE_INTERVAL ) - > get ( ) ,
SIM - > get_param_num ( BXP_MOUSE_ENABLED ) - > get ( ) ? " enabled " : " disabled " ) ;
2001-06-13 12:14:49 +04:00
}
2001-06-18 18:11:55 +04:00
int do_mem_options_menu ( ) {
bx_list_c * menu = ( bx_list_c * ) SIM - > get_param ( BXP_MEMORY_OPTIONS_MENU ) ;
while ( 1 ) {
menu - > get_choice ( ) - > set ( 0 ) ;
int status = menu - > text_ask ( stdin , stderr ) ;
if ( status < 0 ) return status ;
bx_param_num_c * choice = menu - > get_choice ( ) ;
if ( choice - > get ( ) < 1 )
return choice - > get ( ) ;
else {
int index = choice - > get ( ) - 1 ; // choosing 1 means list[0]
bx_param_c * chosen = menu - > get ( index ) ;
assert ( chosen ! = NULL ) ;
chosen - > text_ask ( stdin , stderr ) ;
}
}
}
2001-06-10 00:01:12 +04:00
// return value of bx_control_panel:
// -1: error while reading, like if stdin closed
// 0: no error
// BX_DISABLE_CONTROL_PANEL: returned from BX_CPANEL_START_MAIN if
// user chooses to revert to the normal way of running without the
// control panel.
int bx_control_panel ( int menu )
{
2001-06-18 18:11:55 +04:00
Bit32u choice ;
2001-06-10 00:01:12 +04:00
while ( 1 ) {
switch ( menu )
{
case BX_CPANEL_START_MAIN :
2001-06-11 18:03:35 +04:00
bx_control_panel_init ( ) ;
2001-06-10 00:01:12 +04:00
{
if ( ask_yn ( ask_about_control_panel , 1 , & choice ) < 0 ) return - 1 ;
if ( choice = = 0 ) return BX_DISABLE_CONTROL_PANEL ;
else return bx_control_panel ( BX_CPANEL_START_MENU ) ;
}
case BX_CPANEL_START_MENU :
{
static int read_rc = 0 ;
2001-06-18 18:11:55 +04:00
Bit32u default_choice = 1 ;
2001-06-11 10:35:18 +04:00
default_choice = read_rc ? 4 : 1 ;
2001-06-18 18:11:55 +04:00
if ( ask_uint ( startup_menu_prompt , 1 , 5 , default_choice , & choice , 10 ) < 0 ) return - 1 ;
2001-06-10 00:01:12 +04:00
switch ( choice ) {
2001-06-11 10:35:18 +04:00
case 1 : if ( bx_read_rc ( NULL ) > = 0 ) read_rc = 1 ; break ;
case 2 : bx_control_panel ( BX_CPANEL_START_OPTS ) ; break ;
case 3 : bx_write_rc ( NULL ) ; break ;
case 4 : return 0 ; // return from menu
case 5 : SIM - > quit_sim ( 1 ) ; return - 1 ;
2001-06-10 00:01:12 +04:00
default : BAD_OPTION ( menu , choice ) ;
}
}
break ;
case BX_CPANEL_START_OPTS :
{
2001-06-11 10:35:18 +04:00
char prompt [ CPANEL_PATH_LEN ] ;
char oldpath [ CPANEL_PATH_LEN ] ;
assert ( SIM - > get_log_file ( oldpath , CPANEL_PATH_LEN ) > = 0 ) ;
2001-06-10 00:01:12 +04:00
sprintf ( prompt , startup_options_prompt , oldpath ) ;
2001-06-18 18:11:55 +04:00
if ( ask_uint ( prompt , 0 , 8 , 0 , & choice , 10 ) < 0 ) return - 1 ;
2001-06-10 00:01:12 +04:00
switch ( choice ) {
case 0 : return 0 ;
case 1 : bx_log_file ( ) ; break ;
case 2 : bx_log_options ( 0 ) ; break ;
case 3 : bx_log_options ( 1 ) ; break ;
2001-06-13 12:14:49 +04:00
case 4 : bx_control_panel ( BX_CPANEL_START_OPTS_MEM ) ; break ;
2001-06-10 00:01:12 +04:00
case 5 : bx_control_panel ( BX_CPANEL_START_OPTS_INTERFACE ) ; break ;
case 6 : bx_control_panel ( BX_CPANEL_START_OPTS_DISK ) ; break ;
case 7 : bx_control_panel ( BX_CPANEL_START_OPTS_SOUND ) ; break ;
case 8 : bx_control_panel ( BX_CPANEL_START_OPTS_MISC ) ; break ;
default : BAD_OPTION ( menu , choice ) ;
}
}
break ;
2001-06-13 12:14:49 +04:00
case BX_CPANEL_START_OPTS_MEM :
2001-06-18 18:11:55 +04:00
return do_mem_options_menu ( ) ;
2001-06-10 01:19:58 +04:00
case BX_CPANEL_START_OPTS_INTERFACE :
2001-06-10 00:01:12 +04:00
{
2001-06-10 01:12:16 +04:00
char prompt [ 1024 ] ;
2001-06-16 23:29:59 +04:00
int interval = SIM - > get_param_num ( BXP_VGA_UPDATE_INTERVAL ) - > get ( ) ;
bx_param_num_c * ips = SIM - > get_param_num ( BXP_IPS ) ;
2001-06-10 01:19:58 +04:00
sprintf ( prompt , startup_interface_options ,
interval ,
2001-06-16 23:29:59 +04:00
SIM - > get_param_num ( BXP_MOUSE_ENABLED ) - > get ( ) ? " enabled " : " disabled " ,
ips - > get ( ) ,
2001-06-10 01:29:07 +04:00
SIM - > get_private_colormap ( ) ? " enabled " : " disabled " ) ;
2001-06-18 18:11:55 +04:00
if ( ask_uint ( prompt , 0 , 4 , 0 , & choice , 10 ) < 0 ) return - 1 ;
2001-06-10 00:01:12 +04:00
switch ( choice ) {
case 0 : return 0 ;
2001-06-10 01:29:07 +04:00
case 1 : bx_vga_update_interval ( ) ; break ;
case 2 : bx_mouse_enable ( ) ; break ;
case 3 : bx_ips_change ( ) ; break ;
case 4 : bx_private_colormap ( ) ; break ;
2001-06-10 00:01:12 +04:00
default : BAD_OPTION ( menu , choice ) ;
}
}
break ;
2001-06-10 09:30:27 +04:00
case BX_CPANEL_START_OPTS_DISK :
{
char prompt [ 1024 ] ;
build_disk_options_prompt ( startup_disk_options_prompt , prompt , 1024 ) ;
2001-06-18 18:11:55 +04:00
if ( ask_uint ( prompt , 0 , 7 , 0 , & choice , 10 ) < 0 ) return - 1 ;
2001-06-10 09:30:27 +04:00
switch ( choice ) {
case 0 : return 0 ;
case 1 : bx_edit_floppy ( 0 ) ; break ;
case 2 : bx_edit_floppy ( 1 ) ; break ;
case 3 : bx_edit_hard_disk ( 0 ) ; break ;
case 4 : bx_edit_hard_disk ( 1 ) ; break ;
case 5 : bx_edit_cdrom ( ) ; break ;
case 6 : bx_newhd_support ( ) ; break ;
case 7 : bx_boot_from ( ) ; break ;
default : BAD_OPTION ( menu , choice ) ;
}
}
break ;
2001-06-10 00:01:12 +04:00
case BX_CPANEL_RUNTIME :
2001-06-13 12:14:49 +04:00
char prompt [ 1024 ] ;
build_runtime_options_prompt ( runtime_menu_prompt , prompt , 1024 ) ;
2001-06-18 18:11:55 +04:00
if ( ask_uint ( prompt , 1 , 11 , 10 , & choice , 10 ) < 0 ) return - 1 ;
2001-06-10 00:01:12 +04:00
switch ( choice ) {
case 1 : bx_edit_floppy ( 0 ) ; break ;
case 2 : bx_edit_floppy ( 1 ) ; break ;
2001-06-13 12:14:49 +04:00
case 3 : bx_edit_cdrom ( ) ; break ;
case 4 : bx_ips_change ( ) ; break ;
case 5 : bx_log_options ( 0 ) ; break ;
case 6 : bx_log_options ( 1 ) ; break ;
case 7 : bx_vga_update_interval ( ) ; break ;
case 8 : bx_mouse_enable ( ) ; break ;
case 9 : NOT_IMPLEMENTED ( choice ) ; break ;
case 10 : fprintf ( stderr , " Continuing simulation \n " ) ; return 0 ;
case 11 :
2001-06-10 00:01:12 +04:00
fprintf ( stderr , " You chose quit on the control panel. \n " ) ;
SIM - > quit_sim ( 1 ) ;
return - 1 ;
default : fprintf ( stderr , " Menu choice %d not implemented. \n " , choice ) ;
}
break ;
default :
assert ( menu > = 0 & & menu < BX_CPANEL_N_MENUS ) ;
fprintf ( stderr , " --THIS IS A SAMPLE MENU, NO OPTIONS ARE IMPLEMENTED EXCEPT #0-- \n " ) ;
2001-06-18 18:11:55 +04:00
if ( ask_uint ( menu_prompt_list [ menu ] , 0 , 99 , 0 , & choice , 10 ) < 0 ) return - 1 ;
2001-06-10 00:01:12 +04:00
if ( choice = = 0 ) return 0 ;
fprintf ( stderr , " This is a sample menu. Option %d is not implemented. \n " , choice ) ;
}
}
}
2001-06-08 00:42:00 +04:00
2001-06-10 00:01:12 +04:00
void bx_edit_floppy ( int drive )
2001-06-08 00:42:00 +04:00
{
2001-06-10 00:01:12 +04:00
bx_floppy_options opt , newopt ;
assert ( SIM - > get_floppy_options ( drive , & opt ) > = 0 ) ;
newopt = opt ;
fprintf ( stderr , " Changing options for floppy drive %d \n " , drive ) ;
if ( ask_string ( " Enter new pathname: [%s] " , opt . path , newopt . path ) < 0 )
2001-06-08 00:42:00 +04:00
return ;
2001-06-10 00:01:12 +04:00
int newtype , oldtype = opt . type - BX_FLOPPY_NONE ;
if ( ask_menu ( " What is the floppy disk size? \n Choices are 720K, 1.2M, 1.44M, 2.88M. [%s] " , n_floppy_type_names , floppy_type_names , oldtype , & newtype ) < 0 ) return ;
newopt . type = newtype + BX_FLOPPY_NONE ;
if ( SIM - > set_floppy_options ( drive , & newopt ) < 0 ) {
fprintf ( stderr , " The disk image %s could not be opened. \n " , newopt . path ) ;
}
}
void bx_edit_hard_disk ( int drive )
{
bx_disk_options opt , newopt ;
assert ( SIM - > get_disk_options ( drive , & opt ) > = 0 ) ;
newopt = opt ;
fprintf ( stderr , " Changing options for hard drive %d \n " , drive ) ;
if ( ask_string ( " Enter new pathname, or type 'none' for no disk: [%s] " , opt . path , newopt . path ) < 0 )
return ;
2001-06-10 01:12:16 +04:00
newopt . present = ( strcmp ( newopt . path , " none " ) ! = 0 ) ;
if ( newopt . present ) { // skip if "none" is the path.
2001-06-10 00:01:12 +04:00
// ask cyl, head, sec.
2001-06-18 18:11:55 +04:00
Bit32u n ;
if ( ask_uint ( " How many cylinders? [%d] " , 1 , 65535 , opt . cylinders , & n , 10 ) < 0 )
2001-06-10 00:01:12 +04:00
return ;
newopt . cylinders = n ;
2001-06-18 18:11:55 +04:00
if ( ask_uint ( " How many heads? [%d] " , 1 , 256 , opt . heads , & n , 10 ) < 0 )
2001-06-10 00:01:12 +04:00
return ;
newopt . heads = n ;
2001-06-18 18:11:55 +04:00
if ( ask_uint ( " How many sectors per track? [%d] " , 1 , 255 , opt . spt , & n , 10 ) < 0 )
2001-06-10 00:01:12 +04:00
return ;
newopt . spt = n ;
}
if ( SIM - > set_disk_options ( drive , & newopt ) < 0 ) {
fprintf ( stderr , " The disk image %s could not be opened. \n " , newopt . path ) ;
}
}
void bx_edit_cdrom ( )
{
bx_cdrom_options opt , newopt ;
assert ( SIM - > get_cdrom_options ( 0 , & opt ) > = 0 ) ;
newopt = opt ;
newopt . present = 1 ;
if ( ask_string ( " Enter pathname of the cdrom device, or 'none' for no cdrom: [%s] " , opt . dev , newopt . dev ) < 0 )
2001-06-08 00:42:00 +04:00
return ;
2001-06-10 00:01:12 +04:00
if ( ! strcmp ( newopt . dev , " none " ) ) {
newopt . dev [ 0 ] = 0 ;
newopt . present = 0 ;
}
if ( SIM - > set_cdrom_options ( 0 , & newopt ) < 0 ) {
fprintf ( stderr , " The device at %s could not be opened. \n " , newopt . dev ) ;
}
}
void bx_newhd_support ( )
{
2001-06-18 18:11:55 +04:00
Bit32u newval , oldval = SIM - > get_newhd_support ( ) ;
2001-06-10 00:01:12 +04:00
if ( ask_yn ( " Use new hard disk support (recommended)? [%s] " , oldval , & newval ) < 0 ) return ;
if ( newval = = oldval ) return ;
SIM - > set_newhd_support ( newval ) ;
}
2001-06-10 01:29:07 +04:00
void bx_private_colormap ( )
{
2001-06-18 18:11:55 +04:00
Bit32u newval , oldval = SIM - > get_private_colormap ( ) ;
2001-06-10 01:29:07 +04:00
if ( ask_yn ( " Use private colormap? [%s] " , oldval , & newval ) < 0 ) return ;
if ( newval = = oldval ) return ;
SIM - > set_private_colormap ( newval ) ;
}
2001-06-10 00:01:12 +04:00
void bx_boot_from ( )
{
int newval , oldval = SIM - > get_boot_hard_disk ( ) ;
char * choices [ ] = { " fd " , " hd " } ;
if ( ask_menu ( " Boot floppy disk or hard disk? Type hd or fd. [%s] " ,
2 , choices , oldval , & newval ) < 0 ) return ;
SIM - > set_boot_hard_disk ( newval ) ;
2001-06-08 00:42:00 +04:00
}
void bx_ips_change ( )
{
char prompt [ 1024 ] ;
2001-06-16 23:29:59 +04:00
bx_param_num_c * ips = SIM - > get_param_num ( BXP_IPS ) ;
2001-06-18 18:11:55 +04:00
Bit32u oldips = ips - > get ( ) ;
2001-06-08 11:20:07 +04:00
sprintf ( prompt , " Type a new value for ips: [%d] " , oldips ) ;
2001-06-18 18:11:55 +04:00
Bit32u newips ;
if ( ask_uint ( prompt , 1 , 1 < < 30 , oldips , & newips , 10 ) < 0 )
2001-06-08 00:42:00 +04:00
return ;
2001-06-16 23:29:59 +04:00
ips - > set ( newips ) ;
2001-06-08 00:42:00 +04:00
}
2001-06-10 00:01:12 +04:00
void bx_vga_update_interval ( )
{
char prompt [ 1024 ] ;
2001-06-16 23:29:59 +04:00
bx_param_num_c * pinterval = SIM - > get_param_num ( BXP_VGA_UPDATE_INTERVAL ) ;
2001-06-18 18:11:55 +04:00
Bit32u old = pinterval - > get ( ) ;
2001-06-10 00:01:12 +04:00
sprintf ( prompt , " Type a new value for VGA update interval: [%d] " , old ) ;
2001-06-18 18:11:55 +04:00
Bit32u newinterval ;
if ( ask_uint ( prompt , 1 , 1 < < 30 , old , & newinterval , 10 ) < 0 )
2001-06-10 00:01:12 +04:00
return ;
2001-06-16 23:29:59 +04:00
pinterval - > set ( newinterval ) ;
2001-06-10 00:01:12 +04:00
}
2001-06-08 00:42:00 +04:00
static void bx_print_log_action_table ( )
{
// just try to print all the prefixes first.
fprintf ( stderr , " Current log settings: \n " ) ;
fprintf ( stderr , " Debug Info Error Panic \n " ) ;
fprintf ( stderr , " ID Device Action Action Action Action \n " ) ;
2001-06-10 00:01:12 +04:00
fprintf ( stderr , " ---- --------- --------- --------- ---------- ---------- \n " ) ;
2001-06-12 00:51:15 +04:00
int i , j , imax = SIM - > get_n_log_modules ( ) ;
for ( i = 0 ; i < imax ; i + + ) {
2001-06-08 11:20:07 +04:00
fprintf ( stderr , " %3d. %s " , i , SIM - > get_prefix ( i ) ) ;
2001-06-12 00:51:15 +04:00
for ( j = 0 ; j < SIM - > get_max_log_level ( ) ; j + + ) {
2001-06-08 11:20:07 +04:00
fprintf ( stderr , " %10s " , SIM - > get_action_name ( SIM - > get_log_action ( i , j ) ) ) ;
2001-06-08 00:42:00 +04:00
}
fprintf ( stderr , " \n " ) ;
}
}
static char * log_options_prompt1 = " Enter the ID of the device to edit, or -1 to return: [-1] " ;
2001-06-13 12:14:49 +04:00
static char * log_level_choices [ ] = { " ignore " , " report " , " ask " , " fatal " , " no change " } ;
static int log_level_n_choices_normal = 4 ;
2001-06-08 00:42:00 +04:00
2001-06-10 00:01:12 +04:00
void bx_log_options ( int individual )
2001-06-08 00:42:00 +04:00
{
2001-06-10 00:01:12 +04:00
if ( individual ) {
int done = 0 ;
while ( ! done ) {
bx_print_log_action_table ( ) ;
2001-06-18 18:11:55 +04:00
Bit32s id , level , action ;
Bit32s maxid = SIM - > get_n_log_modules ( ) ;
2001-06-10 00:01:12 +04:00
if ( ask_int ( log_options_prompt1 , - 1 , maxid - 1 , - 1 , & id ) < 0 )
return ;
if ( id < 0 ) return ;
fprintf ( stderr , " Editing log options for the device %s \n " , SIM - > get_prefix ( id ) ) ;
for ( level = 0 ; level < SIM - > get_max_log_level ( ) ; level + + ) {
char prompt [ 1024 ] ;
int default_action = SIM - > get_log_action ( id , level ) ;
sprintf ( prompt , " Enter action for %s event: [%s] " , SIM - > get_log_level_name ( level ) , SIM - > get_action_name ( default_action ) ) ;
// don't show the no change choice (choices=3)
2001-06-13 12:14:49 +04:00
if ( ask_menu ( prompt , log_level_n_choices_normal , log_level_choices , default_action , & action ) < 0 )
2001-06-10 00:01:12 +04:00
return ;
SIM - > set_log_action ( id , level , action ) ;
}
}
} else {
// provide an easy way to set log options for all devices at once
2001-06-08 00:42:00 +04:00
bx_print_log_action_table ( ) ;
2001-06-10 00:01:12 +04:00
for ( int level = 0 ; level < SIM - > get_max_log_level ( ) ; level + + ) {
2001-06-08 00:42:00 +04:00
char prompt [ 1024 ] ;
2001-06-10 00:01:12 +04:00
int action , default_action = 3 ; // default to no change
sprintf ( prompt , " Enter action for %s event on all devices: [no change] " , SIM - > get_log_level_name ( level ) ) ;
// do show the no change choice (choices=4)
2001-06-13 12:14:49 +04:00
if ( ask_menu ( prompt , log_level_n_choices_normal + 1 , log_level_choices , default_action , & action ) < 0 )
2001-06-08 00:42:00 +04:00
return ;
2001-06-10 00:01:12 +04:00
if ( action < 3 ) {
for ( int i = 0 ; i < SIM - > get_n_log_modules ( ) ; i + + )
SIM - > set_log_action ( i , level , action ) ;
}
2001-06-08 00:42:00 +04:00
}
}
}
2001-06-10 00:01:12 +04:00
void bx_mouse_enable ( )
{
2001-06-16 23:29:59 +04:00
bx_param_num_c * mouse_en = SIM - > get_param_num ( BXP_MOUSE_ENABLED ) ;
2001-06-18 18:11:55 +04:00
Bit32u newval , oldval = mouse_en - > get ( ) ;
2001-06-10 00:01:12 +04:00
if ( ask_yn ( " Enable the mouse? [%s] " , oldval , & newval ) < 0 ) return ;
if ( newval = = oldval ) return ;
2001-06-16 23:29:59 +04:00
mouse_en - > set ( newval ) ;
2001-06-10 00:01:12 +04:00
}
int bx_read_rc ( char * rc )
{
if ( rc & & SIM - > read_rc ( rc ) > = 0 ) return 0 ;
2001-06-11 10:35:18 +04:00
char oldrc [ CPANEL_PATH_LEN ] ;
if ( SIM - > get_default_rc ( oldrc , CPANEL_PATH_LEN ) < 0 )
strcpy ( oldrc , " none " ) ;
char newrc [ CPANEL_PATH_LEN ] ;
2001-06-10 00:01:12 +04:00
while ( 1 ) {
2001-06-11 10:35:18 +04:00
if ( ask_string ( " \n What is the configuration file name? \n To cancel, type 'none'. [%s] " , oldrc , newrc ) < 0 ) return - 1 ;
2001-06-10 00:01:12 +04:00
if ( ! strcmp ( newrc , " none " ) ) return 0 ;
if ( SIM - > read_rc ( newrc ) > = 0 ) return 0 ;
fprintf ( stderr , " The file '%s' could not be found. \n " , newrc ) ;
}
}
2001-06-11 10:35:18 +04:00
int bx_write_rc ( char * rc )
{
char oldrc [ CPANEL_PATH_LEN ] , newrc [ CPANEL_PATH_LEN ] ;
if ( rc = = NULL ) {
if ( SIM - > get_default_rc ( oldrc , CPANEL_PATH_LEN ) < 0 )
strcpy ( oldrc , " none " ) ;
} else {
strncpy ( oldrc , rc , CPANEL_PATH_LEN ) ;
}
while ( 1 ) {
if ( ask_string ( " Save configuration to what file? To cancel, type 'none'. \n [%s] " , oldrc , newrc ) < 0 ) return - 1 ;
if ( ! strcmp ( newrc , " none " ) ) return 0 ;
// try with overwrite off first
int status = SIM - > write_rc ( newrc , 0 ) ;
if ( status > = 0 ) {
fprintf ( stderr , " Wrote configuration to '%s'. \n " , newrc ) ;
return 0 ;
} else if ( status = = - 2 ) {
// return code -2 indicates the file already exists, and overwrite
// confirmation is required.
2001-06-18 18:11:55 +04:00
Bit32u overwrite = 0 ;
2001-06-11 10:35:18 +04:00
char prompt [ 256 ] ;
sprintf ( prompt , " Configuration file '%s' already exists. Overwrite it? [no] " , newrc ) ;
if ( ask_yn ( prompt , 0 , & overwrite ) < 0 ) return - 1 ;
if ( ! overwrite ) continue ; // if "no", start loop over, asking for a different file
// they confirmed, so try again with overwrite bit set
if ( SIM - > write_rc ( newrc , 1 ) > = 0 ) {
fprintf ( stderr , " Overwriting existing configuration '%s'. \n " , newrc ) ;
return 0 ;
} else {
fprintf ( stderr , " Write failed to '%s'. \n " , newrc ) ;
}
}
}
}
2001-06-10 00:01:12 +04:00
void bx_log_file ( )
{
2001-06-11 10:35:18 +04:00
char oldpath [ CPANEL_PATH_LEN ] , newpath [ CPANEL_PATH_LEN ] ;
assert ( SIM - > get_log_file ( oldpath , CPANEL_PATH_LEN ) > = 0 ) ;
2001-06-10 00:01:12 +04:00
if ( ask_string ( " Enter log file name: [%s] " , oldpath , newpath ) < 0 ) return ;
SIM - > set_log_file ( newpath ) ;
}
2001-06-10 01:12:16 +04:00
2001-06-11 18:03:35 +04:00
/*
A panic has occurred . Do you want to :
cont - continue execution
alwayscont - continue execution , and do not ask again
die - stop execution now
*/
char * log_action_ask_choices [ ] = { " cont " , " alwayscont " , " die " } ;
int log_action_n_choices = 3 ;
int control_panel_notify_callback ( int code )
{
switch ( code )
{
case NOTIFY_CODE_LOGMSG :
{
int level ;
char prefix [ 512 ] , msg [ 512 ] ;
assert ( SIM - > log_msg_2 ( prefix , & level , msg , sizeof ( msg ) ) > = 0 ) ;
fprintf ( stderr , " ========================================================================\n " ) ;
fprintf ( stderr , " Event type: %s \n " , SIM - > get_log_level_name ( level ) ) ;
fprintf ( stderr , " Device: %s \n " , prefix ) ;
fprintf ( stderr , " Message: %s \n \n " , msg ) ;
2001-06-11 18:07:54 +04:00
fprintf ( stderr , " A %s has occurred. Do you want to: \n " , SIM - > get_log_level_name ( level ) ) ;
2001-06-11 18:03:35 +04:00
fprintf ( stderr , " cont - continue execution \n " ) ;
fprintf ( stderr , " alwayscont - continue execution, and don't ask again. \n " ) ;
fprintf ( stderr , " This affects only %s events from device %s \n " , SIM - > get_log_level_name ( level ) , prefix ) ;
fprintf ( stderr , " die - stop execution now \n " ) ;
int choice ;
if ( ask_menu ( " Choose cont, alwayscont, or die. [%s] " , 3 ,
log_action_ask_choices , 2 , & choice ) < 0 )
return SIM - > notify_return ( - 1 ) ;
// return 0 for continue, 1 for alwayscontinue, 2 for die.
SIM - > notify_return ( choice ) ;
}
break ;
default :
fprintf ( stderr , " Control panel: notify callback called with unknown code %04x \n " , code ) ;
}
2001-06-12 00:51:15 +04:00
// error if we fall through the case
return - 1 ;
2001-06-11 18:03:35 +04:00
}
void bx_control_panel_init ( ) {
//fprintf (stderr, "bx_control_panel_init()\n");
SIM - > set_notify_callback ( control_panel_notify_callback ) ;
}
2001-06-18 18:11:55 +04:00
/////////////////////////////////////////////////////////////////////
// implement the text_* methods for bx_param types.
void
bx_param_num_c : : text_print ( FILE * fp )
{
//fprintf (fp, "number parameter, id=%u, name=%s\n", get_id (), get_name ());
//fprintf (fp, "value=%u\n", get ());
if ( get_format ( ) ) {
fprintf ( fp , get_format ( ) , get ( ) ) ;
fprintf ( fp , " \n " ) ;
} else {
char * format = " %s: %d \n " ;
assert ( base = = 10 | | base = = 16 ) ;
if ( base = = 16 ) format = " %s: 0x%x \n " ;
fprintf ( fp , format , get_name ( ) , get ( ) ) ;
}
}
void
bx_param_string_c : : text_print ( FILE * fp )
{
//fprintf (fp, "string parameter, id=%u, name=%s\n", get_id (), get_name ());
//fprintf (fp, "value=%s\n", getptr ());
if ( get_format ( ) ) {
fprintf ( fp , get_format ( ) , getptr ( ) ) ;
fprintf ( fp , " \n " ) ;
} else {
fprintf ( fp , " %s: %s \n " , get_name ( ) , getptr ( ) ) ;
}
}
void
bx_list_c : : text_print ( FILE * fp )
{
fprintf ( fp , " This is a list. \n " ) ;
fprintf ( fp , " title=%s \n " , title - > getptr ( ) ) ;
fprintf ( fp , " options=%s%s%s \n " ,
( options - > get ( ) = = 0 ) ? " none " : " " ,
( options - > get ( ) & BX_SHOW_PARENT ) ? " SHOW_PARENT " : " " ,
( options - > get ( ) & BX_SERIES_ASK ) ? " SERIES_ASK " : " " ) ;
for ( int i = 0 ; i < size ; i + + ) {
fprintf ( fp , " param[%d] = %p \n " , i , list [ i ] ) ;
if ( list [ i ] )
list [ i ] - > text_print ( fp ) ;
}
}
int
bx_param_num_c : : text_ask ( FILE * fpin , FILE * fpout )
{
fprintf ( fpout , " \n " ) ;
int status ;
char * prompt = get_ask_format ( ) ;
if ( prompt = = NULL ) {
// default prompt, if they didn't set an ask format string
text_print ( fpout ) ;
prompt = " Enter new value: [%d] " ;
if ( base = = 16 )
prompt = " Enter new value in hex: [%x] " ;
}
Bit32u n = get ( ) ;
status = ask_uint ( prompt , min , max , n , & n , base ) ;
if ( status < 0 ) return status ;
set ( n ) ;
return 0 ;
}
int
bx_param_string_c : : text_ask ( FILE * fpin , FILE * fpout )
{
fprintf ( fpout , " \n " ) ;
int status ;
char * prompt = get_ask_format ( ) ;
if ( prompt = = NULL ) {
// default prompt, if they didn't set an ask format string
text_print ( fpout ) ;
prompt = " Enter a new value, or press return for no change. \n " ;
}
//FIXME
char buffer [ 1024 ] ;
status = ask_string ( prompt , getptr ( ) , buffer ) ;
if ( status < 0 ) return status ;
set ( buffer ) ;
return 0 ;
}
int
bx_list_c : : text_ask ( FILE * fpin , FILE * fpout )
{
fprintf ( fpout , " \n " ) ;
int i , imax = strlen ( title - > getptr ( ) ) ;
for ( i = 0 ; i < imax ; i + + ) fprintf ( fpout , " - " ) ;
fprintf ( fpout , " \n %s \n " , title - > getptr ( ) ) ;
for ( i = 0 ; i < imax ; i + + ) fprintf ( fpout , " - " ) ;
fprintf ( fpout , " \n " ) ;
//fprintf (fp, "options=%s\n", options->get ());
if ( options - > get ( ) & BX_SHOW_PARENT )
fprintf ( fpout , " 0. Return to previous menu \n " ) ;
for ( int i = 0 ; i < size ; i + + ) {
assert ( list [ i ] ! = NULL ) ;
fprintf ( fpout , " %d. " , i + 1 ) ;
list [ i ] - > text_print ( fpout ) ;
}
fprintf ( fpout , " \n " ) ;
Bit32u n = choice - > get ( ) ;
int min = ( options - > get ( ) & BX_SHOW_PARENT ) ? 0 : 1 ;
int max = size ;
int status = ask_uint ( " Please choose one: [%d] " , min , max , n , & n , 10 ) ;
if ( status < 0 ) return status ;
choice - > set ( n ) ;
return 0 ;
}
///////////////////////////////////////////////////////////
2001-06-11 10:48:37 +04:00
# endif