#!/usr/bin/perl

# Header for Xconfigurator

$INC{"flush.pl"} = "loaded";
$INC{"vidmodes"} = "loaded";
$INC{"monitors"} = "loaded";

##################################
# Functions that handle calling dialog(1) -*-perl-*-

# Return values are 1 for success and 0 for failure (or cancel)
# Resultant text (if any) is in dialog_result

# Unfortunately, the gauge requires use of /bin/sh to get going.
# I didn't bother to make the others shell-free, although it
# would be simple to do.

# Note that dialog generally returns 0 for success, so I invert the
# sense of the return code for more readable boolean expressions.

$scr_lines = 24;

require "flush.pl";

sub rhs_clear {
    return system("dialog --clear");
}

sub rhs_textbox {
    local ( $title, $file, $width, $height ) = @_;

    system("dialog --title \"$title\" --textbox $file $height $width");

    return 1;
}

sub rhs_msgbox {
    local ( $title, $message, $width ) = @_;
    local ( $tmp, $height, $message_len );

    $message = &rhs_wordwrap($message, $width);
    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    $height = 4 + $message_len;

    $tmp = system("dialog --title \"$title\" --msgbox \"$message\" $height $width");
    if ($tmp) {
	return 0;
    } else {
	return 1;
    }
}

sub rhs_infobox {
    local ( $title, $message, $width ) = @_;
    local ( $tmp, $height, $message_len );

    $message = &rhs_wordwrap($message, $width);
    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    $height = 2 + $message_len;

    return system("dialog --title \"$title\" --infobox \"$message\" $height $width");
}

sub rhs_yesno {
    local ( $title, $message, $width ) = @_;
    local ( $tmp, $height, $message_len );

    $message = &rhs_wordwrap($message, $width);
    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    $height = 4 + $message_len;

    $tmp = system("dialog --title \"$title\" --yesno \"$message\" $height $width");
    # Dumb: dialog returns 0 for "yes" and 1 for "no"
    if (! $tmp) {
	return 1;
    } else {
	return 0;
    }
}

sub rhs_gauge {
    local ( $title, $message, $width, $percent ) = @_;
    local ( $tmp, $height, $message_len );

    $gauge_width = $width;

    $message = &rhs_wordwrap($message, $width);
    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    $height = 5 + $message_len;

    open(GAUGE, "|dialog --title \"$title\" --gauge \"$message\" $height $width $percent");
}

sub rhs_update_gauge {
    local ( $percent ) = @_;

    &printflush(GAUGE, "$percent\n");
}

sub rhs_update_gauge_and_message {
    local ( $message, $percent ) = @_;

    $message = &rhs_wordwrap($message, $gauge_width);
    $message =~ s/\n/\\n/g;
    &printflush(GAUGE, "XXX\n$percent\n$message\nXXX\n");
}

sub rhs_stop_gauge {
    close GAUGE;
}

sub rhs_inputbox {
    local ( $title, $message, $width, $instr ) = @_;
    local ( $tmp, $height, $message_len, $result);

    $message = &rhs_wordwrap($message, $width);
    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    $height = 7 + $message_len;

    $result = &return_output(0, "dialog --title \"$title\" --inputbox \"$message\" $height $width \"$instr\"");
    while (($dialog_result =~ /\"/) ||
           ($dialog_result =~ /\'/) ||
           ($dialog_result =~ /\`/) ||
           ($dialog_result =~ /\|/) ||
           ($dialog_result =~ /\;/) ||
           ($dialog_result =~ /\&/) ||
           ($dialog_result =~ /\>/) ||
           ($dialog_result =~ /\</) ||
           ($dialog_result =~ /\*/)) {
	&rhs_msgbox("Malformed Input",
<<EOM
>
Please do not enter text with of the following characters:
>
\' \\" \\` \| \; \& \> \< \*
>
EOM
		    , 50);
	$result = &return_output(0, "dialog --title \"$title\" --inputbox \"$message\" $height $width \"$instr\"");
	$_ = $result;
    }

    return $result;
}

sub rhs_menu {
    local ( $title, $message, $width, $numitems ) = @_;
    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );

    shift; shift; shift; shift;

    @list = ();
    for ($i = 0; $i < $numitems; $i++) {
        $ent = shift;
        $list[@list] = "\"$ent\"";
	$ent = shift;
        $list[@list] = "\"$ent\"";
    }

    $message = &rhs_wordwrap($message, $width);

    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    
    $height = $message_len + 6 + $numitems;
    if ($height <= $scr_lines) {
        $menuheight = $numitems;
    } else {
        $height = $scr_lines;
        $menuheight = $scr_lines - $message_len - 6;
    }

    return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
}

sub rhs_menul {
    local ( $title, $message, $width, $numitems ) = @_;
    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );

    shift; shift; shift; shift;

    @list = ();
    for ($i = 0; $i < $numitems; $i++) {
        $ent = shift;
        $list[@list] = "\"$ent\"";
        $list[@list] = "\"\"";
    }

    $message = &rhs_wordwrap($message, $width);

    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }

    $height = $message_len + 6 + $numitems;
    if ($height <= $scr_lines) {
        $menuheight = $numitems;
    } else {
        $height = $scr_lines;
        $menuheight = $scr_lines - $message_len - 6;
    }

    return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
}

sub rhs_menua {
    local ( $title, $message, $width, %items ) = @_;
    local ( $tmp, $ent, $height, $menuheight, @list, $message_len );

    @list = ();
    foreach $ent (sort keys (%items)) {
        $list[@list] = "\"$ent\"";
        $list[@list] = "\"$items{$ent}\"";
    }

    $message = &rhs_wordwrap($message, $width);

    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }

    $numitems = keys(%items);
    $height = $message_len + 6 + $numitems;
    if ($height <= $scr_lines) {
        $menuheight = $numitems;
    } else {
        $height = $scr_lines;
        $menuheight = $scr_lines - $message_len - 6;
    }

    return &return_output(0, "dialog --title \"$title\" --menu \"$message\" $height $width $menuheight @list");
}

sub rhs_checklist {
    local ( $title, $message, $width, $numitems ) = @_;
    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );

    shift; shift; shift; shift;

    @list = ();
    for ($i = 0; $i < $numitems; $i++) {
        $ent = shift;
        $list[@list] = "\"$ent\"";
        $ent = shift;
        $list[@list] = "\"$ent\"";
        $ent = shift;
	if ($ent) {
	    $list[@list] = "ON";
	} else {
	    $list[@list] = "OFF";
	}
    }

    $message = &rhs_wordwrap($message, $width);

    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    
    $height = $message_len + 6 + $numitems;
    if ($height <= $scr_lines) {
        $menuheight = $numitems;
    } else {
        $height = $scr_lines;
        $menuheight = $scr_lines - $message_len - 6;
    }

    return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
}

sub rhs_checklistl {
    local ( $title, $message, $width, $numitems ) = @_;
    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );

    shift; shift; shift; shift;

    @list = ();
    for ($i = 0; $i < $numitems; $i++) {
        $ent = shift;
        $list[@list] = "\"$ent\"";
        $list[@list] = "\"\"";
	$list[@list] = "OFF";
    }

    $message = &rhs_wordwrap($message, $width);

    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    
    $height = $message_len + 6 + $numitems;
    if ($height <= $scr_lines) {
        $menuheight = $numitems;
    } else {
        $height = $scr_lines;
        $menuheight = $scr_lines - $message_len - 6;
    }
    return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
}

sub rhs_checklista {
    local ( $title, $message, $width, %items ) = @_;
    local ( $tmp, $ent, $height, $menuheight, @list, $message_len );

    shift; shift; shift; shift;

    @list = ();
    foreach $ent (sort keys (%items)) {
	$list[@list] = "\"$ent\"";
	$list[@list] = "\"$items{$ent}\"";
	$list[@list] = "OFF";
    }

    $message = &rhs_wordwrap($message, $width);

    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }
    
    $numitems = keys(%items);
    $height = $message_len + 6 + $numitems;
    if ($height <= $scr_lines) {
        $menuheight = $numitems;
    } else {
        $height = $scr_lines;
        $menuheight = $scr_lines - $message_len - 6;
    }

    return &return_output("list", "dialog --title \"$title\" --separate-output --checklist \"$message\" $height $width $menuheight @list");
}

sub rhs_radiolist {
    local ( $title, $message, $width, $numitems ) = @_;
    local ( $i, $tmp, $ent, $height, $menuheight, @list, $message_len );

    shift; shift; shift; shift;

    @list = ();
    for ($i = 0; $i < $numitems; $i++) {
        $ent = shift;
        $list[@list] = "\"$ent\"";
        $ent = shift;
        $list[@list] = "\"$ent\"";
        $ent = shift;
	if ($ent) {
	    $list[@list] = "ON";
	} else {
	    $list[@list] = "OFF";
	}
    }

    $message = &rhs_wordwrap($message, $width);

    $message_len = split(/^/, $message);
    $tmp = $message;
    if (chop($tmp) eq "\n") {
	$message_len++;
    }

    $height = $message_len + 6 + $numitems;
    if ($height <= $scr_lines) {
        $menuheight = $numitems;
    } else {
        $height = $scr_lines;
        $menuheight = $scr_lines - $message_len - 6;
    }

    return &return_output(0 , "dialog --title \"$title\" --radiolist \"$message\" $height $width $menuheight @list");
}

sub return_output {
    local ( $listp, $command ) = @_;
    local ( $res );

    open(SAVESTDERR, ">&STDERR");
    open(STDERR, ">/tmp/dialogout");
    $res = system($command);
    close(STDERR);
    open(STDERR, ">&SAVESTDERR");
    
    open(IN, "/tmp/dialogout");
    if ($listp) {
	@dialog_result = ();
	while (<IN>) {
	    chop;
	    $dialog_result[@dialog_result] = $_;
	}
    } else {
	$dialog_result = <IN>;
    }
    close(IN);
    unlink("/tmp/dialogout");

    # Again, dialog returns results backwards
    if (! $res) {
	return 1;
    } else {
	return 0;
    }
}

sub rhs_wordwrap {
    local ( $intext, $width ) = @_;
    local ( $outtext, $i, $j, @lines, $wrap, @words, $pos, $pad );

    $outtext = "";
    $pad = 3;			# leave 3 spaces around each line
    $pos = $pad;		# current insert position
    $wrap = 0;			# 1 if we have been auto wraping
    $insert_nl = 0;		# 1 if we just did an absolute
				# and we should preface any new text
				# with a new line
    @lines = split(/\n/, $intext);
    for ($i = 0; $i <= $#lines; $i++) {
        if ($lines[$i] =~ /^>/) {
	    $outtext .= "\n" if ($insert_nl);
            $outtext .= "\n" if ($wrap);
	    $lines[$i] =~ /^>(.*)$/;
            $outtext .= $1;
	    $insert_nl = 1;
            $wrap = 0;
            $pos = $pad;
        } else {
            $wrap = 1;
            @words = split(/\s+/,$lines[$i]);
            for ($j = 0; $j <= $#words; $j++) {
		if ($insert_nl) {
		    $outtext .= "\n";
		    $insert_nl = 0;
		}
                if ((length($words[$j]) + $pos) > $width - $pad) {
                    $outtext .= "\n";
                    $pos = $pad;
                }
                $outtext .= $words[$j] . " ";
                $pos += length($words[$j]) + 1;
            }
        }
    }

    return $outtext;
}

############
1;
;# Usage: &flush(FILEHANDLE)
;# flushes the named filehandle

;# Usage: &printflush(FILEHANDLE, "prompt: ")
;# prints arguments and flushes filehandle

sub flush {
    local($old) = select(shift);
    $| = 1;
    print "";
    $| = 0;
    select($old);
}

sub printflush {
    local($old) = select(shift);
    $| = 1;
    print @_;
    $| = 0;
    select($old);
}

1;
# Misc routines

# Variable $no_invoke controls whether or not commands are executed

# Vaiable $show_invoke, if true, causes invoke to display the command
# to be run before running it.

$no_invoke = 0;
$show_invoke = 0;
$hold_on_error = 1;

sub cmp_reverse {
    $b cmp $a
}

sub member {
    local ( $element, @list ) = @_;
    local ( $tmp );

    foreach $tmp (@list) {
	if ($tmp eq $element) {
	    return 1;
	}
    }

    return 0;
}

sub abs {
    local ($i) = @_;

    $i = -$i if ($i < 0);
    return $i;
}

sub invoke {
    local ($command) = @_;
    local ( $ret );

    if ($show_invoke) {
	&rhs_msgbox("invoke", $command, 75);
    }

    $ret = 0;
    if (! $no_invoke) {
	$ret = system($command) / 256;
    }

    if ($ret && $hold_on_error) {
	print "\nError.  The following exited with code $ret\n";
	print "$command\n";
	print "\nPress enter to continue.\n";
	<STDIN>;
    }
    return $ret;
}

sub rhs_error {
    print "\nAn error of some kind occurred.\n";
    print "Press enter to continue: ";
    <STDIN>;
}

sub invoke_no_output {
    local ( $command ) = @_;
    local ( $ret );

    if ($show_invoke) {
	&rhs_msgbox("invoke", $command, 75);
    }

    open(SAVEERR, ">&STDERR");
    open(SAVEOUT, ">&STDOUT");
    open(STDERR, ">/dev/null");
    open(STDOUT, ">/dev/null");
    $ret = system($command) unless ($no_invoke);
    open(STDERR, ">&SAVEERR");
    open(STDOUT, ">&SAVEOUT");

    return $ret;
}

sub asciitime {
    local ( $tval ) = @_;
    local ( $secs, $mins, $hours );

    $hours = $tval / 3600;
    $tval %= 3600;
    $mins = $tval / 60;
    $secs = $tval % 60;

    return sprintf("%02d:%02d:%02d", $hours, $mins, $secs);
}

######################
1;
# Video Modes -*-perl-*-

@vidmodes = ("640x480   72Hz VESA Non-Interlaced",                "640x480_1",    31.5,   " 640  664  704  832    480  489  492  520",
	     "640x480   60Hz      Non-Interlaced",                "640x480_2",    25.175, " 640  664  760  800    480  491  493  525",
             "640x480   60Hz      Non-Interlaced (Alternate)",    "640x480_3",    25.175, " 640  672  768  800    480  490  492  525",
             "640x480   63Hz      Non-Interlaced (non-standard)", "640x480_4",    28.322, " 640  680  720  864    480  488  491  521",
             "640x480   70Hz      Non-Interlaced (non-standard)", "640x480_5",    31.5,   " 640  680  720  864    480  488  491  521",
             

             "800x600   56Hz VESA Non-Interlaced",                "800x600_1",    36,     " 800  824  896 1024    600  601  603  625",
             "800x600   56Hz      Non-Interlaced (Alternate)",    "800x600_2",    36,     " 800  832  976 1016    600  604  606  634",
             "800x600   60Hz VESA Non-Interlaced",                "800x600_3",    40,     " 800  840  968 1056    600  601  605  628  +hsync +vsync",
             "800x600   60Hz      Non-Interlaced (Alternate)",    "800x600_4",    40,     " 800  848 1000 1056    600  605  607  633",
             "800x600   72Hz VESA Non-Interlaced",                "800x600_5",    50,     " 800  856  976 1040    600  637  643  666  +hsync +vsync",

             "1024x768  43.5Hz    Interlaced (8514/A standard)",  "1024x768i",    44.9,   "1024 1048 1208 1264    768  776  784  817 Interlace",

             "1024x768  60Hz VESA Non-Interlaced",                "1024x768_1",   65,     "1024 1032 1176 1344    768  771  777  806  -hsync -vsync",
             "1024x768  70Hz VESA Non-Interlaced",                "1024x768_2",   75,     "1024 1048 1184 1328    768  771  777  806  -hsync -vsync",
             "1024x768  60Hz      Non-Interlaced (non-standard)", "1024x768_3",   62,     "1024 1064 1240 1280    768  774  776  808",
             "1024x768  70Hz      Non-Interlaced (non-standard)", "1024x768_4",   72,     "1024 1056 1192 1280    768  770  776  806  -hsync -vsync",
             "1024x768  76Hz      Non-Interlaced",                "1024x768_5",   85,     "1024 1032 1152 1360    768  784  787  823",

             "1152x910  60Hz      Non-Interlaced (non-standard)", "1152x910",     80,     "1152 1176 1424 1424    910  910  924  936",

             "1152x900  68Hz      Non-Interlaced (non-standard)", "1152x900_1",   90,     "1152 1256 1272 1424    910  907  912  929",
             "1152x900  68Hz      Non-Interlaced (non-standard2)","1152x900_2",   95,     "1152 1152 1192 1472    900  900  931  939",
             "1152x900  76Hz      Non-Interlaced (non-standard)", "1152x900_3",   110,    "1152 1184 1344 1528    900  901  903  935",

             "1280x1024 44Hz      Interlaced",                    "1280x1024i_1", 80,     "1280 1296 1512 1568   1024 1025 1037 1165  Interlace",
             "1280x1024 44Hz      Interlaced (non-standard)",     "1280x1024i_2", 75,     "1280 1312 1528 1576   1024 1028 1034 1080  Interlace",

             "1280x1024 59Hz      Non-Interlaced (non-standard)", "1280x1024_1",  110,    "1280 1320 1480 1728   1024 1029 1036 1077",
             "1280x1024 61Hz      Non-Interlaced",                "1280x1024_2",  110,    "1280 1328 1512 1712   1024 1025 1028 1054",
             "1280x1024 74Hz      Non-Interlaced",                "1280x1024_3",  135,    "1280 1312 1456 1712   1024 1027 1030 1064");

#######
1;

# Monitor Timings -*-perl-*-

# This was generated from the Monitors file using gentimigs
# It was cleaned up by hand

$monitor_bandwidth{"Custom"} = "50";
$monitor_horizsync{"Custom"} = "30-64";
$monitor_vertrefresh{"Custom"} = "50-100";

$monitor_bandwidth{"Generic Multisync"} = "50";
$monitor_horizsync{"Generic Multisync"} = "30-64";
$monitor_vertrefresh{"Generic Multisync"} = "50-100";

$monitor_bandwidth{"NEC XE15"} = "85";
$monitor_horizsync{"NEC XE15"} = "31-65";
$monitor_vertrefresh{"NEC XE15"} = "55-120";

$monitor_bandwidth{"AOC-15"} = "135";
$monitor_horizsync{"AOC-15"} = "23.5-86";
$monitor_vertrefresh{"AOC-15"} = "50-120";

$monitor_bandwidth{"Apollo 1280x1024-68Hz"} = "125";
$monitor_horizsync{"Apollo 1280x1024-68Hz"} = "73.702";
$monitor_vertrefresh{"Apollo 1280x1024-68Hz"} = "68.24";

$monitor_bandwidth{"Apollo 1280x1024-70Hz"} = "125";
$monitor_horizsync{"Apollo 1280x1024-70Hz"} = "75.118";
$monitor_vertrefresh{"Apollo 1280x1024-70Hz"} = "70.07";

$monitor_bandwidth{"Chuntex CTX CPS-1560/LR"} = "75.0";
$monitor_horizsync{"Chuntex CTX CPS-1560/LR"} = "30.00-60.00";
$monitor_vertrefresh{"Chuntex CTX CPS-1560/LR"} = "50.00-100.00";

$monitor_bandwidth{"Compudyne KD-1500N"} = "74.8";
$monitor_horizsync{"Compudyne KD-1500N"} = "30.00-66";
$monitor_vertrefresh{"Compudyne KD-1500N"} = "50-90";

$monitor_bandwidth{"CTX-1561"} = "100";
$monitor_horizsync{"CTX-1561"} = "30-60";
$monitor_vertrefresh{"CTX-1561"} = "50-90";

$monitor_bandwidth{"CrystalScan 1572FS"} = "80.0";
$monitor_horizsync{"CrystalScan 1572FS"} = "30.00-57.00";
$monitor_vertrefresh{"CrystalScan 1572FS"} = "43.00-70.04";

$monitor_bandwidth{"DEC PCXBV-KA/KB"} = "120.0";
$monitor_horizsync{"DEC PCXBV-KA/KB"} = "30.0-66.0";
$monitor_vertrefresh{"DEC PCXBV-KA/KB"} = "50-130";

$monitor_bandwidth{"Dell VS17"} = "78.0";
$monitor_horizsync{"Dell VS17"} = "30.0-62.0";
$monitor_vertrefresh{"Dell VS17"} = "50-90";

$monitor_bandwidth{"DELL VS17"} = "25.2";
$monitor_horizsync{"DELL VS17"} = "30-62";
$monitor_vertrefresh{"DELL VS17"} = "50-90";

$monitor_bandwidth{"EIZO FlexScan T660"} = "135.0";
$monitor_horizsync{"EIZO FlexScan T660"} = "30.0-82.0";
$monitor_vertrefresh{"EIZO FlexScan T660"} = "55.0-90.0";

$monitor_bandwidth{"EIZO FlexScan 9080i"} = "60.0";
$monitor_horizsync{"EIZO FlexScan 9080i"} = "30.0-64.0";
$monitor_vertrefresh{"EIZO FlexScan 9080i"} = "50.0-90.0";

$monitor_bandwidth{"ELSA GDM-17E40"} = "135";
$monitor_horizsync{"ELSA GDM-17E40"} = "29-82";
$monitor_vertrefresh{"ELSA GDM-17E40"} = "50-150";

$monitor_bandwidth{"ESCOM MONO-LCD-screen"} = "28";
$monitor_horizsync{"ESCOM MONO-LCD-screen"} = "30-36";
$monitor_vertrefresh{"ESCOM MONO-LCD-screen"} = "43-72";

$monitor_bandwidth{"Gateway 2000 CrystalScan 1776LE"} = "110";
$monitor_horizsync{"Gateway 2000 CrystalScan 1776LE"} = "30-64";
$monitor_vertrefresh{"Gateway 2000 CrystalScan 1776LE"} = "50-120";

$monitor_bandwidth{"Generic Monitor"} = "25.2";
$monitor_horizsync{"Generic Monitor"} = "31.5";
$monitor_vertrefresh{"Generic Monitor"} = "60";

$monitor_bandwidth{"HP 1280x1024-72Hz"} = "135";
$monitor_horizsync{"HP 1280x1024-72Hz"} = "78.125";
$monitor_vertrefresh{"HP 1280x1024-72Hz"} = "72.008";

$monitor_bandwidth{"Highscreen LE 1024"} = "45";
$monitor_horizsync{"Highscreen LE 1024"} = "31.4-31.6, 35.1-35.2, 35.5-35.6";
$monitor_vertrefresh{"Highscreen LE 1024"} = "50-87";

$monitor_bandwidth{"Hitachi SuperScan 20S"} = "100.0";
$monitor_horizsync{"Hitachi SuperScan 20S"} = "30-69";
$monitor_vertrefresh{"Hitachi SuperScan 20S"} = "50-100";

$monitor_bandwidth{"Hyundai hcm-421E"} = "110";
$monitor_horizsync{"Hyundai hcm-421E"} = "30-36";
$monitor_vertrefresh{"Hyundai hcm-421E"} = "43-72";

$monitor_bandwidth{"IDEK VisionMaster 17 (1)"} = "135";
$monitor_horizsync{"IDEK VisionMaster 17 (1)"} = "31.5-85.0";
$monitor_vertrefresh{"IDEK VisionMaster 17 (1)"} = "60-80";

$monitor_bandwidth{"IDEK VisionMaster 17 (2)"} = "135.0";
$monitor_horizsync{"IDEK VisionMaster 17 (2)"} = "23.5-86.0";
$monitor_vertrefresh{"IDEK VisionMaster 17 (2)"} = "50-120";

$monitor_bandwidth{"IDEK VisionMaster 17 (3)"} = "135";
$monitor_horizsync{"IDEK VisionMaster 17 (3)"} = "23.5-86";
$monitor_vertrefresh{"IDEK VisionMaster 17 (3)"} = "50-120";

$monitor_bandwidth{"IDEK Vision Master 17 (4)"} = "135.0";
$monitor_horizsync{"IDEK Vision Master 17 (4)"} = "23.5-86.0";
$monitor_vertrefresh{"IDEK Vision Master 17 (4)"} = "50-120";

$monitor_bandwidth{"IDEK Vision Master 17 (5)"} = "135.0";
$monitor_horizsync{"IDEK Vision Master 17 (5)"} = "23.5-86";
$monitor_vertrefresh{"IDEK Vision Master 17 (5)"} = "50-120";

$monitor_bandwidth{"Lite-On CM1414E"} = "45.0";
$monitor_horizsync{"Lite-On CM1414E"} = "30-40";
$monitor_vertrefresh{"Lite-On CM1414E"} = "40.0-87.0";

$monitor_bandwidth{"MAG Impression 17"} = "100.0";
$monitor_horizsync{"MAG Impression 17"}= "30.00-65.00";
$monitor_vertrefresh{"MAG Impression 17"} = "40.00-120.00";

$monitor_bandwidth{"MAG MX15F (1)"} = "100";
$monitor_horizsync{"MAG MX15F (1)"} = "30-65";
$monitor_vertrefresh{"MAG MX15F (1)"} = "50-120";

$monitor_bandwidth{"MAG MX15F (2)"} = "100.0";
$monitor_horizsync{"MAG MX15F (2)"} = "30.00-65.00";
$monitor_vertrefresh{"MAG MX15F (2)"} = "40.00-120.00";

$monitor_bandwidth{"MegaImage 17"} = "106";
$monitor_horizsync{"MegaImage 17"} = "30-64";
$monitor_vertrefresh{"MegaImage 17"} = "50-100";

$monitor_bandwidth{"NED 3D"} = "45.0";
$monitor_horizsync{"NED 3D"} = "15.5-38.0";
$monitor_vertrefresh{"NED 3D"} = "50.0-90.0";

$monitor_bandwidth{"NEC 4D"} = "75";
$monitor_horizsync{"NEC 4D"} = "30-57";
$monitor_vertrefresh{"NEC 4D"} = "50-90";

$monitor_bandwidth{"NEC MultiSync 4FGe"} = "80";
$monitor_horizsync{"NEC MultiSync 4FGe"} = "27-62";
$monitor_vertrefresh{"NEC MultiSync 4FGe"} = "55-90";

$monitor_bandwidth{"NEC 5FG"} = "135.0";
$monitor_horizsync{"NEC 5FG"} = "27-79";
$monitor_vertrefresh{"NEC 5FG"} = "55-90";

$monitor_bandwidth{"Nanao F340i-W"} = "75.0";
$monitor_horizsync{"Nanao F340i-W"} = "27-61";
$monitor_vertrefresh{"Nanao F340i-W"} = "55-90";

$monitor_bandwidth{"Nanao F550i"} = "100.0";
$monitor_horizsync{"Nanao F550i"} = "30-66";
$monitor_vertrefresh{"Nanao F550i"} = "40-130";

$monitor_bandwidth{"Nanao F550i-w"} = "80";
$monitor_horizsync{"Nanao F550i-w"} = "27-65";
$monitor_vertrefresh{"Nanao F550i-w"} = "55-90";

$monitor_bandwidth{"Nokia 445X"} = "200";
$monitor_horizsync{"Nokia 445X"} = "30-102";
$monitor_vertrefresh{"Nokia 445X"} = "50-120";

$monitor_bandwidth{"Nokia 447B (1)"} = "110";
$monitor_horizsync{"Nokia 447B (1)"} = "30-64";
$monitor_vertrefresh{"Nokia 447B (1)"} = "48-100";

$monitor_bandwidth{"Nokia 447B (2)"} = "110";
$monitor_horizsync{"Nokia 447B (2)"} = "30-64";
$monitor_vertrefresh{"Nokia 447B (2)"} = "48-100";

$monitor_bandwidth{"Philips 1764DC"} = "110";
$monitor_horizsync{"Philips 1764DC"} = "30-66";
$monitor_vertrefresh{"Philips 1764DC"} = "50-100";

$monitor_bandwidth{"PHILIPS 7BM749"} = "28";
$monitor_horizsync{"PHILIPS 7BM749"} = "30-33";
$monitor_vertrefresh{"PHILIPS 7BM749"} = "55-70";

$monitor_bandwidth{"Princeton Graphics Systems Ultra 17"} = "100";
$monitor_horizsync{"Princeton Graphics Systems Ultra 17"} = "30-64";
$monitor_vertrefresh{"Princeton Graphics Systems Ultra 17"} = "50-100";

$monitor_bandwidth{"Quantex TE1564M, Super View 1280"} = "75";
$monitor_horizsync{"Quantex TE1564M, Super View 1280"} = "30-64";
$monitor_vertrefresh{"Quantex TE1564M, Super View 1280"} = "50-100";

$monitor_bandwidth{"Relisys RE1564"} = "80.0";
$monitor_horizsync{"Relisys RE1564"} = "30-64";
$monitor_vertrefresh{"Relisys RE1564"} = "50-100";

$monitor_bandwidth{"Sampo alphascan-17"} = "95";
$monitor_horizsync{"Sampo alphascan-17"} = "30-77";
$monitor_vertrefresh{"Sampo alphascan-17"} = "20-105";

$monitor_bandwidth{"Sony CPD-1430"} = "77.0";
$monitor_horizsync{"Sony CPD-1430"} = "28.0-58.0";
$monitor_vertrefresh{"Sony CPD-1430"} = "55.0-110.0";

$monitor_bandwidth{"Sony Multiscan 15sf"} = "110";
$monitor_horizsync{"Sony Multiscan 15sf"} = "31.5-64";
$monitor_vertrefresh{"Sony Multiscan 15sf"} = "50-120";

$monitor_bandwidth{"Sony Multiscan 17se"} = "135";
$monitor_horizsync{"Sony Multiscan 17se"} = "31.5-82";
$monitor_vertrefresh{"Sony Multiscan 17se"} = "50-150";

$monitor_bandwidth{"TARGA TM 1710 D"} = "100";
$monitor_horizsync{"TARGA TM 1710 D"} = "30-65";
$monitor_vertrefresh{"TARGA TM 1710 D"} = "50-90";

$monitor_bandwidth{"TAXAN 875"} = "130";
$monitor_horizsync{"TAXAN 875"} = "30-78";
$monitor_vertrefresh{"TAXAN 875"} = "50-90";

$monitor_bandwidth{"Unisys-19"} = "110";
$monitor_horizsync{"Unisys-19"} = "57-65";
$monitor_vertrefresh{"Unisys-19"} = "55-65";

$monitor_bandwidth{"ViewSonic 17"} = "75.0";
$monitor_horizsync{"ViewSonic 17"} = "30-82";
$monitor_vertrefresh{"ViewSonic 17"} = "50-90";

$monitor_bandwidth{"ViewSonic 5e"} = "25.2";
$monitor_horizsync{"ViewSonic 5e"} = "30-60";
$monitor_vertrefresh{"ViewSonic 5e"} = "50-90";

$monitor_bandwidth{"ViewSonic 6"} = "80.0";
$monitor_horizsync{"ViewSonic 6"} = "30.00-57.00";
$monitor_vertrefresh{"ViewSonic 6"} = "43.00-70.04";

$monitor_bandwidth{"ViewSonic-7"} = "110";
$monitor_horizsync{"ViewSonic-7"} = "30.0-64.0";
$monitor_vertrefresh{"ViewSonic-7"} = "50.0-90.0";

$monitor_bandwidth{"IBM 8507"} = "45";
$monitor_horizsync{"IBM 8507"} = "31.5,35.5";
$monitor_vertrefresh{"IBM 8507"} = "70,60,87";

# Configure an X server -*-perl-*-

# To use as a stand alone X config tool:
# Files: x_config, vidmodes, monitors, dialog, flush.pl, misc
# $xserver = "SVGA" | "Mach32", etc
# $mousetype = mousetype;
# $fsmount = "";
# backup /etc/X11/XF86Config
# &config_x

require "vidmodes";
require "monitors";

$chipset = "";

sub _configure_x {

    local ( $ret, @lret, $tmp, $i, $j, @ltmp, @timings, $probecs, @probeclks );
    local ( $proberd, $probemem, $ramreduced, $msg, @options, $depth );
    local ( $driver, $ramdac, $clockchip, $maxclock );
    local ( %ltmp_to_vidmodes, @vmodes, $primary_mode, @chosen_modes );
    local ( $cachemem, $max_height, $max_width );
    local ( $chosen_vertrefresh, $chosen_bandwidth, $chosen_horizsync, $chosen_monitor );
    local ( $required_clock, $required_memory, $required_vertrefresh, $required_horizsync );
    local ( $virtual_line );
    @options = ();

    &init_chipsetlist;

    #### Clock Chip

    $clockchip = "";

    if ($xserver eq "S3" || $xserver eq "AGX") {
        if (&rhs_yesno("X configuration",
<<EOM
>
Does your video card have a programmable clock chip?
>
EOM
		       , 60)) {
            if (! &rhs_menu("X Configuration",
<<EOM
>
What kind of clock chip does your card have?
 (If you have a XGA-2 board, choose anything
to enable its programmable clock code.)
>
EOM
			    , 50, 11,
			    "ti3025", "",
			    "ch8391", "",
			    "icd2061a", "",
			    "ics9161a", "",
			    "dcs2834", "",
			    "sc11412", "",
			    "s3gendac", "",
			    "s3_sdac", "",
			    "ics5300", "",
			    "ics5342", "",
			    "ics2595", "")) {
		return 0;
	    }
            $clockchip = $dialog_result;
        }
    }

    #### RAMDAC

    $ramdac = "";

    if ($xserver eq "S3") {
        if (&rhs_yesno("X Configuration",
<<EOM
>
Do you have a SPEA Mercury card?
>
EOM
		       , 40)) {
            $options[@options] = "spea_mercury";
            $ramdac = "bt485";
        } else {
            if (&rhs_yesno("X configuration",
<<EOM
>
Do you have an STB Pegasus card?
>
EOM
			   , 40)) {
                $options[@options] = "stb_pegasus";
                $ramdac = "bt485";
            } else {
                if (&rhs_yesno("X configuration",
<<EOM
>
Do you have a Number Nine GXe level 10, 11, or 12 card?
>
EOM
			       , 40)) {
                    $options[@options] = "number_nine";
                    $ramdac = "bt485";
                }
            }
        }
    }
    
    #### Auto Probe

    $probecs = "unknown";
    $probemem = "unknown";
    $driver = "unknown";
    $proberd = "unknown";
    @probeclks = ();
    $maxclock = 0;

    if (&rhs_yesno("X Configuration",
<<EOM
>
Do you want to autoprobe?
>
Note that auto-probing is not infallible.  If you feel the
auto-probe determined your clocks incorrectly, you *may*
get a different result with another probe (believe it or
not!).
>
The probe results are saved in /tmp/probe.
If things go wrong, you might be able to find
out what happened by examining the results.
>
EOM
		   , 65)) {

        $proberd = "normal_dac";
        &rhs_infobox("X Configuration",
<<EOM
>
Probing...
>
EOM
                     , 20);

        open(FD, ">$fsmount/etc/X11/XF86Config");

        print FD
<<EOM
Section "Files"
EndSection
Section "ServerFlags"
EndSection
Section "Keyboard"
    Protocol "Standard"
EndSection
Section "Pointer"
    Protocol "Microsoft"
    Device "/dev/mouse"
EndSection
Section "Monitor"
    Identifier  "Generic Monitor"
    VendorName  "Unknown"
    ModelName   "Unknown"
    Bandwidth   25.2
    HorizSync   31.5
    VertRefresh 60
    ModeLine  "640x480" 25.175 640 672 768 800 480 490 492 525
    ModeLine  "640x480" 31.5   640 664 704 832 480 489 492 520
    ModeLine  "640x480" 28.322 640 680 720 864 480 488 491 521
EndSection
Section "Device"
    Identifier  "Generic"
    VendorName  "Unknown"
    BoardName   "Unknown"
EOM
    ;
	
        if ($clockchip ne "") {
            print FD "    ClockChip \"$clockchip\"\n";
        }
        if ($ramdac ne "") {
            print FD "  Ramdac \"$ramdac\"\n";
        }
        foreach $tmp (@options) {
            print FD "  Option \"$options[$tmp]\"\n";
        }

	print FD
<<EOM
EndSection
Section "Screen"
    Driver      "svga"
    Device      "Generic"
    Monitor     "Generic Monitor"
    Subsection "Display"
        Depth       8
        Modes       "640x480"
    EndSubsection
EndSection
Section "Screen"
    Driver      "vga16"
    Device      "Generic"
    Monitor     "Generic Monitor"
    Subsection "Display"
        Modes       "640x480"
    EndSubsection
EndSection
Section "Screen"
    Driver      "vga2"
    Device      "Generic"
    Monitor     "Generic Monitor"
    Subsection "Display"
        Modes       "640x480"
    EndSubsection
EndSection
Section "Screen"
    Driver    "accel"
    Device    "Generic"
    Monitor   "Generic Monitor"
    Subsection  "Display"
        Depth     8
        Modes     "640x480"
    EndSubsection
EndSection
EOM
    ;
        
        close FD;

	# These are really only useful during initial install
        symlink("$fsmount/usr/X11", "/usr/X11");
        symlink("$fsmount/etc/X11/XF86Config", "/etc/X11/XF86Config");

        open(SAVEERR, ">&STDERR");
        open(STDERR, ">$fsmount/tmp/probe");
        &invoke("$fsmount/usr/X11R6/bin/XF86_$xserver :1 -probeonly");
#       &invoke("/usr/X11R6/bin/XF86_$xserver -probeonly");
        close PROBE;
        close STDERR;
        open(STDERR, ">&SAVEERR");

        open(PROBE, "<$fsmount/tmp/probe");
        $ramreduced = 0;
        while (<PROBE>) {
            if (/chipset:  (.*)$/) {
                $probecs = $1;
            }
            if (/chipset driver: (.*)$/) {
                $driver = $1;
            }
            if (/videoram: (.*)k$/) {
                $probemem = $1;
            }
            if (/available videoram reduced by 1k to allow/) {
                $ramreduced = 1;
            }
            if (/clocks: +(.*)$/) {
                @ltmp = split(' ', $1);
                for ($i = 0; $i <= $#ltmp; $i++) {
                    $probeclks[@probeclks] = $ltmp[$i];
                }
            }
            if (/Maximum allowed dot-clock: (.*)MHz$/) {
                $maxclock = $1;
            }
	    if (/Ramdac type: (.*)$/) {
		$proberd = $1;
	    }
        }
	close PROBE;

        if ($ramreduced) {
            $probemem += $ramreduced;
        }
    }				# End Auto Probe

    #### Chipset

    if ($chipset eq "") {
        $ret = 1;
        if ($driver eq "unknown") {
            if ($probecs ne "unknown") {
                if (&rhs_yesno("X Configuration",
<<EOM
>
>Your chipset appears to be:
>    $probecs ($chipsetlist{$probecs})
>Is this correct?
>
EOM
			       , 60)) {
		    $ret = 0;
		}
            }

            if ($ret) {
                if (! &rhs_menua("X configuration",
<<EOM
>
Pick a chipset.
>
EOM
				 , 70, %chipsetlist)) {
		    return 0;
		}
                $chipset = $dialog_result;
            } else {
                $chipset = $probecs;
            }

        } else {
	    ## ????? Does this stuff reall belong here?
            if (! &rhs_yesno("X Configuration",
<<EOM
>
You appear to have a $driver chipset driver.
>
Is this correct?
>
EOM
			   , 60)) {
                if (! &rhs_menu("X Configuration",
<<EOM
>
Pick a chipset driver.
>
EOM
				, 40, 2,
				"s3_generic", "",
				"mmio_928", "")) {
		    return 0;
		}
		$driver = $dialog_result;
	    }
	    $chipset = $driver;
	}
    }

    #### Memory

    $ret = 1;
    if ($probemem ne "unknown") {
        if (&rhs_yesno("X Configuration",
<<EOM
>
Your card appears to have $probemem Kb of memory.
>
Is this correct?
>
EOM
		       , 60)) {
	    $ret = 0;
	}
    }

    if ($ret) {
        if (! &rhs_inputbox("X Configuration",
<<EOM
>
How much memory does your card have. (In kilobytes?)
>
EOM
			    , 60, "")) {
	    return 0;
	}
        $vidmem = $dialog_result;
    } else {
        $vidmem = $probemem;
    }

    #### RAMDAC

    if ($ramdac eq "") {
        $ret = 1;
        if ($proberd ne "unknown" && ($xserver eq "S3" ||
				      $xserver eq "AGX" ||
                                      $xserver eq "Mach32" ||
                                      $xserver eq "Mach8")) {
            $msg = ">\nYou appear to have a ";
            $msg .= "normal RAMDAC"             if ($proberd eq "normal_dac");
            $msg .= "AT&T 20C490 RAMDAC"        if ($proberd eq "att20c490");
            $msg .= "AT&T 20C505 RAMDAC"        if ($proberd eq "att20c505");
            $msg .= "AT&T 20C498 RAMDAC"        if ($proberd eq "att20c498");
            $msg .= "Sierra SC15025 RAMDAC"     if ($proberd eq "sc15025");
            $msg .= "BrookTree Bt485 RAMDAC"    if ($proberd eq "bt485");
            $msg .= "BrookTree Bt481 RAMDAC"    if ($proberd eq "bt481");
            $msg .= "BrookTree Bt482 RAMDAC"    if ($proberd eq "bt482");
	    $msg .= "STG1700 RAMDAC"            if ($proberd eq "stg1700");
	    $msg .= "S3 86C708 GENDAC"          if ($proberd eq "s3gendac");
	    $msg .= "S3 86C716 SDAC RAMDAC"     if ($proberd eq "s3_sdac");
            $msg .= "TI ViewPoint Ti3020 RAMDAC" if ($proberd eq "ti3020");
            $msg .= "TI ViewPoint Ti3025 RAMDAC" if ($proberd eq "ti3025");
	    $msg .= "Hercules Graphite Pro 2 DAC" if ($proberd eq "herc_dual_dac");
	    $msg .= "Hercules Graphite Pro 1 DAC" if ($proberd eq "herc_small_dac");

	    $msg .= "\n";
            if ($proberd eq "normal_dac") {
                $msg .=
<<EOM
>
The following RAMDACs do NOT count as "normal" RAMDACs:
The AT&T 20C49X, and 20C505; the Sierra SC15025 and SC15026;
the BrookTree Bt485, Bt481, Bt482; the STG1700; the
S3 86C708 GENDAC, S3 86C716 SDAC RAMDAC; 
the Hercules Graphite Pro 1 and 2 DAC;
and the TI ViewPoint Ti3020 and Ti3025.
EOM
    ;
            }
            $msg .= 
<<EOM
>
Is this correct?
>
EOM
    ;
            if (&rhs_yesno("X Configuration",
			   $msg, 60)) {
		$ret = 0;
	    }
        }

        if ($xserver eq "S3" || $xserver eq "Mach32" || 
	    $xserver eq "Mach8" || $xserver eq "AGX") {
            $ramdac = $proberd;
        } else {
            $ramdac = "";
        }

        if ($ret == 1 && ($xserver eq "S3" || $xserver eq "Mach32" ||
                          $xserver eq "Mach8" || $xserver eq "AGX")) {
            if (! &rhs_menu("X Configuration",
<<EOM
>
Pick your RAMDAC.
>
EOM
			    , 60, 15,

			    "normal_dac", "Normal RAMDAC",
			    "att20c490", "AT&T 20C490 RAMDAC",
			    "att20c505", "AT&T 20C505 RAMDAC",
			    "att20c498", "AT&T 20C498 RAMDAC",
			    "sc15025", "Sierra SC15025 RAMDAC",
			    "bt485", "BrookTree Bt485 RAMDAC",
			    "bt481", "BrookTree Bt481 RAMDAC",
			    "bt482", "BrookTree Bt482 RAMDAC",
			    "stg1700", "STG1700 RAMDAC",
			    "s3gendac", "S3 86C708 GENDAC",
			    "s3_sdac", "S3 86C716 SDAC RAMDAC",
			    "ti3020", "TI ViewPoint Ti3020 RAMDAC",
			    "ti3025", "TI ViewPoint Ti3025 RAMDAC",
			    "herc_dual_dac", "Hercules Graphite Pro 2 DAC",
			    "herc_small_dac", "Hercules Graphite Pro 1 DAC")) {
		return 0;
	    }
	    $ramdac = $dialog_result;
        }
    }

    #### Clock Chip

    if ($clockchip eq "") {
        $ret = 1;
        if (@probeclks > 0) {
            if (&rhs_yesno("X Configuration",
<<EOM
>
Your card appears to have the following clocks:
>
@probeclks
>
Is this correct?
>
EOM
			   , 70)) {
		$ret = 0;
	    }
        }

        if ($ret) {
            if (! &rhs_inputbox("X Configuration",
<<EOM
>
Enter your clocks, separated by spaces.
>
EOM
				, 70, "")) {
		return 0;
	    }
	    $_ = $dialog_result;
            @clocks = split;
        } else {
            @clocks = @probeclks;
        }
    }

    #### Monitor Specs

    if (! &rhs_menul("Monitor Specs",
<<EOM
>
Please choose a monitor.
>
If your monitor is not listed,
you can choose Generic Multisync, Generic Monitor, or
Custom.  If you select Custom you will be prompted for 
your monitors bandwidth, horizontal sync, and vertical refresh.
>
EOM
		     , 60, scalar(keys(%monitor_bandwidth)), sort keys(%monitor_bandwidth))) {
	return 0;
    }
    $chosen_monitor = $dialog_result;

    if ($chosen_monitor ne "Custom") {
	$chosen_bandwidth = $monitor_bandwidth{$chosen_monitor};
	$chosen_horizsync = $monitor_horizsync{$chosen_monitor};
	$chosen_vertrefresh = $monitor_vertrefresh{$chosen_monitor};
    } else {
	if (! &rhs_inputbox("Monitor Specs",
<<EOM
>
Please enter your monitor bandwidth in MHz.
>
EOM
			, 60, $monitor_bandwidth{$chosen_monitor})) {
	    return 0;
	}
	$chosen_bandwidth = $dialog_result;

	if (! &rhs_inputbox("Monitor Specs",
<<EOM
>
Please enter your monitor horizontal sync range.
>
This should be of the form XX-XXX for multisync monitors,
and XX,XX,... for fixed frequency monitors.
>
Values are in kHz.
>
EOM
			    , 60, $monitor_horizsync{$chosen_monitor})) {
	    return 0;
	}
	$chosen_horizsync = $dialog_result;

	if (! &rhs_inputbox("Monitor Specs",
<<EOM
>
Pleas enter you monitor vertival refresh range.
>
This should be of the form XX-XXX for multisync monitors,
and XX,XX,... for fixed frequency monitors.
>
Values are in Hz.
>
EOM
			    , 60, $monitor_vertrefresh{$chosen_monitor})) {
	    return 0;
	}
	$chosen_vertrefresh = $dialog_result;
    }

    #### Video Modes

    if ($xserver eq "Mono") {
        $depth = 1;
    } elsif ($xserver eq "VGA16") {
        $depth = 4;
    } else {
        $depth = 8;
    }

    if ($xserver eq "Mach32") {
	$cachemem = 256;
    } else {
	$cachemem = 0;
    }

    $vmode = 0;
    while ($vmode == 0) {
        &rhs_infobox("X Configuration",
<<EOM
>
Looking for usable video modes...
>
EOM
                     , 50);

	# Calculate Modes

        @ltmp = ();
	%ltmp_to_vidmodes = ();
      MODES:
	for ($j = 0; $j < @vidmodes; $j += 4) {
	    @timings = split(' ', $vidmodes[$j + 3]);
	    $required_clock = $vidmodes[$j+2];
	    $required_memory = ($timings[0]*$timings[4]*$depth)/(8*1024);
	    $required_vertrefresh = ($vidmodes[$j+2]*1000000)/($timings[3]*$timings[7]);
	    $required_horizsync = ($vidmodes[$j+2]*1000000)/($timings[3]*1000);
	    
	    # Check clock speed/bandwidth
	    if (($required_clock > $maxclock) ||
		($required_clock > $chosen_bandwidth)) {
		next MODES;
	    }

	    # Check memory
	    if ($required_memory > ($vidmem - $cachemem)) {
		next MODES;
	    }

	    # Check vertical refresh

	    # Check horizontal sync

	    if ($clockchip ne "") {
		# We have a programmable clock chip, we are set
		$ltmp[@ltmp] = $vidmodes[$j];
		$ltmp_to_vidmodes{$vidmodes[$j]} = $j;
	    } else {
		# OK, now just see if we have a close clock
		for ($i = 0; $i < @clocks; $i++) {
		    if (&abs($clocks[$i] - $vidmodes[$j+2]) < 2.0) {
			$ltmp[@ltmp] = $vidmodes[$j];
			$ltmp_to_vidmodes{$vidmodes[$j]} = $j;
			next MODES;
		    }
		}
	    }
	}

	# Choose Modes

	@dialog_result = ();
        if (! &rhs_checklistl("X Configuration",
<<EOM
>
The following modes may work with your hardware.
>
Select the modes you wish to include in XF86Config.
>
EOM
			      , 75, scalar(@ltmp), @ltmp)) {
	    return 0;
	}

	# Cycle through, displaying choices
	@chosen_modes = @dialog_result;
	@vmodes = ();

	if (scalar(@chosen_modes) == 0) {
	    next;
	}

	$max_width = 0;
	$max_height = 0;

	foreach $ent (@chosen_modes) {
	    $tmp = $ltmp_to_vidmodes{$ent};
	    $vmodes[@vmodes] = $tmp;

	    @timings = split(' ', $vidmodes[$tmp + 3]);

	    if ($timings[0] > $max_width) {
		$max_width = $timings[0];
	    }
	    if ($timings[4] > $max_height) {
		$max_height = $timings[4];
	    }

	    $msg = 
<<EOM
>
Data for mode:
>$ent
>
IMPORTANT: Check that VertRefresh and HorizSync are within your monitor spec!
>
EOM
    ;
	    $msg .=         ">             Required\t\tMonitor Spec\n";
	    $msg .= sprintf(">Geometry:    %d x %d\n", $timings[0], $timings[4]);
	    $msg .= sprintf(">Bandwidth:   %d MHz\t\t%s\n", $vidmodes[$tmp+2], $chosen_bandwidth);
	    $msg .= sprintf(">VertRefresh: %3.1f Hz\t\t%s\n",
			    ($vidmodes[$tmp+2]*1000000)/($timings[3]*$timings[7]), $chosen_vertrefresh);
	    $msg .= sprintf(">Memory:      %d K\n",
			    ($timings[0]*$timings[4]*$depth)/(8*1024));
	    $msg .= sprintf(">HorizSync:   %3.1f kHz\t\t%s\n",
			    ($vidmodes[$tmp+2]*1000000)/($timings[3]*1000), $chosen_horizsync);
	    $msg .= sprintf(">VertSync:    %3.1f kHz\n",
			    ($vidmodes[$tmp+2]*1000000)/($timings[7]*1000));
#	    &rhs_msgbox("X configuration", $msg, 75);
	}

	# Did that seem OK?
	if (&rhs_menul("X Configuration",
<<EOM
>
Choose primary video mode.  This will be the mode in which
X starts.  After X starts you can cycle through the selected
modes with Control-Alt-Keypad+.
>
 (Cancel to re-select modes)
>
EOM
		       , 75, scalar(@chosen_modes), @chosen_modes)) {
	    $vmode = 1;
	    $primary_mode = $ltmp_to_vidmodes{$dialog_result};
        }
    }				# While video modes not picked

    #### Misc Config Stuff

    if (($xserver eq "S3" || $xserver eq "P9000") &&
	($ramdac eq "bt485" || $ramdac eq "ti3020" || 
	 $ramdac eq "ti3025" || $ramdac eq "att20c505")) {
        if (&rhs_yesno("X Configuration",
<<EOM
>
Your card has the ability to generate a sync on green signal. Do you
want it to do so? (If you do not know, you do not want it to.)
>
EOM
		       , 60)) {
            $options[@options] = "sync_on_green";
        }
    }

    if ($xserver eq "Mach32") {
        if (&rhs_yesno("X Configuration",
<<EOM
>
Do you have an Intel GX Pro?
>
EOM
		       , 40)) {
            $options[@options] = "intel_gx";
        }
    }

    if ($chipset eq "et4000") {
        if (&rhs_yesno("X Configuration",
<<EOM
>
Do you have a Sigma Legend board?
>
EOM
		       , 50)) {
            $options[@options] = "legend";
        }
    }

    if ($chipset eq "pvga1") {
        if (&rhs_yesno("X Configuration",
<<EOM
>
Some cards with the PVGA1 chipset support 8 clocks, instead of the usual
4. Does your card support 8 clocks? (Say no if you are uncertain.)
>
EOM
			, 60)) {
            $options[@options] = "8clocks";
        }
    }

    if ($chipset eq "tvga8900b" || $chipset eq "tvga8900c") {
        if (&rhs_yesno("X Configuration",
<<EOM
>
Some newer boards using the Trident 8900B and 8900C chipsets support 16
clocks instead of the standard 8. Such boards will have a TCK9002 or
TCK9004 chip on them. Does your board support 16 clocks? (Say no if
you are uncertain.)
>
EOM
		       , 60)) {
            $options[@options] = "16clocks";
        }
    }

    if ($chipset =~ /^clgd/) {
	if (&rhs_yesno("X Configuration",
<<EOM
>
Cirrus cards with 2MB of videoram which is in the form of 512kx8 DRAMs (4
chips) rather than 256kx4 DRAMs (16 chips) must have the no_2mb_banksel
option set in the Xconfig file. Do you have such a card?
>
EOM
		       , 60)) {
            $options[@options] = "no_2mb_banksel";
        }
    }

    @dialog_result = ();
    if (&rhs_checklist("X Configuration",
<<EOM
>
There are a large number of configuration options that may (or may not) be
of use to some people. Select the ones you want.
>
DO NOT SELECT ANYTHING IF YOU ARE NOT ABSOLUTELY CERTAIN
YOU KNOW WHAT YOU ARE DOING.
>
 (Cancel will not cancel entire configuration.)
>
EOM
                       , 60, 16,
		       "hibit_low", "", 0,
		       "hibit_high", "", 0,
		       "swap_hibit", "", 0,
		       "probe_clocks", "", 0,
		       "noaccel", "", 0,
		       "fifo_conservative", "", 0,
		       "fifo_aggressive", "", 0,
		       "slow_dram", "", 0,
		       "fast_dram", "", 0,
		       "no_bitblt", "", 0,
		       "nomemaccess", "", 0,
		       "nolinear", "", 0,
		       "ti3020_curs", "", 0,
		       "no_ti3020_curs", "", 0,
		       "sw_cursor", "", 0,
		       "dac_8_bit", "", 0)) {
	@options = (@options, @dialog_result);
    }

    #### Write out Xconfig

    open(FD, ">$fsmount/etc/X11/XF86Config");
    print FD
<<EOM
# This XF86Config file generated by the Xconfigurator

# **********************************************************************
# Refer to the XF86Config(4/5) man page for details about the format of 
# this file.
# **********************************************************************

# **********************************************************************
# Files section.  This allows default font and rgb paths to be set
# **********************************************************************

Section "Files"

    RgbPath     "/usr/X11R6/lib/X11/rgb"

#
# Multiple FontPath entries are allowed (which are concatenated together),
# as well as specifying multiple comma-separated entries in one FontPath
# command (or a combination of both methods)
#

EOM
    ;

    if ( -d "/usr/X11R6/lib/X11/fonts/misc" ) {
        print FD "    FontPath      \"/usr/X11R6/lib/X11/fonts/misc/\"\n";
    }
    if ( -d "/usr/X11R6/lib/X11/fonts/Type1/" ) {
        print FD "    FontPath      \"/usr/X11R6/lib/X11/fonts/Type1/\"\n";
    }
    if ( -d "/usr/X11R6/lib/X11/fonts/Speedo/" ) {
        print FD "    FontPath      \"/usr/X11R6/lib/X11/fonts/Speedo/\"\n";
    }
    if ( -d "/usr/X11R6/lib/X11/fonts/75dpi/" ) {
        print FD "    FontPath      \"/usr/X11R6/lib/X11/fonts/75dpi/\"\n";
    }
    if ( -d "/usr/X11R6/lib/X11/fonts/100dpi/" ) {
        print FD "    FontPath      \"/usr/X11R6/lib/X11/fonts/100dpi/\"\n";
    }

    print FD
<<EOM

EndSection

# **********************************************************************
# Server flags section.
# **********************************************************************

Section "ServerFlags"

# Uncomment this to cause a core dump at the spot where a signal is 
# received.  This may leave the console in an unusable state, but may
# provide a better stack trace in the core dump to aid in debugging

#    NoTrapSignals

# Uncomment this to disable the <Crtl><Alt><BS> server abort sequence

#    DontZap

EndSection

# **********************************************************************
# Input devices
# **********************************************************************

# **********************************************************************
# Keyboard section
# **********************************************************************

Section "Keyboard"

    Protocol    "Standard"

# when using XQUEUE, comment out the above line, and uncomment the
# following line

#    Protocol   "Xqueue"

    AutoRepeat  500 5
    ServerNumLock

# Specifiy which keyboard LEDs can be user-controlled (eg, with xset(1))
#    Xleds      1 2 3

# To set the LeftAlt to Meta, RightAlt key to ModeShift, 
# RightCtl key to Compose, and ScrollLock key to ModeLock:

#    LeftAlt     Meta
#    RightAlt    ModeShift
#    RightCtl    Compose
#    ScrollLock  ModeLock

EndSection

# **********************************************************************
# Pointer section
# **********************************************************************

Section "Pointer"

EOM
    ;

    if ($mousetype eq "microsoft-serial") {
        print FD "    Protocol    \"Microsoft\"";
    } elsif ($mousetype eq "mousesystems-serial") {
        print FD "    Protocol    \"MouseSystems\"";
    } elsif ($mousetype eq "mouseman-serial") {
        print FD "    Protocol    \"MouseMan\"";
    } elsif ($mousetype eq "logitech-serial") {
        print FD "    Protocol    \"Logitech\"";
    } elsif ($mousetype eq "mmseries-serial") {
        print FD "    Protocol    \"MMSeries\"";
    } elsif ($mousetype eq "mmhittab-serial") {
        print FD "    Protocol    \"MMHitTab\"";
    } elsif ($mousetype eq "ps2-bus") {
        print FD "    Protocol    \"PS/2\"";
    } elsif ($mousetype =~ /-bus$/) {
        print FD "    Protocol    \"BusMouse\"";
    }
    print FD "\n    Device      \"/dev/mouse\"\n";

    print FD
<<EOM

# When using XQUEUE, comment out the above two lines, and uncomment
# the following line.

#    Protocol   "Xqueue"

# Baudrate and SampleRate are only for some Logitech mice

#    BaudRate   9600
#    SampleRate 150

# Emulate3Buttons is an option for 2-button Microsoft mice

EOM
    ;

    ## For some reason, mouse configuration is in here

    while (! &rhs_menu("X Configuration",
<<EOM
>
How many buttons are on your mouse?
>
 (Cancel will not cancel entire configuration)
>
EOM
		       , 60, 2, "Two", "", "Three", "")) {
    }
    $ret = $dialog_result;
    if ($ret eq "Three") {
	print FD "#";
    }
    print FD "    Emulate3Buttons\n";

    print FD
<<EOM

# ChordMiddle is an option for some 3-button Logitech mice

EOM
    ;

    if ($ret eq "Three") {
        if (! &rhs_yesno("X Configuration",
<<EOM
>
On some three button mice, the middle button sends left and right button
events when it is pressed.
>
Do you have such a mouse?
>
EOM
		       , 60)) {
	    print FD "#";
	}
    } else {
	print FD "#";
    }
    print FD "    ChordMiddle\n";

    print FD
<<EOM

# Some dual-protocol mice require DTR to be cleared to operate in
# MouseSystems mode.

EOM
    ;

    if ($mousetype eq "mousesystems-serial") {
        if (! &rhs_yesno("X Configuration",
<<EOM
>
Some dual-protocol mice require DTR to be cleared to operate in MouseSystems
mode.
>
Do you have such a mouse? (Answer "no" if you are not certain.)
>    
EOM
		       , 60)) {
	    print FD "#";
        }
    } else {
	print FD "#";
    }
    print FD "    ClearDTR\n";

    print FD
<<EOM

# Some dual-protocol mice require RTS to be cleared to operate in
# MouseSystems mode.

EOM
    ;

    if ($mousetype eq "mousesystems-serial") {
        if (! &rhs_yesno("X Configuration",
<<EOM
>
Some dual-protocol mice require RTS to be cleared to operate in MouseSystems
mode.
>
Do you have such a mouse? (Answer "no" if you are not certain.)
>    
EOM
		       , 60)) {
	    print FD "#";
        }
    } else {
	print FD "#";
    }
    print FD "    ClearRTS\n";

    print FD "\nEndSection\n";

    print FD
<<EOM

# **********************************************************************
# Graphics device section
# **********************************************************************

# Any number of graphics device sections may be present

Section "Device"
    Identifier  "Generic Video Card"
    VendorName  "Unknown"
    BoardName   "Unknown"
EOM
    ;

    print FD "    Chipset     \"$chipset\"\n";
    if ($ramdac ne "") {
	print FD "    Ramdac      \"$ramdac\"\n";
    }

    if ($clockchip eq "") {
        print FD "    Clocks      @clocks\n";
    } else {
        print FD "    ClockChip   \"$clockchip\"\n";
    }

    print FD "    VideoRam    $vidmem\n";

    for ($i = 0; $i < @options; $i++) {
        print FD "    Option      \"$options[$i]\"\n";
    }

    print FD
<<EOM
EndSection

# **********************************************************************
# Monitor section
# **********************************************************************

# Any number of monitor sections may be present

Section "Monitor"

    Identifier  "$chosen_monitor"
    VendorName  "Unknown"
    ModelName   "Unknown"

    Bandwidth    $chosen_bandwidth
    HorizSync    $chosen_horizsync
    VertRefresh  $chosen_vertrefresh
EOM
    ;

    foreach $tmp (@vmodes) {
	printf FD ("    ModeLine %-11s %3.3f  %s\n",
		   "\"$vidmodes[$tmp+1]\"",
		   $vidmodes[$tmp+2],
		   $vidmodes[$tmp+3]);
    }

    $tmp_modes = "\"$vidmodes[$primary_mode+1]\"";
    foreach $tmp (@vmodes) {
	if ($tmp != $primary_mode) {
	    $tmp_modes .= " \"$vidmodes[$tmp+1]\"";
	}
    }

    # This used to be necessary for the Mach32
    # We will apply to any card that can handle it
    # The only reason we can reset max_* directly is
    # because they are not used from here on out.
    $virtual_line = "# Virtual xres yres";
    if ($vidmem >= 1024) {
	if ($max_width < 1024) {
	    $max_width = 1024;
	}
	if ($max_height < 768) {
	    $max_height = 768;
	}
	$virtual_line =  "Virtual $max_width $max_height";
    }


    print FD
<<EOM
EndSection

# **********************************************************************
# Screen sections
# **********************************************************************

# The colour SVGA server

Section "Screen"
    Driver      "svga"
    Device      "Generic Video Card"
    Monitor     "$chosen_monitor"
    Subsection "Display"
        Depth       8
        Modes       $tmp_modes
        ViewPort    0 0
        $virtual_line
    EndSubsection
EndSection

# The 16-colour VGA server

Section "Screen"
    Driver      "vga16"
    Device      "Generic Video Card"
    Monitor     "$chosen_monitor"
    Subsection "Display"
        Modes       $tmp_modes
        ViewPort    0 0
        $virtual_line
    EndSubsection
EndSection

# The Mono server

Section "Screen"
    Driver      "vga2"
    Device      "Generic Video Card"
    Monitor     "$chosen_monitor"
    Subsection "Display"
        Modes       $tmp_modes
        ViewPort    0 0
        $virtual_line
    EndSubsection
EndSection

# The accelerated servers (S3, Mach32, Mach8, 8514, P9000, AGX, W32)

Section "Screen"
    Driver    "accel"
    Device    "Generic Video Card"
    Monitor   "$chosen_monitor"
    Subsection "Display"
        Depth    8
        Modes    $tmp_modes
        ViewPort 0 0
        $virtual_line
    EndSubsection
EndSection
EOM
    ;


    #### That is it

    close FD;

    #### DONE
    
    return 1;
}

sub init_chipsetlist {
    local ( $chipsetlist );

    $chipset = "";

    if ($xserver eq "VGA16") {
	%chipsetlist = ("vgawonder", "ATI VGA Wonder",
			"et4000", "Tseng et4000",
			"et4000w32", "Tseng et4000w32",
			"et4000w32i", "Tseng et4000w32i",
			"et4000w32p", "Tseng et4000w32p",
			"tvga8800cs", "Trident tvga8800cs",
			"tvga8900b", "Trident tvga8900b",
			"tvga8900c", "Trident tvga8900c",
			"tvga8900cl", "Trident tvga8900cl",
			"tvga9000", "Trident tvga9000",
			"cl6420", "Cirrus Logic 6420",
			"oti067", "OAK oti067",
			"oti077", "OAK oti077",
			"generic", "Generic VGA");
    } elsif ($xserver eq "SVGA") {
	%chipsetlist = (
			"vgawonder", "ATI VGA Wonder",
			"et3000", "Tseng et3000",
			"et4000", "Tseng et4000",
			"et4000w32", "Tseng et4000w32",
			"et4000w32i", "Tseng et4000w32i",
			"et4000w32p", "Tseng et4000w32p",
			"pvga1", "Western Digital pvga1",
			"wd90c00", "Western Digital wd90c00",
			"wd90c10", "Western Digital wd90c10",
			"wd90c30", "Western Digital wd90c30",
			"wd90c31", "Western Digital wd90c31",
			"wd90c33", "Western Digital wd90c33",
			"gvga", "Genoa gvga",
			"tvga8800cs", "Trident tvga8800cs",
			"tvga8900b", "Trident tvga8900b",
			"tvga8900c", "Trident tvga8900c",
			"tvga8900cl", "Trident tvga8900cl",
			"tvga9000", "Trident tvga9000",
			"ncr77c22", "NCR ncr77c22",
			"ncr77c22e", "NCR ncr77c22e",
			"clgd5420", "Cirrus Logic clgd5420",
			"clgd5422", "Cirrus Logic clgd5422",
			"clgd5424", "Cirrus Logic clgd5424",
			"clgd5426", "Cirrus Logic clgd5426",
			"clgd5428", "Cirrus Logic clgd5428",
			"clgd5429", "Cirrus Logic clgd5429",
			"clgd5430", "Cirrus Logic clgd5430",
			"clgd5434", "Cirrus Logic clgd5434",
			"clgd6205", "Cirrus Logic clgd6205",
			"clgd6215", "Cirrus Logic clgd6215",
			"clgd6225", "Cirrus Logic clgd6225",
			"clgd6235", "Cirrus Logic clgd6235",
			"cl6420", "Cirrus Logic 6420",
			"cpq_avga", "Compaq CPQ AVGA",
			"oti067", "OAK oti067",
			"oti077", "OAK oti077",
			"al2101", "Advance Logic",
			"mx", "MX",
			"video7", "Video7",
			"generic", "Generic");
    } elsif ($xserver eq "Mach8") {
	$chipset = "mach8";
    } elsif ( $xserver eq "Mach32") {
	$chipset = "mach32";
    } elsif ( $xserver eq "Mach64") {
	$chipset = "mach64";
    } elsif ( $xserver eq "P9000") {
	%chipsetlist = ("vipervlb", "Diamond Viper VLB",
			"viperpci", "Diamond Viper PCI",
			"orchidp9000", "Orchid P9000 and generics");
    } elsif ( $xserver eq "AGX") {
	%chipsetlist = ("agx-016", "",
			"agx-015", "",
			"agx-014", "",
			"agx-010", "",
			"xga-2", "",
			"xga-1", "");
    } elsif ( $xserver eq "W32") {
	%chipsetlist = (
			"et4000w32", "",
			"et4000w32i", "",
			"et4000w32i_rev_b", "",
			"et4000w32i_rev_c", "",
			"et4000w32p_rev_a", "",
			"et4000w32p_rev_b", "",
			"et4000w32p_rev_c", "",
			"et4000w32p_rev_d", "");
    } elsif ($xserver eq "8514") {
	$chipset = "ibm8514";
    } elsif ($xserver eq "S3") {
	%chipsetlist = ("s3_generic", "Standard IO driven server",
			"mmio_928",
			"Memory mapped IO driven server on 86C928 boards");
    } elsif ($xserver eq "Mono") {
	%chipsetlist = ("et3000", "Tseng et3000",
			"et4000", "Tseng et4000",
			"et4000w32", "Tseng et4000w32",
			"et4000w32i", "Tseng et4000w32i",
			"et4000w32p", "Tseng et4000w32p",
			"pvga1", "Western Digital pvga1",
			"wd90c00", "Western Digital wd90c00",
			"wd90c10", "Western Digital wd90c10",
			"wd90c30", "Western Digital wd90c30",
			"wd90c31", "Western Digital wd90c31",
			"wd90c33", "Western Digital wd90c33",
			"gvga", "Genoa gvga",
			"tvga8800cs", "Trident tvga8800cs",
			"tvga8900b", "Trident tvga8900b",
			"tvga8900c", "Trident tvga8900c",
			"tvga8900cl", "Trident tvga8900cl",
			"tvga9000", "Trident tvga9000",
			"ncr77c22", "NCR ncr77c22",
			"ncr77c22e", "NCR ncr77c22e",
			"cpq_avga", "Compaq CPQ AVGA",
			"oti067", "OAK oti067",
			"oti077", "OAK oti077",
			"oti087", "OAK oti087",
			"clgd5420", "Cirrus Logic clgd5420",
			"clgd5422", "Cirrus Logic clgd5422",
			"clgd5424", "Cirrus Logic clgd5424",
			"clgd5426", "Cirrus Logic clgd5426",
			"clgd5428", "Cirrus Logic clgd5428",
			"clgd5429", "Cirrus Logic clgd5429",
			"clgd5430", "Cirrus Logic clgd5430",
			"clgd5434", "Cirrus Logic clgd5434",
			"clgd6205", "Cirrus Logic clgd6205",
			"clgd6215", "Cirrus Logic clgd6215",
			"clgd6225", "Cirrus Logic clgd6225",
			"clgd6235", "Cirrus Logic clgd6235",
			"clgd6410", "Cirrus Logic clgd6420",
			"clgd6412", "Cirrus Logic clgd6420",
			"clgd6420", "Cirrus Logic clgd6420",
			"clgd6440", "Cirrus Logic clgd6420",
			"al2101", "Advance Logic 2101",
			"ali2301", "Advance Logic i2301",
			"ali2302", "Advance Logic i2302",
			"ali2308", "Advance Logic i2308",
			"ali2401", "Advance Logic i2401",
			"ct65520", "Chips and Technologies 65520",
			"ct65530", "Chips and Technologies 65530",
			"ct65540", "Chips and Technologies 65540",
			"ct65545", "Chips and Technologies 65545",
			"mx", "MX",
			"video7", "Video7",
			"generic", "Generic VGA",
			"hgc1280", "Hyundai hgc1280",
			"sigmalview", "Sigma LaserView",
			"apollo9", "Apollo 9",
			"hercules", "Hercules",
			"vgawonder", "ATI VGA Wonder");
    }

}

##############################
1;
# Xconfigurator tail -*-perl-*-

# Get args

( $xserver, $mousetype, $fsmount ) = @ARGV;
if ($xserver) {
    $short = 1
} else {
    $short = 0
}

$* = 1;
$scr_lines = 24;

if (! $fsmount && ! $short) {
    if (! &rhs_yesno("Red Hat XConfigurator",
<<EOM
>
Your /etc/X11/XF86Config is about to be deleted!!
Save it now!
>
If X is running this will *not* work!
>
Copyright (C) 1995 Red Hat Software, ACC Corp., Inc.
>
Continue?
>
EOM
		     , 70)) {
	exit(0);
    }
}

if (! $short) {
if (! &rhs_msgbox("Notice",
<<EOM
>
During X configuration, selecting Cancel at any time,
unless otherwise noted, will cancel the entire X configuration
process.
>
If you make an error, cancel and restart X configuration.
>
EOM
		  , 70)) {
    return 0;
}
}

if ( ! $xserver) {
    if (! &rhs_menu("X Configuration",
<<EOM
>
What kind of video card you you have?
> 
EOM
		    , 60, 10,
		    "VGA16", "Generic VGA",
		    "SVGA", "Generic SVGA",
		    "Mach8", "ATI Mach8 chipset",
		    "Mach32", "ATI Mach32 chipset",
		    "Mach64", "ATI Mach64 chipset",
		    "8514", "IBM 8514/A chipset",
		    "S3", "S3 chipset",
		    "AGX", "AGX/XGA",
		    "P9000", "Weitek Power 9000",
		    "W32", "ET4000/W32[i,p]",
		    "Mono", "Monochrome card")) {
	exit(0);
    }

    $xserver = $dialog_result;
}

unlink("$fsmount/etc/X11/X");
symlink("$fsmount/usr/X11R6/bin/XF86_$xserver", "$fsmount/etc/X11/X");

if (! -f "$fsmount/usr/X11R6/bin/XF86_$xserver") {
    &rhs_msgbox("Error",
<<EOM
>
/usr/X11R6/bin/XF86_$xserver does not exist!
>
The server must be present to configure it!  You probably
need to install the XF86_$xserver package.
>
EOM
		, 60);
    exit(1);
}

if (! $mousetype ) {
    if (! &rhs_menu("Mouse Configuration",
<<EOM
>
/dev/mouse should be a link to your mouse device.
If it is not, you will have to create it before
continuing.
>
What kind of mouse do you have?
> 
EOM
		    , 70, 10,
		    "microsoft-serial", "Microsoft compatible serial mouse",
		    "mousesystems-serial", "Mouse Systems serial mouse",
		    "mouseman-serial", "Logitech MouseMan",
		    "logitech-serial", "Logitech serial mouse",
		    "logitech-bus", "Logitech bus mouse",
		    "microsoft-bus", "Microsoft bus mouse",
		    "ps2-bus", "C&T 82C710 or PS/2 style (aux port)",
		    "mmseries-serial", "mmseries (?) serial mouse",
		    "mmhittab-serial", "Hitachi (?) serial (??) mouse",
		    "ati-bus", "ATI XL bus mouse")) {
	exit(0);
    }

    $mousetype = $dialog_result;

    if ($mousetype =~ /serial/) {
	while ($mouseport eq "") {
	    if (&rhs_menu("Mouse Configuration",
<<EOM
>
Which device (serial port) is your mouse connected to?
> 
EOM
			    , 60, 4,
			    "/dev/ttyS0", "COM1: under MS-DOS",
			    "/dev/ttyS1", "COM2: under MS-DOS",
			    "/dev/ttyS3", "COM3: under MS-DOS",
			    "/dev/ttyS4", "COM4: under MS-DOS")) {
		    $mouseport = $dialog_result;
		    $mouseport =~ s/.*\///;
	    }
	}
    } elsif ($mousetype eq "logitech-bus") {
	$mouseport = "logibm";
    } elsif ($mousetype eq "ati-bus") {
	$mouseport = "atibm";
    } elsif ($mousetype eq "microsoft-bus") {
	$mouseport = "inportbm";
    } elsif ($mousetype eq "ps2-bus") {
	$mouseport = "psaux";
    }
    
    unlink("/dev/mouse");
    symlink($mouseport, "/dev/mouse");
}

if (&_configure_x && !($short)) {
    unlink("$fsmount/etc/X");
    &rhs_msgbox("Notice",
<<EOM
>
X Configuration is finished.  You will find the configuration
file in /etc/X11/XF86Config.
>
Please note that probing is not always completely accurate, and
two consecutive probes do always give the same results!
In addition, some servers need additional memory for caching,
which reduces available memory for display, possible preventing
X from starting properly.  If this happens to you, try running
Xconfigurator again, or try running xf86config, which is another
X configuration program.
>
EOM
		, 70);
    exit(0);
} elsif (! $short) {
    unlink("$fsmount/etc/X");
    &rhs_msgbox("Error",
<<EOM
>
Something went wrong, or you cancelled the configuration.
>
What's left in /etc/X11/XF86Config is probably junk.
>
EOM
		, 60);
    exit(1);
}
