#!/usr/bin/perl
use strict 'vars';
use strict 'refs';
use vars (
'$AUTOLOAD','$CHANGE','$COMMAND_EDIT','$COMMAND_LINE','$CONFFILE','$DEBUG',
'$DEBUGBOX','$DEBUGBOXT','$DEBUG_LEVEL','$DECOR','$EDITWINDOW','$INIT_DECOR',
'$SETWINLIST','$COLOREDIT','$ERRLOG',
'$INIT_STYLE','$LINESREAD','$LINK_STYLE_DECOR','$MAXREADLINES','$MW','$SAVED','$SAVE_AS',
'$SETDECOR','$SETFONTS','$SETGLOBAL','$SETIMAGES','$SETSTYLE','$SLEEP','$STYLE',
'$SETBUTTONS','$VECTORTOOL','$YPAD1',
'$RWIDTH','$RHEIGHT',
'$bfont','$bfont2','$butbd','$butbg','$butpadx','$butpady','$butrel','$editorfont',
'$entbg','$buttextbg','$frabg','$fvwmContxt','$fvwmRcfile','$fvwm_conf_comm_dir',
'$fvwm_conf_dir','$fvwm_conf_user_dir','$getsub','$hbfont','$help_dir','$hfont',
'$htheight','$htwidth','$hwinId','$inFd','$indicatoron','$labbd','$labbg','$labfg',
'$labrel','$labtitlebg','$len','$m1','$m2','$pm','$menbg','$mfont','$oldpid','$oldpidfile',
'$outFd','$outs','$radbg','$recap','$recapture','$rgbfile','$scalbg','$scalhc',
'$state_file','$topbg','$topf','$troughcolor','$update','$writef_file','%CONFIG',
'%FARGS','%HISTORYLIST','%HISTORYLISTBOX','%HISTORYSHORT','%RCVARS','%STATE',
'@DecorOrder','@E','@EF','@F','@EFX','@FX','@GlobalOrder','@StyleOrder','@WINDOWLIST',
'@WINDOWSUB','@argv','@butcon','@butcon2','@butpack','@confs','@entcon','@fracon',
'@hbutcon','@labcon','@labcon2','@liscon','@menbutcon','@radcon','@scalcon',
'@textcon','@textcon2','@topcon','$COLOR','$COLORTOOL','$FONT','$DATE','$VERSION',
'$SELECT_COLORS','$applybg','$bitmapdir','$fontlistheight','$fvwmconfbin',
'$instlibdir',
'@imagepath','@labcont','$maxwidth','$small_font','$style_entry_width','@textpl',
'@libdirs','$IMGCONV','%HAVE','@PATHS','@WARN','*FOHAND'
);

#use vars ( '$end_variables',);
use lib "$ENV{HOME}/myperl5lib";
use lib "$ENV{HOME}/myperl5lib/i386-linux/";
#use lib "$ENV{HOME}/myperl5lib/i386-linux/5";
use Tk;
#use X11::Fvwm;
use Tk::Font;
use Carp;
# the following two lines are machine edited.
$VERSION='0.19';
$DATE='Wed, 15 Apr 1998 02:41:30 -0700';
sub movement;
sub execute_one_global;
sub set_global;
sub debug_box;
sub set_style;
sub set_decor;
sub set_fonts;
sub make_help_dismiss;
sub pad;
sub pad_list;
sub last_word;
sub button_style_ref;

use lib "/usr/lib/fvwmconf/lib";
use lib "/usr/local/lib/fvwmconf/lib";
use lib "/usr/lib/X11/fvwmconf/lib";

#INSTLIB  don't change this comment, it is  parsed by ./install program
use lib '/usr/lib/fvwmconf/lib';


use lib "$ENV{HOME}/.fvwmconf/lib";
# for the developer's use
use lib "$ENV{HOME}/fvwmconf/lib";
# moved this here, because IO::File often missing, and I put it in distribution..
#use IO::File;

use Var;
use MultiVar;
use PagerOnVar;
use MButtonStyle;
use MState;

#VINSTLIB  don't change this line, it parsed by ./install program
$instlibdir = '/usr/lib/fvwmconf';

# These are possible installation dirs to look for help files , etc.
@libdirs = ( 
             $instlibdir,
             "$ENV{HOME}/.fvwmconf",
             "$ENV{HOME}/fvwmconf",
              "/usr/local/lib/fvwmconf",
               "/usr/lib/X11/fvwmconf",
               "/usr/lib/fvwmconf"
);
@PATHS = split /:/,$ENV{PATH};

# put this up here so it is visible for compile time my's
$CONFIG{Global} = {};
$CONFIG{Decors} = {};
$CONFIG{Styles} = {};
$CONFIG{Menus} = {};
$CONFIG{Decors}{default} = {};
$CONFIG{Styles}{'*'} = {};



$DEBUG_LEVEL = 1;
###########################################################################

sub debug {
    my($level,$text) = @_;
    return unless $level <= $DEBUG_LEVEL;
    if (Exists $DEBUGBOXT ) {
	$DEBUGBOX->insert('end',"$text\n");
	$DEBUGBOX->see('end');
	return;
    }
    print STDERR "$text\n";

}

sub fcerror { debug (0,@_)};
###########################################################################
$MAXREADLINES = 10000;
$LINESREAD=0;
sub check_read {
    $LINESREAD++;
    return if $LINESREAD < $MAXREADLINES ;
    debug 10, "TOO MANY LINES READ, THIS IS JUST A SAFTEY";
    die "Too many lines read" ;
}

$fvwm_conf_user_dir = "$ENV{HOME}/.fvwmconf";
foreach ( '/usr/lib/X11/fvwmconf','/usr/local/lib/fvwmconf',
	 '/usr/lib/fvwmconf','/usr/local/lib/X11/fvwmconf',
	 '/usr/lib/X11R6/fvwmconf')  {
    $fvwm_conf_dir = $_ if -d $_;
}


if(not -e $fvwm_conf_user_dir) {
    print STDERR "Creating $ENV{HOME}/.fvwmconf ....\n";
    system "mkdir $ENV{HOME}/.fvwmconf" ;
    system "cp -r $fvwm_conf_dir/user/* $ENV{HOME}/.fvwmconf";
    system "cp -r $fvwm_conf_dir/user/.f* $ENV{HOME}/.fvwmconf";
}
$INIT_STYLE = "*";
$INIT_DECOR = "default";
$STYLE=$INIT_STYLE;
$DECOR=$INIT_DECOR;
$FONT = '';
$COLOR = '';
$SLEEP = 0.5;
$LINK_STYLE_DECOR = 'Yes';
@WINDOWLIST = ('SETGLOBAL','DEBUGBOXT','SETSTYLE','SETDECOR','SETFONTS',
	       'SETIMAGES','COLORTOOL','COLOREDIT','SETBUTTONS','VECTORTOOL');
@WINDOWSUB = (\&set_global,\&debug_box,\&set_style,\&set_decor,\&set_fonts,
	      \&set_images,\&color_tool,\&coledit,\&set_buttons,\&vector_tool);
#$end_variables = 'END_VARIABLES';

$style_entry_width = 15;
$fontlistheight = 15;
$butrel = 'raised';
$labrel = 'groove';
$butbd = '3';
$labbd = '3';
$butpadx = '0';
$butpady = '0';
$butbg = 'LightSteelblue';
$entbg = 'LightBlue';
$buttextbg = '#6270e0';
$menbg = 'skyblue';
$applybg = 'HotPink';
#$labbg = 'LightCyan';
$labtitlebg = 'grey';
$scalbg =  'CornflowerBlue';
$radbg = 'CornflowerBlue';
$labfg = 'black';
#$frabg = 'blue3';
$frabg = 'PaleTurquoise2';
$labbg = $frabg;
$topbg = 'PaleTurquoise2';
$scalhc = 'blue';
#$radht = '3';
$troughcolor = 'LightCyan';
$htwidth = '50';
$htheight = '20';
$indicatoron = 'yes';

$editorfont = 'fixed';
$bfont = 'fixed';
$bfont2 = 'fixed';
$hbfont = 'fixed';
$mfont = 'fixed';
$hfont ='fixed';
$small_font = 'fixed';

#$editorfont = '-adobe-helvetica-bold-r-normal--14-100-100-100-p-82-iso8859-1';
#$bfont = '-adobe-courier-bold-r-normal--17-120-100-100-m-100-iso8859-1';
#$bfont2 = '-adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1';
#$hbfont = '-adobe-courier-medium-r-normal--14-100-100-100-m-90-iso8859-1';
#$mfont = '-adobe-courier-bold-r-normal--14-140-75-75-m-90-iso8859-1';
#$hfont ='-adobe-courier-medium-r-normal--18-180-75-75-m-110-iso8859-1';
#$small_font = '-adobe-courier-bold-r-normal--12-120-75-75-m-70-iso8859-1';

$YPAD1 = '0';


%RCVARS = (
	   RgbFile => \$rgbfile,
	   Sleep => \$SLEEP,
	   LinkStyleDecor => \$LINK_STYLE_DECOR,
	   WriteFile => \$writef_file,
	   FvwmConfDir => \$fvwm_conf_dir,
	   FvwmConfUserDir => \$fvwm_conf_user_dir,
	   EditorFont => \$editorfont,
	   ButtonFont => \$bfont,
	   ButtonFont2 => \$bfont2,
	   HelpButtonFont => \$hbfont,
	   MenuFont => \$mfont,
	   HelpFont => \$hfont,
	   SmallFont => \$small_font
	   );
read_rc();

sub set_derived_file_names {
    $fvwmconfbin = "$fvwm_conf_dir/bin";
    $fvwm_conf_comm_dir = "$fvwm_conf_user_dir/configurations";
    $bitmapdir = "$fvwm_conf_dir/confimages";
    foreach (@libdirs) {
	if ( -e "$_/help" ) {
	    $help_dir = "$_/help";
	    return;
	}
    }
    warn "Can't find help directory";
}

$state_file = "statefile";
$CONFFILE = "new";
$writef_file = "$ENV{HOME}/.com.fvwm";
$rgbfile = "/usr/X11R6/lib/X11/rgb.txt";

sub  pads {('-padx',"$_[0]",'-pady',"$_[1]")}

sub setcons {

    @butcon = (-bd => $butbd, -font => $bfont, -relief => $butrel, 
	       -background => $butbg, pads($butpadx,$butpady) );
    @butcon2 = (pads(0,0),-bd => $butbd, -font => $bfont2, 
		-relief => $butrel, -background => $butbg);
    @labcon2 = (pads(0,0),-bd => $labbd, -font => $bfont2, 
		-relief => $labrel, -background => $labbg);
    
    @hbutcon = (pads(0,0),-bd => 1, -font => $hbfont, -relief => $butrel, 
		-background => $butbg);
    @menbutcon = (pads(0,0), -bd => $butbd, -font => $mfont, -relief => $butrel, 
		  -background => $menbg);
    @labcon = (pads(0,0),-bd => $labbd, -font => $bfont, -relief => $labrel, 
	       -background => $labbg, -fg => $labfg);
    @labcont =  (@labcon,-background=>$labtitlebg);
    @entcon = (-bd => $butbd, -font => $bfont, 
	       -background => $entbg);
    @radcon = (pads(0,0),-bd => $butbd, -font => $bfont, 
	       -background => $radbg, -indicatoron => $indicatoron);
    @fracon = (-bd => 1, -relief => 'flat', 
	       -background => $frabg);
    @liscon = ( -background => $frabg);
    @topcon = ( -background => $topbg);
    @textcon = ( -wrap => 'word', -exportselection => 1, -background => $entbg,
		-font => $editorfont,);
    @textcon2 = ( -wrap => 'word', -exportselection => 1, -background => $buttextbg, -font => $hbfont,);
#@textpl = ( -fill => 'both', -expand => 'y');
    @scalcon = ( -activebackground => $scalhc, -background => $scalbg, -troughcolor => $troughcolor);
}    


@butpack = (-fill=>'both');

@F = (-fill=>'both');
@E = (-expand=> '1');
@EF = (@E,@F);
@EFX = (-fill=>'x',-expand=>'1');
@FX = (-fill=>'x');
#######################################################

sub mysleep {
    my $time = shift;
    select undef, undef, undef, $time;
}

# see which support programs are available.
sub find_support_programs {
    my @progs = (
		 'xv','xlsfonts',
		 'ppmtogif','xpmtoppm','giftopnm','ppmtoxpm',
		 'convert',
		 'display',
		 'xpmroot',
		 'pixmap',
		 'xwininfo',
		 );
    my($pr,$pa,$f) ;
    foreach $pr (@progs) {
	$f = 0;
	foreach $pa (@PATHS) {
#	    debug 0,"$pa/$pr";
	    if (-e "$pa/$pr" ) {
		$HAVE{$pr} = 'Yes';
		$f = 1;
		last;
	    }
	}
	$HAVE{$pr} = '' unless $f == 1;
    }
#    my $st='';
#    foreach (keys %HAVE) {
#	$st .= "$_: $HAVE{$_}\n";
#    }
#    debug (0,$st);
}

sub get_root_size {
    if ($HAVE{xwininfo}) {
	my $st=`xwininfo -root`;
	($RWIDTH) = $st =~ /idth\:\s+(\d+)/;
	($RHEIGHT) = $st =~ /eight\:\s+(\d+)/;
#	debug 0, "$RWIDTH:$RHEIGHT";
    }
    else {
	message("You are missing the program 'xwininfo', check your PATH or have your sysadmin install it !");

    }
}


# Stuff from the Fvwm module
#Some code  taken from  X11::Fvwm by
#Randy J. Ray <randy@byz.org> .
#########################################################################
#    ($hwinId, @argv);
#    ($outFd, $inFd, $fvwmWinId, $fvwmContxt, $fvwmRcfile);

    @argv = @ARGV;

    @argv >= 5 || croak "$0 should only be run from fvwm2.\n";
    ($outFd, $inFd, $fvwmRcfile, $hwinId, $fvwmContxt) = 
        splice(@argv, 0, 5);
    $FARGS{fvwmWinId} = hex $hwinId;
    $FARGS{fvwmContext} = $fvwmContxt;
    $FARGS{fvwmRcfile} = $fvwmRcfile;
    $FARGS{argv} = [@argv];
    $outFd =~ /(\d+)/o; $outFd = $1;
    $inFd =~ /(\d+)/o; $inFd = $1;
    debug 4, "opening $outFd and $inFd";
#    $FARGS{OFD} = new IO::File ">&$outFd";
    open FOHAND, ">&$outFd";
##    $FARGS{IFD} = new IO::File "<&$inFd";
#    open IFD ,"<&$inFd";
#    $IFD = Tk::IO->new("<&$inFd");
    select (FOHAND);
    $| = 1;   # command buffering
    select (STDOUT);
#    $FARGS{OFD}->autoflush(1);
#    $FARGS{IFD}->autoflush(1);
#    debug 4,"opened $outFd and $inFd";
#    $handle = $FARGS{OFD};

#####################################################################
sub sendInfo
{
#    my $handle = shift;
    my ($winid, $data, $cont) = @_;

    my (@parts, $part);

#    $self->initModule unless ($self->{didInit});
    my     $number = @_;
debug 4,"got $number args to sendInfo";
    croak "Wrong # $number args to sendInfo" if (@_ < 2 || @_ > 3);
     
    $cont = 1 unless (defined $cont);
    @parts = split(/,/, $data);

    for $part (@parts)
    {
        $len = length $part;
#        $handle->print(pack("lla${len}l",
#                                 $winid, length $part, $part, 1));
       print  FOHAND (pack("lla${len}l",
                                 $winid, length $part, $part, 1));
    }
    unless ($cont)
    {
        $FARGS{sentEndPkt} = 1;
#        $handle->print(pack("lla3l", $winid, 3, 'Nop', 0));
        print FOHAND (pack("lla3l", $winid, 3, 'Nop', 0));
    }

    1;
}
############################################################
sub endModule
{
#    my $handle = shift;

    {
#        sendInfo($handle,0, "Nop", 0) unless ($FARGS{sentEndPkt});
        sendInfo(0, "Nop", 0) unless ($FARGS{sentEndPkt});
#        close $FARGS{IFD};
	close FOHAND
#        close $FARGS{OFD};
    }

    1;
}

########################################################################
# ignore lines beg. with #, use cont. char. \
sub read_a_line {
    no strict 'refs';
    my $HANDLE = shift;
    my ($line); 
    my $count = 0;
    for(;;){ 
	$line = '';
	for(;;) {
	    if (eof($HANDLE)){return undef}
	    $line .= <$HANDLE>;chomp $line;
	    check_read();
#	    debug 10,$line;
	    last unless $line =~ s/\\$//;
	}
	last unless  $line =~ /^\s*\#|^\s*$/;
	$count++;
	if (eof($HANDLE)){return undef}
    }
    $line =~ s/^\s+//; # leading spaces
    $line =~ s/\s+$//;  # trailing ...
#   return ($line);
    return ($count,$line);
}

#########################################################################
sub tilde_expand {
    my $string = shift;
    $string =~ s#\~/#$ENV{HOME}/#;
    return  $string;
}

#########################################################################
sub parse_line {
    my $line = shift;
    debug 10, "line: $line";
    my ($first,$rest)=(undef,undef);
    ($first,$rest)= $line =~ /^\s*(\w+)\s+(.*)$/;
    ($first) = $line =~ /^\s*(\w+)\s*$/ unless $first;
    return undef unless $first;
    return($first,$rest);
}
    
###########################################################################
sub read_state {
    my ($line,$var,$val);
        debug 10,"trying to open  $fvwm_conf_user_dir/$state_file";
    open STATEHAND , "<$fvwm_conf_user_dir/$state_file"   || return;
    debug 10,"opening $fvwm_conf_user_dir/$state_file";
    while(1==1) {
	if (eof STATEHAND) {close STATEHAND;return;}
	$line=read_a_line(STATEHAND);
	last unless defined $line  and not  $line eq '';
	($var,$val) = parse_line($line);
	debug 10, "STATE: $val:$var";
	$STATE{$var} = $val if defined $val and defined $var;
    }
    close STATEHAND;
}
###########################################################################
sub set_state {
my     %pairs = (DefaultConfig => \$CONFFILE,
	ButtonRelief => \$butrel,
	ButtonBorder => \$butbd,
	LabelRelief => \$labrel,
	ButtonBG => \$butbg,
	EntryBG => \$entbg,
	MenuBG => \$menbg ,
	LabelBG => \$labbg,
	RadioBG => \$radbg,
	FrameBG => \$frabg ,
	ToplevelBG => \$topbg,
	ButtonFont => \$bfont,
	ButtonFont2 => \$bfont2,
	HelpButtonFont => \$hbfont,
	MenuFont => \$mfont,
        HelpFont => \$hfont,
        EditorFont => \$editorfont,
        SmallFont => \$small_font,
);
  my ($key,@fonts,$fl);
  if ($HAVE{xlsfonts} ) {
      my @fonts = `xlsfonts`;
      foreach $key ( keys %pairs) {
	  if ( $key =~ /Font/) {
	      debug 0, $key;
	      $fl = 0;
	      foreach (@fonts) {
		  chomp;
		  if( defined $STATE{$key} and $STATE{$key} eq $_ ){$fl=1;last;}
	      }
	      if ($fl == 1) {
		  ${$pairs{$key}} = $STATE{$key} if defined $STATE{$key};
	      }
	      else {  ${$pairs{$key}} = 'fixed'; }
          }
          else {
	    ${$pairs{$key}} = $STATE{$key} if defined $STATE{$key};
          }
      }
  }
  else {
    foreach $key ( keys %pairs) {
	${$pairs{$key}} = $STATE{$key} if defined $STATE{$key};
     }
  }
}
###########################################################################

sub open_windows_from_state {
    my $i;
    for ($i=0;$i<@WINDOWLIST;$i++) {
	&{$WINDOWSUB[$i]} if $STATE{$WINDOWLIST[$i]} eq 'Open';
    }
}   
###########################################################################

sub what_was_open {
    my $i;
    for  ($i=0;$i<@WINDOWLIST;$i++) {
	$STATE{$WINDOWLIST[$i]} = 'Closed';
	$STATE{$WINDOWLIST[$i]} = 'Open' if Exists eval "\$$WINDOWLIST[$i]";
    }
}

###########################################################################
sub write_state {
    my ($key);
    what_was_open();
    open STATEHANDOUT , ">$fvwm_conf_user_dir/$state_file" ;
    print STATEHANDOUT "#   machine written file #\n";
    foreach $key (sort keys %STATE){
#	debug 1 , "Write STATE : $key  $STATE{$key}";	
	print STATEHANDOUT "$key  $STATE{$key}\n";	
    }
    close STATEHANDOUT;
}
################################################
sub read_rc {
    local *RCHAND;
    my ($one,$var,$val,@rckeys);
    @rckeys = keys %RCVARS;
#    print STDERR "here\n";
    if ( not open RCHAND, "$fvwm_conf_user_dir/.fvwmconfrc") {
	warn "Can't open $fvwm_conf_user_dir/.fvwmconfrc"; return
    }
    for(;;) {
	last if eof(RCHAND) ;
	$one = read_a_line(RCHAND);
#        print STDERR "read $one\n";
	last unless defined $one;
	($var,$val) = parse_line($one);
	next unless defined $var and $var ne '';
	foreach (@rckeys) {
#	    debug 0,"$var:  $_ and $val";
	    if ($var eq $_) {
#		debug 0,"success :::$var:  $_ and $val";
		${$RCVARS{$_}} = $val;
	        last;
	   }
        }
    }
}


########################################################################

sub read_all_variables {
    if (not open READHAND, "<$fvwm_conf_comm_dir/$CONFFILE" ) {
	debug 10,"couldn't open $fvwm_conf_comm_dir/$CONFFILE";
	return undef;
    }
    my ($line);
    set_saved();
    for(;;) {
	last if eof(READHAND);
	$line = read_a_line(READHAND);
#	last if $line eq $end_variables; # found separator
	if($line eq 'Styles') {read_styles(READHAND);next}
	if($line eq 'Decors') {read_decors(READHAND);next}
	if($line eq 'Global') {read_global(READHAND);next}
    }
    close READHAND;
}

#########################################################################
sub write_all_variables {
    open WRITEHAND, ">$fvwm_conf_comm_dir/$CONFFILE";
    write_styles(WRITEHAND);
    write_decors(WRITEHAND);
    write_global(WRITEHAND);
    close WRITEHAND;
}


#########################################################################
sub write_global {
    no strict 'refs';
    my $hand = shift;
    my $g = $CONFIG{Global};
    my ($var,$val,@hist);
    print $hand "Global\n";
    foreach $var (sort keys %$g) {
	@hist = $g->{$var}->get_store();
	foreach ( reverse @hist) {
	    print $hand "   $var $_\n";
	}		
    }
#	if($g->{$var}->is_set() ){
#	    print $hand "$var  ".$g->{$var}->get_value()."\n";
#	    debug 0, "write: $var  ".$g->{$var}->get_value();
#	}

}
#########################################################################
sub read_global {
    no strict 'refs';
    my $hand = shift;
    my $g = $CONFIG{Global};
    my ($var,$line,$val);
    for(;;) {
	last if eof($hand);
	$line  = read_a_line($hand);
	($var,$val) = parse_line($line) if defined $line;
#	debug 0, "$var: $val ";
	$g->{$var} = new  Var unless exists $g->{$var};
	$g->{$var}->set_value($val) if defined $val;
#	debug 0, "read: $var:  ".$g->{$var}->get_value(). "\n";
    }
}

#########################################################################
sub write_styles {
    no strict 'refs';
    my $hand = shift;
    my ($key,$var,@hist);
    my $s = $CONFIG{Styles};
    print $hand "Styles\n";
    foreach $key (sort keys %$s) {
	print $hand "  $key\n";
	foreach $var (sort keys %{$s->{$key}}) {
	    @hist = $s->{$key}->{$var}->get_store();
	    foreach (reverse @hist) {
		print $hand "   $var $_\n";
	    }	
#	    if($s->{$key}->{$var}->is_set) {
#		$val = $s->{$key}->{$var}->get_value();
#		print $hand "   $var $val\n";
#	    }
	}
	print $hand "  EndStyle\n";
    }
    print $hand "EndStyles\n";  
}
  
###########################################################################
sub read_styles {
    my $hand = shift;
    my ($style,$in,$svar,$sval);
    no strict 'refs';
    return if eof($hand);
    $style  =  read_a_line($hand);
    create_style_variables($style);
    initialize_style($style) if $style eq '*';
    return if $style eq 'EndStyles';
    for(;;) {
	return if eof($hand);
	$in = read_a_line($hand);
	return if $in eq 'EndStyles';
	if ($in eq 'EndStyle') {
	    return if eof($hand);
	    $style = read_a_line($hand) ; 
	    return if $style eq 'EndStyles';
	    create_style_variables($style);
	    return if eof($hand);
	    $in = read_a_line($hand) ;
	}
	($svar,$sval) = parse_line($in);
	if( not $svar) {fcerror "in style line in $CONFFILE";next;}
#	debug 0, "style $style: $svar: $sval";
	if (exists $CONFIG{Styles}{$style}->{$svar}) {
	    $CONFIG{Styles}{$style}->{$svar}->set_value($sval);
	}
	else {
	    debug 0, "Bad style variable: $CONFFILE:$style:$svar:$sval";
	}
    }
}
###########################################################################


sub write_decors {
    no strict 'refs';
    my $hand = shift;
    my ($key,$var,$val,@hist);
    my $d = $CONFIG{Decors};
    print $hand "Decors\n";
    foreach $key (sort keys %$d) {
	print $hand "  $key\n";
	foreach $var (sort keys %{$d->{$key}}) {
	    if ($var eq 'Buttons'){
		write_buttons($hand,$d->{$key}->{Buttons});
	    }
	    else {
		@hist = $d->{$key}->{$var}->get_store();
		foreach (reverse @hist) {
		    print $hand "   $var $_\n";
		}
	    }		
	}
	print $hand "  EndDecor\n";
    }
    print $hand "EndDecors\n";  
}  
###########################################################################
sub read_decors {
    my $hand = shift;
    my ($decor,$in,$dvar,$dval);
    no strict 'refs';
    return if eof($hand);
    $decor  =  read_a_line($hand);
    return if $decor eq 'EndDecors';
    create_decor_variables($decor);
#    debug 0, "create one $decor";
    for(;;) {
	return if eof($hand);
	$in = read_a_line($hand);
	return if $in eq 'EndDecors';
	if ($in eq 'EndDecor') {
	    return if eof($hand);
	    $in = read_a_line($hand) ;
	    for(;;) {
		return if $in eq 'EndDecors';
		create_decor_variables($in);
		$decor = $in;
#		debug 0, "create two $in";
		return if eof($hand);
		$in = read_a_line($hand) ;
		last unless $in eq 'EndDecor';
		return if eof($hand);
		$in = read_a_line($hand) ;
	    }
	}
	($dvar,$dval) = parse_line($in);
	if( not $dvar) {fcerror "in decor line in $CONFFILE";next;}
#	debug 0, "decor:'$decor'  var:'$dvar'";
	if($dvar eq 'ButtonStyle' ) {
	    read_buttons($hand,$CONFIG{Decors}{$decor}->{Buttons});
	}
	elsif (exists $CONFIG{Decors}{$decor}->{$dvar}) {
	    $CONFIG{Decors}{$decor}->{$dvar}->set_value($dval);
	}
	else {
	    debug 0, "FvwmConf: Bad decor variable: $dvar";
	}
    }
}


###########################################################################

sub write_buttons {
    no strict 'refs';
    my($hand,$ref) = @_;

    my (@hist,$var,$val);
    my(@buts) = $ref->get_styles();
    foreach (@buts) {
	print $hand "   ButtonStyle\n";
	foreach $var  (keys %$_) {
#	    debug 0, "$var";
	    @hist = $_->{$var}->get_store();
	    foreach $val (reverse @hist) {
		print $hand "     $var $val\n";
	    }
	}
    }
    print $hand "   EndButtonStyles\n";
}

###########################################################################
sub read_buttons {
    my($hand,$ref) = @_;
    no strict 'refs';
    my($butref,$var,$val,$line);
    $butref = $ref->style(0);
    for(;;) {
	return if eof $hand;
	$line = read_a_line $hand;
	if($line eq 'ButtonStyle') {
	    $butref = $ref->insert_style();
	}
	elsif ($line eq 'EndButtonStyles') {
	    return;
	}
	else {
	    ($var,$val) = parse_line($line);
	    if( not $var) {fcerror "in decor buttonstyle line in $CONFFILE";next;}
	    elsif (exists $butref->{$var}) {
		$butref->{$var}->set_value($val);
	    }
	    else {
		debug 0, "FvwmConf: Bad decor buttonstyle variable: $var";
	    }
	}
    }
}
###########################################################################

sub clean_tmp_directory {
    system "rm -f $fvwm_conf_user_dir/tmp/*";
}





##########################################################
sub send_command {
    my $command = shift;
#    debug 1, "send1: $command";
#    $handle->sendInfo(0, "$command"); 
sendInfo(0, "$command")
}
##########################################################

sub debug_box {
    my $file = shift;
    $DEBUGBOXT->destroy if Exists($DEBUGBOX);
    $DEBUGBOXT = $MW->Toplevel(@topcon);
    $DEBUGBOXT->title('Debug Box');
    my $w = $DEBUGBOXT ;
    my $f = make_help_dismiss($w,'NoHelp');
    $DEBUGBOX = $w->Text(@textcon);
    my $dt = $DEBUGBOX;
    $f->Button(@butcon,-text=>'Clear' , -command =>
sub { $dt->delete('0.0','end');})->pack;
    $DEBUGBOX->pack(@EF);
    debug 10, "Debugging information will appear here.";
}


##########################################################
sub destroy_most {
    my $one;
    foreach $one ($SETIMAGES,$SETFONTS,
		  $SELECT_COLORS,$SETGLOBAL,$SETDECOR,$SETSTYLE )  {
	$one->destroy if Exists($one);
    }
}

##########################################################
# be careful, if you call this , then the routines below
# will not be able to clear individual styles.
sub clear_config {
    my ($k,$k1);
    my $s = $CONFIG{Styles};
    my $d = $CONFIG{Decors};
    reset_styles();
    reset_decors();
    foreach $k (keys %$s){
	delete $s->{$k};
    }
    foreach $k (keys %$d){

#all this to preserve default is really unneccessary
	send_command("DestroyDecor  $k");
	if ($k eq 'default') {
	    foreach $k1 (keys %{$d->{'default'}} ) {
		$d->{'default'}->{$k1}->reset;
	    }
	}
	else {
	    delete $CONFIG{Decors}->{$k};
	}
    }
    foreach $k (keys %{$CONFIG{Global}}){
	 $CONFIG{Global}->{$k}->reset;
    }    
    
}

sub reset_decors {
    foreach (keys %{$CONFIG{Decors}}) {
	reset_decor($_);
    }
}

sub reset_decor  {
    my $decor = $DECOR;
    $decor = shift if @_;
    my $one;
    my @list = (
		"AddToDecor \"$decor\"  BorderStyle Simple",
		"AddToDecor \"$decor\" ButtonStyle Reset",
		"AddToDecor \"$decor\" TitleStyle Simple",
		);
    foreach $one (@list) {send_command $one}
}

# a little anyway
sub reset_fvwm {
    my $one;
    my @list = (
		'BorderStyle Simple',
		'Exec xsetroot -solid grey',
		'ButtonStyle Reset',
	       'Style "*"  Slippery, Title',
		'Style "*" NoIcon',
		);
		
    foreach $one (@list) {send_command $one}
}

sub reset_styles {
    foreach (keys %{$CONFIG{Styles}}) {
	reset_style($_);
    }
}
 

sub reset_style {
    my $style = $STYLE;
    $style = shift if @_;
    my $s = $CONFIG{Styles}->{$style};
    my $one;
    my @list = (
#		qq#Style "$style" NoIcon#
# don't do this, it takes icon away from rclock , for instance.
		);
    foreach $one (@list) {send_command $one}
# Try this, only clear Icon if it was explicily set by FvwmConf
    if($s->{IconPixmap}->get_value()) {
	send_command qq#Style "$style" NoIcon#;
    }

}   

###########################################################################
sub set_unsaved {
    $SAVED = 'no';
}
sub set_saved {
    $SAVED = 'yes';
}
sub is_saved {
    if ($SAVED eq 'yes') {return 'yes'};
    return '';
}


########################################################
sub recapture {
    send_command 'Recapture';
}
sub update_decor {
    my $decor = shift;
    if (defined $decor) {
	send_command "UpdateDecor $decor";
    }
    else {
	send_command "UpdateDecor";
    }
}
sub beep {
    send_command 'Beep';
}

#########################################################################

sub create_global_variables { 

    my $g = $CONFIG{Global};
    $g->{RootBackground}  = new Var;
    $g->{RootBackground}->set_prefix('Exec');
    $g->{RootBackground}-> set_panel_widget_class('Entry');
    $g->{RootBackground}->set_name_title('RootBackground','Root Background Color');
    $g->{RootBackground}->set_store_size(50);

    $g->{RootBackground}->set_name_title('RootBackground','Root Background');

    $g->{ClickTime} = new Var;
    $g->{ClickTime}-> set_panel_widget_class('Entry');
    $g->{ClickTime}->set_prefix('ClickTime');
    $g->{ClickTime}->set_name_title('ClickTime','Double Click Timeout');


    $g->{OpaqueMoveSize} = new Var;
    $g->{OpaqueMoveSize}-> set_panel_widget_class('Radiobutton');
    $g->{OpaqueMoveSize}->set_prefix('OpaqueMoveSize');

    $g->{ClickFocusRaise} = new Var;
    $g->{ClickFocusRaise}-> set_panel_widget_class('Radiobutton');
    $g->{ClickFocusRaise}->set_prefix('GlobalOpts');

    $g->{ClickPasses} = new Var;
    $g->{ClickPasses}-> set_panel_widget_class('Radiobutton');
    $g->{ClickPasses}->set_prefix('GlobalOpts');

    $g->{MouseFocusRaise} = new Var;
    $g->{MouseFocusRaise}-> set_panel_widget_class('Radiobutton');
    $g->{MouseFocusRaise}->set_prefix('GlobalOpts');


    $g->{SmartPlacementSmart} = new Var;
    $g->{SmartPlacementSmart}-> set_panel_widget_class('Radiobutton');
    $g->{SmartPlacementSmart}->set_prefix('GlobalOpts');

    $g->{ColorMapFocus} = new Var;
    $g->{ColorMapFocus}-> set_panel_widget_class('Radiobutton');
    $g->{ColorMapFocus}->set_prefix('ColorMapFocus');

    $g->{DeskTopSizex} = new MultiVar;
    $g->{DeskTopSizex}-> set_panel_widget_class('Entry');
    $g->{DeskTopSizex}->set_name_title('DeskTopSizex','DeskTop Size x');
    $g->{DeskTopSizey} = new MultiVar;
    $g->{DeskTopSizey}-> set_panel_widget_class('Entry');
    $g->{DeskTopSizex}->set_prefix('DeskTopSize');
    $g->{DeskTopSizex}->set_fellows($g->{DeskTopSizex},$g->{DeskTopSizey});
    $g->{DeskTopSizey}->set_name_title('DeskTopSizey','DeskTop Size y');

    $g->{EdgeScrollx} = new MultiVar;
    $g->{EdgeScrollx}-> set_panel_widget_class('Scale');
    $g->{EdgeScrolly} = new MultiVar;
    $g->{EdgeScrolly}-> set_panel_widget_class('Scale');
    $g->{EdgeScrollx}->set_prefix('EdgeScroll');
    $g->{EdgeScrollx}->set_fellows($g->{EdgeScrollx},$g->{EdgeScrolly});

    $g->{EdgeTime} = new MultiVar('150');
    $g->{EdgeTime}-> set_panel_widget_class('Entry');
    $g->{EdgeTime}->set_name_title('EdgeTime','Edge Resistance Time');
    $g->{EdgePixels} = new MultiVar('100');
    $g->{EdgePixels}-> set_panel_widget_class('Entry');
    $g->{EdgeTime}->set_prefix('EdgeResistance');
    $g->{EdgeTime}->set_fellows($g->{EdgeTime},$g->{EdgePixels});
    $g->{EdgePixels}->set_name_title('EdgePixels','Edge Resistance Pixels');

    $g->{MenuFore} = new MultiVar('Black');
    $g->{MenuFore}->set_prefix('MenuStyle');
    $g->{MenuFore}-> set_panel_widget_class('Entry');
    $g->{MenuFore}->set_name_title('MenuFore','Menu Foreground Color');
    $g->{MenuBack} = new MultiVar('Lightblue');
    $g->{MenuBack}-> set_panel_widget_class('Entry');
    $g->{MenuBack}->set_name_title('MenuBack','Menu Background Color');
    $g->{MenuShade} = new MultiVar('grey');
    $g->{MenuShade}-> set_panel_widget_class('Entry');
    $g->{MenuShade}->set_name_title('MenuShade','Menu Shade Color');
    $g->{MenuFont} = new MultiVar('fixed');
    $g->{MenuFont}-> set_panel_widget_class('Entry');
    $g->{MenuFont}->set_name_title('MenuFont','Menu Font');
    $g->{MenuStyle} = new MultiVar('fvwm');
    $g->{MenuStyle}-> set_panel_widget_class('Radiobutton');
    $g->{MenuFore}->set_fellows($g->{MenuFore},$g->{MenuBack},$g->{MenuShade},
				$g->{MenuFont},$g->{MenuStyle});

    $g->{IconFont} = new Var();
    $g->{IconFont}->set_prefix('IconFont');
    $g->{IconFont}-> set_panel_widget_class('Entry');
    $g->{IconFont}->set_name_title('IconFont','Icon Font');

    $g->{PagerFore} = new Var();
    $g->{PagerFore}->set_prefix('*FvwmPagerFore');
    $g->{PagerFore}->set_name_title('PagerFore','Pager Fore Color');
    $g->{PagerFore}-> set_panel_widget_class('Entry');

    $g->{PagerBack} = new Var();
    $g->{PagerBack}->set_prefix('*FvwmPagerBack');
    $g->{PagerBack}->set_name_title('PagerBack','Pager Back Color');
    $g->{PagerBack}-> set_panel_widget_class('Entry');

    $g->{WinListFore} = new Var();
    $g->{WinListFore}->set_prefix('*FvwmWinListFore');
    $g->{WinListFore}->set_name_title('WinListFore','WinList Fore');
    $g->{WinListFore}-> set_panel_widget_class('Entry');

    $g->{WinListBack} = new Var();
    $g->{WinListBack}->set_prefix('*FvwmWinListBack');
    $g->{WinListBack}->set_name_title('WinListBack','WinList Back');
    $g->{WinListBack}-> set_panel_widget_class('Entry');

    $g->{WinListFont} = new Var();
    $g->{WinListFont}->set_prefix('*FvwmWinListFont');
    $g->{WinListFont}->set_name_title('WinListFont','WinList Font');
    $g->{WinListFont}-> set_panel_widget_class('Entry');

=pod
    $g->{WinList} = new Var();
    $g->{WinList}->set_prefix('*FvwmWinList');
    $g->{WinList}->set_name_title('WinList','WinList');
    $g->{WinList}-> set_panel_widget_class('Entry');
=cut

    $g->{PagerDeskTopScale} = new Var();
    $g->{PagerDeskTopScale}->set_prefix('*FvwmPagerDeskTopScale');
    $g->{PagerDeskTopScale}->set_name_title('PagerDeskTopScale','Pager Desk Top Scale');
    $g->{PagerDeskTopScale}-> set_panel_widget_class('Entry');

    $g->{PagerHilight} = new Var();
    $g->{PagerHilight}->set_prefix('*FvwmPagerHilight');
    $g->{PagerHilight}->set_name_title('PagerHilight','Pager Hilight Color');
    $g->{PagerHilight}-> set_panel_widget_class('Entry');

    $g->{PagerOn} = new PagerOnVar();
    $g->{PagerOn}-> set_panel_widget_class('Radiobutton');


#    foreach  (keys %$g) {
#	$g->{$_}->stack_off unless $g->{$_}->get_panel_widget_class eq 'Entry';
#    }

######
# This will be the order of execution. Here it serves mostly
# to prevent trying to exeute other fellows in MultiVars

    @GlobalOrder= qw( RootBackground IconFont ClickTime OpaqueMoveSize
      ClickFocusRaise ClickPasses MouseFocusRaise ColorMapFocus SmartPlacementSmart
      DeskTopSizex   EdgeScrollx  EdgeTime MenuFore PagerFore PagerBack
     PagerDeskTopScale  PagerHilight  PagerOn WinListFore WinListBack WinListFont
		     );

}

sub create_decor_variables {

    my $decor = $DECOR;
    $decor = shift if @_;
    $CONFIG{Decors}{$decor}={};
    my $d = $CONFIG{Decors}{$decor};
    
    $d->{Justification} = new Var('Centered');
    $d->{Justification}->set_prefix('TitleStyle');
    $d->{Justification}->set_panel_widget_class('Radiobutton');

    $d->{WindowFont} = new Var('fixed');
    $d->{WindowFont}->set_prefix('WindowFont');
    $d->{WindowFont}->set_panel_widget_class('Entry');
    $d->{WindowFont}->set_name_title('D:WindowFont','Window Font');

    $d->{TitleHeight} = new Var();
    $d->{TitleHeight}->set_prefix('TitleStyle Height');
    $d->{TitleHeight}->set_panel_widget_class('Entry');
    $d->{TitleHeight}->set_name_title('D:TitleHeight','Title Height');

    $d->{BorderActivePixmap} = new Var();
    $d->{BorderActivePixmap}->
	set_prefix('BorderStyle Active');
    $d->{BorderActivePixmap}->set_panel_widget_class('Entry');
    $d->{BorderActivePixmap}->set_name_title('D:BorderActivePixmap','Active Border Pixmap');

    $d->{BorderInactivePixmap} = new Var();
    $d->{BorderInactivePixmap}->
	set_prefix('BorderStyle Inactive');
    $d->{BorderInactivePixmap}->set_panel_widget_class('Entry');
    $d->{BorderInactivePixmap}->set_name_title('D:BorderInactivePixmap','Inactive Border Pixmap');

    $d->{HiddenHandles} = new Var();
    $d->{HiddenHandles}->
	set_prefix('BorderStyle -- ');
    $d->{HiddenHandles}->set_panel_widget_class('Radiobutton');
    $d->{HiddenHandles}->set_name_title('D:HiddenHandles','Hidden Handles');

    $d->{NoInset} = new Var();
    $d->{NoInset}->
	set_prefix('BorderStyle -- ');
    $d->{NoInset}->set_panel_widget_class('Radiobutton');
    $d->{NoInset}->set_name_title('D:NoInset','No Inset');


    $d->{TitleActiveUp} = new Var();
    $d->{TitleActiveUp}->
	set_prefix('TitleStyle  ActiveUp ');
    $d->{TitleActiveUp}->set_panel_widget_class('Entry');
    $d->{TitleActiveUp}->set_name_title('D:TitleActiveUp','Active-Up  Title Color/Pixmap');

    $d->{TitleActiveDown} = new Var();
    $d->{TitleActiveDown}->
	set_prefix('TitleStyle  ActiveDown ');
    $d->{TitleActiveDown}->set_panel_widget_class('Entry');
    $d->{TitleActiveDown}->set_name_title('D:TitleActiveDown','Active-Down  Title Color/Pixmap');

    $d->{TitleInactive} = new Var();
    $d->{TitleInactive}->
	set_prefix('TitleStyle Inactive ');
    $d->{TitleInactive}->set_panel_widget_class('Entry');
    $d->{TitleInactive}->set_name_title('D:TitleInactive','Inactive  Title Color/Pixmap');

    $d->{TitleReliefAUp } = new Var();
    $d->{TitleReliefAUp }->set_prefix('TitleStyle ActiveUp --');
    $d->{TitleReliefAUp }->set_panel_widget_class('Radiobutton');

    $d->{TitleReliefADown} = new Var();
    $d->{TitleReliefADown}->set_prefix('TitleStyle ActiveDown --');
    $d->{TitleReliefADown}->set_panel_widget_class('Radiobutton');

    $d->{TitleReliefIA} = new Var();
    $d->{TitleReliefIA}->set_prefix('TitleStyle Inactive --');
    $d->{TitleReliefIA }->set_panel_widget_class('Radiobutton');

    $d->{HilightColorFore} = new MultiVar('black');
    $d->{HilightColorFore}->set_panel_widget_class('Entry');
    $d->{HilightColorFore}->set_name_title('D:HilightColorFore','Hilight Fore Color');
    $d->{HilightColorBack} = new MultiVar('grey');
    $d->{HilightColorBack}->set_panel_widget_class('Entry');
    $d->{HilightColorBack}->set_name_title('D:HilightColorBack','Hilight Back Color');
# make certain prefix is set before fellows
    $d->{HilightColorFore}->set_prefix('HilightColor');
    $d->{HilightColorFore}->set_fellows($d->{HilightColorFore},$d->{HilightColorBack});


    $d->{Buttons}= new MButtonStyle();


}
# important that order is WindowFont TitleHeight
@DecorOrder = qw ( HilightColorFore   WindowFont TitleHeight Justification
      BorderActivePixmap BorderInactivePixmap 
HiddenHandles NoInset TitleActiveUp
TitleActiveDown TitleInactive  TitleReliefAUp TitleReliefADown TitleReliefIA
  Buttons
		  );

sub copy_decor {
    my($n1,$n2) = @_;
    my $d = $CONFIG{Decors};
    foreach (keys %{$d->{$n1}} ) {
	$d->{$n2}->{$_}->set_value($d->{$n1}->{$_}->get_value);
    }
}

sub create_style_variables {

    my $style = $STYLE;
    $style = shift if @_;
    $CONFIG{Styles}{$style}={};
    my $s = $CONFIG{Styles}{$style};

    $s->{HandleWidth} = new Var();
    $s->{HandleWidth}->set_panel_widget_class('Entry');
    $s->{HandleWidth}->set_prefix('HandleWidth');
    $s->{HandleWidth}->set_name_title('S:HandleWidth','Width of Borders with Handles');
#    $s->{}->set_name_title('','');

    $s->{BorderWidth} = new Var();
    $s->{BorderWidth}->set_panel_widget_class('Entry');
    $s->{BorderWidth}->set_prefix('BorderWidth');
    $s->{BorderWidth}->set_name_title('S:BorderWidth','Width of Borders without Handles');

    $s->{ShowTitle} = new Var();
    $s->{ShowTitle}->set_panel_widget_class('Radiobutton');
    $s->{ShowTitle}->set_name_title('S:ShowTitle','Show Title Bar ?');

    $s->{ShowIcon} = new Var();
    $s->{ShowIcon}->set_panel_widget_class('Radiobutton');

    $s->{IconTitle} = new Var();
    $s->{IconTitle}->set_panel_widget_class('Radiobutton');

    $s->{IconPixmap} = new Var();
    $s->{IconPixmap}->set_panel_widget_class('Entry');
    $s->{IconPixmap}->set_prefix('Icon');
    $s->{IconPixmap}->set_name_title('S:IconPixmap','Icon Pixmap');

    $s->{Handles} = new Var();
    $s->{Handles}->set_panel_widget_class('Radiobutton');

    $s->{WindowList} = new Var();
    $s->{WindowList}->set_panel_widget_class('Radiobutton');

    $s->{StaysOnTop} = new Var();
    $s->{StaysOnTop}->set_panel_widget_class('Radiobutton');

# values: Sticky , Slippery
    $s->{Sticky} = new Var();
    $s->{Sticky}->set_panel_widget_class('Radiobutton');

    $s->{StartIconic} = new Var();
    $s->{StartIconic}->set_panel_widget_class('Radiobutton');

    $s->{Circulate} = new Var();
    $s->{Circulate}->set_panel_widget_class('Radiobutton');

    $s->{ForeColor} = new Var();
    $s->{ForeColor}->set_panel_widget_class('Entry');
    $s->{ForeColor}->set_prefix('ForeColor');
    $s->{ForeColor}->set_name_title('S:ForeColor','Title Bar Foreground Color');

    $s->{BackColor} = new Var();
    $s->{BackColor}->set_name_title('Style:BackColor','Title Bar Background Color');
    $s->{BackColor}->set_panel_widget_class('Entry');
    $s->{BackColor}->set_prefix('BackColor');
    $s->{BackColor}->set_name_title('S:BackColor','Title Bar Background Color');
	;
    $s->{SmartPlacement} = new Var();
    $s->{SmartPlacement}->set_panel_widget_class('Radiobutton');

    $s->{RandomPlacement} = new Var();
    $s->{RandomPlacement}->set_panel_widget_class('Radiobutton');

    $s->{Focus} = new Var();
    $s->{Focus}->set_panel_widget_class('Radiobutton');


    $s->{MWMButtons} = new Var();
    $s->{MWMButtons}->set_panel_widget_class('Radiobutton');

    $s->{MWMBorder} = new Var();
    $s->{MWMBorder}->set_panel_widget_class('Radiobutton');

    $s->{MWMDecor} = new Var();
    $s->{MWMDecor}->set_panel_widget_class('Radiobutton');

    $s->{MWMFunctions} = new Var();
    $s->{MWMFunctions}->set_panel_widget_class('Radiobutton');

    $s->{OLDecor} = new Var();
    $s->{OLDecor}->set_panel_widget_class('Radiobutton');

    $s->{SkipMapping} = new Var();
    $s->{SkipMapping}->set_panel_widget_class('Radiobutton');

    $s->{NoPPosition} = new Var();
    $s->{NoPPosition}->set_panel_widget_class('Radiobutton');

    $s->{Lenience} = new Var();
    $s->{Lenience}->set_panel_widget_class('Radiobutton');

    $s->{UseDecor} = new Var('default');
    $s->{UseDecor}-> set_panel_widget_class('Entry');
    $s->{UseDecor}-> set_prefix('UseDecor');
    $s->{UseDecor}->set_name_title('S:UseDecor',"Decor to be used with Style: $style");

    $s->{UseStyle} = new Var();
    $s->{UseStyle}-> set_panel_widget_class('Entry');
    $s->{UseStyle}-> set_prefix('UseStyle');
    $s->{UseStyle}->set_name_title('S:UseStyle',"Style used by Style: $style");

    $s->{DecorateTransient} = new Var();
    $s->{DecorateTransient}-> set_panel_widget_class('Radiobutton');


}

@StyleOrder = qw ( UseStyle HandleWidth  BorderWidth ShowTitle ShowIcon 
 IconTitle IconPixmap
  Handles  WindowList StaysOnTop Sticky StartIconic Circulate ForeColor
BackColor  SmartPlacement RandomPlacement Focus UseDecor DecorateTransient
		  );

#----------------------------------------------------------------------------------------

sub global {
    my $vname = shift;
    return $CONFIG{Global}->{$vname};
}

sub decor {
    my $vname = shift;
#    debug 0, "$vname";
#    debug 0, "Exists" if exists $CONFIG{Decors}->{$DECOR}->{$vname};
    return $CONFIG{Decors}->{$DECOR}->{$vname}; 

}


sub style {
    my $vname = shift;
    return $CONFIG{Styles}->{$STYLE}->{$vname};
}

###########################################################################################
sub get_var_by_name {
    my $namew = shift;
    if ($namew =~ /:/) {
	my($type,$name) = split ':',$namew ;
	if ($type =~ /^S/) {
	    return $CONFIG{Styles}->{$STYLE}->{$name};
	}
	elsif ($type =~ /^D/) {
	    return $CONFIG{Decors}->{$DECOR}->{$name};
	}
	elsif ($type =~ /^B/) {
#	    debug 0, "type $type, name $name";
	    my($num,$vname) = split '-',$name;
#	    debug 0, "got $num";
	    if (defined $CONFIG{Decors}->{$DECOR}->{Buttons}->{ButtonStyles}->[$num]) {
#		debug 0, "defined";
#		debug 0, "exists" if exists
#		    $CONFIG{Decors}->{$DECOR}->{Buttons}->{ButtonStyles}->[$num]->{$namew};
#		debug 0,"namew $namew";
		return $CONFIG{Decors}->{$DECOR}->{Buttons}->{ButtonStyles}->[$num]->{$vname};
	    }
	    else {
		return undef;
	    }
	}
    }
    else {
	return $CONFIG{Global}->{$namew};
    }
}

sub initialize_style {
    my $style = $STYLE;
    $style = shift if @_;
    create_style_variables($style) unless exists $CONFIG{Styles}{$style};
    my $s = $CONFIG{Styles}{$style};
    $s->{HandleWidth}->set_value('5');
    $s->{BorderWidth}->set_value('5');
    $s->{ForeColor}->set_value('black');
    $s->{BackColor}->set_value('grey');
#    $s->{}->set_value('');
#    $s->{}->set_value('');
#    $s->{}->set_value('');
#    $s->{}->set_value('');
#    $s->{}->set_value('');

}

sub get_type_and_name {
    my $var = shift;
    my $namew = $var->get_name;
    return undef unless defined $namew;
    my($type,$name) = split ':',$namew;
    if (defined $name) {
	if ($type=~/^S/) {
	    return ('Style',$name);
	}
	elsif ($type=~/^D|^B/) {
	    return ('Decor',$name);
	}
    }
    else {
	return ('Global',$namew);
    }
}


# set a variable and do other stuff.
sub set {
    my($var,$val,$update) = @_;
    my ($type,$name) = get_type_and_name($var);
    $var->set_value($val);
    $var->put_value_on_panel();
    return unless defined $type;
    if (not $update) {
	if($type eq 'Global') {
	    execute_one_global(0,$name);
	}
	elsif ($type eq 'Style') {
	    execute_style($STYLE,0);mysleep($SLEEP);recapture();
	}
	elsif ($type eq 'Decor') {
	    execute_decor($DECOR,0);mysleep($SLEEP);update_decor;
	}
	set_unsaved();
    }
    update_one_history_panel($var->get_name());
}
################################################

sub pop_tool {
    my $var = shift;
    my $ind = shift;
    my $val;
    my $name = $var->get_name();
    if (defined $ind) {
	$val = $var->get_one_store($ind);
    }
    else {
	$val = $var->get_value();
    }
    if( $val =~ /ixmap|\.gif|\.xpm/ ) {
	set_images() unless Exists $SETIMAGES;
	put_image_on_tool($val);
    }
    elsif($name =~ /Font/) {
	set_fonts() unless Exists $SETFONTS;
#	beep();
    }
    elsif($val =~ /Vector/) {
# nothing yet	
	beep();
    }
    else { # guess that its color ? 
	color_tool() unless Exists $COLORTOOL;
	put_color_on_tool($val);
    }

}



    
################################################################
# only for use with history functions.
# kludgy !!
sub last_word {
    return $_ if /Gradient|Vector/;
    if ( /^xset.*(#.*)\'/ ) {
      return $1;
    }
    /([\w\.\-]+$)/;
    return $1;
}		 


#################################################################
sub update_one_history_panel {
    my $name = shift;
    my ($l,$var,@vals);
    return unless Exists $HISTORYLIST{$name};
    $l = $HISTORYLISTBOX{$name};
    $var = get_var_by_name($name);
    if( not defined $var ) {
	$l->destroy;
	return;
    }
    @vals = $var->get_store();
    $l->delete('0','end');
    if($HISTORYSHORT{$name} eq 'Yes') {
	$l->insert(0, map(last_word,@vals) );   
    }
    else {
	$l->insert(0, @vals ); 
    }
    $l->selectionSet(0);
}
##################################################################
sub put_history_vars_on_panel {
    my ($l,$var,@vals,$name);
    foreach $name (keys %HISTORYLIST) {
	next unless Exists $HISTORYLIST{$name};
	$l = $HISTORYLISTBOX{$name};
	$var = get_var_by_name($name);
	if( not defined $var ) {
	    $l->destroy;
	}
	else {
	    @vals = $var->get_store();
	    $l->delete('0','end');
	    if($HISTORYSHORT{$name} eq 'Yes') {
		$l->insert(0, map(last_word,@vals) );   
	    }
	    else {
		$l->insert(0, @vals ); 
	    }
	    $l->selectionSet(0);
	}
    }
}

##################################################################
sub history_list {
    my ($var,@vals,@lvals,$w,$name,$title);
     $var = shift;
     @vals = $var->get_store();
    ($name,$title) = $var->get_name_title();
    if ( $name) {
          $HISTORYLIST{$name}->destroy if Exists($HISTORYLIST{$name});
	    $HISTORYLIST{$name} = $MW->Toplevel;
	  $HISTORYSHORT{$name} = 'Yes';
	    $w = $HISTORYLIST{$name};
	}
    else {
	$HISTORYLIST{"$var"}->destroy if Exists($HISTORYLIST{"$var"});
	$HISTORYLIST{"$var"} = $MW->Toplevel;
	$w = $HISTORYLIST{"$var"};
    }
    $w->title("History");
    my $f = make_help_dismiss($w,'File:history');
    my $f1 = $w->Frame(@fracon);
    my $lab =$f1->Label(@labcon);
    $f1->pack(-fill=>'x');
    my $flab = $w->Frame(@fracon);
    $flab->pack(-fill=>'x');
    my $lab2 = $flab->Label(@labcon);
    $lab2->pack(-side=>'left');
    my $lab3 = $flab->Label(@labcon);
    $lab3->pack(-side=>'left');
    my $f2 = $w->Frame(@fracon);
    $f2->pack(-side=>'bottom', -fill=>'x', );
    $lab->pack;

    if (defined $title) {
	$lab->configure(-text=>$title);
    }
    else {
	$lab->configure(-text=>'No Title');
    }
#    my($type,$varname) = split ':',$name if defined $name;
    my($type,$varname) = get_type_and_name($var);
    if ($type =~ /^S/) {
	$lab2->configure(-text=>'Style: ');
	$lab3->configure(-textvariable=>\$STYLE);
    }
    elsif ($type =~ /^D|^B/) {
	$lab2->configure(-text=>'Decor: ');
	$lab3->configure(-textvariable=>\$DECOR);
    }
    else {
	$lab2->configure(-text=>'Global Parameter');
    }

    my $s = $w->Scrollbar(@scalcon);
    $HISTORYLISTBOX{$name} = $w->Listbox(@liscon,-yscrollcommand => ['set', $s],
			-setgrid => 1, -width => 20, -height => 10); 
    my $l = $HISTORYLISTBOX{$name};
    $s->configure(-command => ['yview', $l]);
    $s->pack(-side => 'right', -fill => 'y');
    $l->pack(-side=> 'left',-expand=> '1' ,-fill=>'both');
    @lvals = map(last_word ,@vals);

    $l->insert(0, @lvals);
    $l->selectionSet(0);
    $l->configure(-width=> max_length(@lvals));
    my $reex = sub {
	my $com = $var->get_command();
#        send_command();
#	debug 0, $var->get_command();
	if( defined $type and $type =~ /^D|^B/)  {
	    execute_decor($DECOR,0);
	    update_decor();
	}
	if( defined $type and $type =~ /^S/)  {
	    execute_style($STYLE,0);
	    recapture();
	}
	else {
	    send_command($com) if defined $com;
	}
	set_unsaved();
    };
    $l->bind('<Double-Button-1>' => sub {
	my $i = $l->curselection();
	$var = get_var_by_name($var->get_name());
	$var->pop_value($i);
	@vals = $var->get_store();
	$l->delete('0','end');
	if($HISTORYSHORT{$name} eq 'Yes') {
	    $l->insert(0, map(last_word,@vals) );   
	}
	else {
	    $l->insert(0, @vals ); 
	}
	$l->selectionSet(0);
	$var->put_value_on_panel() if $var->has_widget();
	&$reex;
    });
    $l->bind('<Shift-1>' => sub {
	my $e = $l->XEvent;
	my $p = '@'.$e->x.','.$e->y;
	$l->selectionClear(0,'end');
	$l->selectionSet($p);
#	$l->activate($l->index($p));
	$MW->update;
	pop_tool($var,$l->index($p));
    });

    $f2->Button(@butcon,-text=>'Delete',-activebackground=> 'red', -command =>
              sub {
		  my $i = $l->curselection();
		  $var = get_var_by_name($var->get_name());
		  if($var->get_store() <=1 ) {
		      beep();
		      return;
		  }
		  $var->delete_from_store($i);
		  @vals = $var->get_store();
		  $l->delete('0','end');
		  set_unsaved();  
		  if($HISTORYSHORT{$name} eq 'Yes') {
		      $l->insert(0, map(last_word,@vals) );   
		  }
		  else {
		      $l->insert(0, @vals ); 
		  }
		  $l->selectionSet($i);
		  if ($i == 0 ) {
		      $var->put_value_on_panel() if $var->has_widget();
		      &$reex;
		  }
	      }
    )->pack(-side=>'left');
    $f2->Button(@butcon,-text=>'Long/Short',-command => 
    sub{ 
	if( $HISTORYSHORT{$name} eq 'Yes' ) {
	    $HISTORYSHORT{$name} = 'No';
	}
	else {
	    $HISTORYSHORT{$name} = 'Yes';
	}
	update_one_history_panel($name);
    })->pack(-side=>'right');
}
## end history_list


############################################################
# write the commands to a file suitable for inclusion in
#  .fvwmrc

sub dump_fvwm_commands {
    my ($key) ;
    if (open WRITEFH, ">$STATE{WriteFile}") {
	    execute_all(1,'NoRecapture');
	    close WRITEFH;
    }
    else {
      message("can't open $STATE{WriteFile}") ;
    }

}
	
############################################################

sub send_one {
    my($f,$stringa)=@_;

#  edit string to expand ~/ 
    my $string = tilde_expand $stringa;
#    debug 1, "send: $string";
    no strict 'refs';
    if ($f==0) {
	if (defined @$string) {
	    foreach (@$string) {
		sendInfo(0, $_);
	    }
	}
	else {
	    sendInfo(0, $string);
	}
    }
    else {
	if (defined @$string) {
	    foreach (@$string) {
		print WRITEFH "$_\n";
	    }
	}
	else {
	    print WRITEFH "$string\n";
	}
    }	

}

	
########################################################
sub execute_one_global {
    my $g = $CONFIG{Global};
    die "execute_one_global needs two arguments" unless @_==2;
    my ($f,$var) = @_;
    my($com,$v);
    if(exists $g->{$var}) {
	$com = $g->{$var}->get_command;
    }
    else {
	debug 0, "Global $var does not exist";
	return;
    }
    send_one($f,$com) if defined $com;
#    debug 0, "sending: $com";
}    
   


########################################################
sub execute_global {
    die "execute_global needs an argument" unless @_==1;
    my $f = shift;
    foreach (@GlobalOrder) {
	execute_one_global($f,$_);
    }
}

#########################################################################
sub execute_style {
    my($style,$f) = @_;
    my $s = $CONFIG{Styles}{$style};
    my ($key,$outs) ;
   
    my $pref = "Style \"$style\"  " ;

    foreach (@StyleOrder) {
	$outs = $s->{$_}->get_command();
	next unless defined $outs and $outs ne '';

	send_one($f,$pref.$outs) if defined $outs;
    }
}

sub execute_styles {
    my $key;
    my($f) = shift;
    foreach $key (sort keys %{$CONFIG{Styles}}) {
	execute_style($key,$f) ;
    }
}

##########################################################################################

sub execute_decor {
    my($decor,$f,$recaparg) = @_;
    my $s = $CONFIG{Styles};
    if(defined $recaparg and $recaparg eq 'NoRecapture') {
#	debug 0,"setting recap to zero";
	$recapture = '';
    }
# setting no recapture no matter what .
    $recapture = '';
    my $outstring;
    my $d = $CONFIG{Decors}{$decor};

#    debug 0, "decor $decor";
    reset_decor($decor);
# I think destroying, and therefor recapturing is
# never neccessry
#    send_one($f,"DestroyDecor $decor");
    my $pref = "AddToDecor \"$decor\"  ";
    foreach (@DecorOrder) {
#	debug 0,"var: $_";
	$outs = $d->{$_}->get_command();
	next unless defined $outs and $outs ne '';
# handling Buttons like this for now
	no strict 'refs';
	if (defined @$outs) {
	    send_one($f,$pref);
	    foreach (@$outs) {
		send_one($f, '+ '.$_) if defined $_;
	    }
	}
	else {
	    send_one($f,$pref.$outs);
	}
    }
    if($recapture ne '' ) {
#	debug 0, "recapture is $recapture";
	foreach (keys %$s) {
	    if ($s->{$_}->{UseDecor} eq $decor) {
		send_command "Style \"$_\" UseDecor \"$decor\"";
	    }
	}
    send_command "Recapture";
    }
}
##########################################################################################
sub execute_decors {
    my($f) = shift;
    my $recaparg = shift;
    my $key;
    my $s = $CONFIG{Styles};
    foreach $key (sort keys %{$CONFIG{Decors}}) {
	execute_decor($key,$f,'NoRecapture') ;
	}
# destroying a decor resets UseDecor, so we set it back
#    return if defined $recaparg and $recaparg eq 'NoRecapture';
#    foreach (keys %$s) {
#	if ($s->{$_}->{UseDecor} eq $decor) {
#	    send_command "Style \"$_\" UseDecor \"$decor\"";
#	}
#    }
#    send_command "Recapture";
}

##########################################################################################

sub execute_all {
    my($f) = shift;    
    execute_global($f);
    execute_decors($f,'NoRecapture');
    execute_styles($f);
}


sub save_as { 
    $SAVE_AS->destroy if Exists($SAVE_AS); 
    $SAVE_AS = $MW->Toplevel(@topcon); 
    my $w = $SAVE_AS;
    $w->title('Save As: Fvwm');
    make_help_dismiss( $w,
'Save the current configuration under a new  name.
Do not use full path names here; just a filename.
All configurations are stored in one directory.');
    my $f = $w->Frame(@fracon,);
    $f->pack(-expand => 1);
    my $ent = $f->Entry(@entcon, -width => 30);
    $ent->insert('0',$CONFFILE);
    $ent->pack();
    $getsub = sub {
	   $CONFFILE = $ent->get();
	   set_saved();
	   write_all_variables();write_state;
	   $w->destroy; };
    $ent->bind('<Return>' => $getsub);
    my $ok = $f->Button(@butcon,
			-text => 'OK',
			-command => $getsub
			);
    $ok->pack();
}
#######################################################################################    


# using Tk::Dialog sometimes caused hanging.
sub query_save {
    my @labels = ('Save', 'Don\'t Save', 'Cancel');
    my $d = $MW->Toplevel(); 
    $d->title('quit FvwmConf');
    mysleep(.1); # this should be some kind of wait
    $d->grab;
    my $done = 'no';
    my $m = $d->Message(@labcon, -width=>'100m',-text => 
     "The configuration '$CONFFILE' is not saved.\n".
			"If you choose 'Don\'t Save', your changes will be lost" );
    $m->pack(-side=>'top',-fill=>'both',-expand=>'1');
    my $f = $d->Frame(@fracon);
    $f->pack(-fill=>'both');
    $f->Button(@butcon,-activebackground=> 'yellow',
	       -text=>'Save',
	       -command=>sub {set_saved();write_all_variables();
			     $done = 'OK'; }
	       )->pack(-side=>'left');
    $f->Button(@butcon,-activebackground=> 'red',
	       -text=>'Don\'tSave',
	       -command=>sub {$done = 'OK';}
	       )->pack(-side=>'left');
    $f->Button(@butcon,-activebackground=> 'green',
	       -command => sub {$done = '';},
	       -text=>'Cancel')->pack(-side=>'left');
    $d->waitVariable(\$done);
    $d->grabRelease;
    $d->destroy;
    return $done;
}

# throw up  a message window.
sub message {
    my $w = $MW -> Toplevel;
    my $m = $w->Message(@labcon,-padx=>'10',-pady=>'10',-text=>shift);
    $m->pack();
    $w->Button(@butcon,-text=>'OK',-padx=>'10',-pady=>'10',-command =>
     sub { $w->destroy })->pack;
}


###########################################################################
sub close_command {
    write_state();
    if ( is_saved() or query_save()) {
      endModule($FARGS{OFD});$MW->destroy;
  }
}

##########################################################################
# after 'B', supply text, command, and var ref.
sub labbutlist{
    my($obj,$what,$one,$but);
    $obj=shift;
    my $f = $obj->Frame(@fracon,);    
    $f->pack(-fill => 'both');
    my @pl = (-side => 'left', -anchor => 'w');
    while(@_ != 0 ) {
	$what=shift;
	if($what eq 'L') {
	    $f->Label(@labcon2,-text => shift)->pack(@pl,@butpack);
	}	
	else {
	    $but=$f->Button(@butcon2, -text=> shift);
	    $but->bind('<1>'=>shift);
	   $but->pack(@pl,@butpack);
	   bind_history($but,shift);
	}
    }
    return($f);
}        

##########################################################################
sub radlablist {
    my($obj,$ltext,$variable);
    $obj=shift;$ltext=shift;$variable=shift;
    my (@rads,$r) ;
    my $f = $obj->Frame(@fracon,);
    $f->pack(-fill => 'both'); 

    my @pl = (-side => 'left', -pady => $YPAD1, -anchor => 'w');
    my $lab = $f->Button( @labcon,-text => $ltext);
    $lab->pack(@pl);
    my $help;
    if ($_[0] =~ /File:/) {
	$help = shift;
	bind_help($lab,$help);
    }
    else {
	$lab->configure(-state=>'disabled',-disabledforeground=>'black',-highlightthickness=>'0');
    }
    my ($i,@text,@value);
    while(@_ != 0 ) {
	push @text, shift;
	push @value, shift;
    }
    for($i=0;$i<@text;$i++) {
	$r =$f->Radiobutton(@radcon,
			    -text=> $text[$i],
			    -variable => $variable,
			    -value => $value[$i]);	
	$r->pack(@pl);
	$r->bind('<Double-Button-1>' =>
sub { my $var = $r->cget(-variable);
	        $$var = undef});
	push @rads,$r;
    }
    return ($f,\@rads);
}

##########################################################################
# This one embeds the lab and button in a text widget, $obj
sub radlabtext {
    my($obj,$ltext,$variable);
    $obj=shift;$ltext=shift;$variable=shift;
    my (@rads,$r) ;
    my $f = $obj->Frame(@fracon,);
#    $f->pack(-fill => 'both'); 

    my @pl = (-side => 'left', -pady => $YPAD1, -anchor => 'w');
    my $lab = $f->Button( @labcon,-text => $ltext);
    $lab->pack(@pl);
    my $help;
    if ($_[0] =~ /File:/) {
	$help = shift;
	bind_help($lab,$help);
    }
    else {
	$lab->configure(-state=>'disabled',-disabledforeground=>'black',-highlightthickness=>'0');
    }
    my ($i,@text,@value);
    while(@_ != 0 ) {
	push @text, shift;
	push @value, shift;
    }
    for($i=0;$i<@text;$i++) {
	$r =$f->Radiobutton(@radcon,
			    -text=> $text[$i],
			    -variable => $variable,
			    -value => $value[$i]);	
	$r->pack(@pl);
	$r->bind('<Double-Button-1>' =>
sub { my $var = $r->cget(-variable);
	        $$var = undef});
	push @rads,$r;
    }
    $obj->window('create', 'end', -window => $f);
    $obj->insert('end',"\n");
    return ($f,\@rads);
}
########################################################################




# should switch to this
# no nothing here !
sub radlablist2 {
    my($obj,$ltext,$variable);
    $obj=shift;$ltext=shift;$variable=shift;
    my $f = $obj->Frame(@fracon,);
    $f->pack(-fill => 'both'); 
    my ($i,@text,@value);
    while(@_ != 0 ) {
	push @text, shift;
	push @value, shift;
    }
    my @pl = (-side => 'left', -pady => $YPAD1, -anchor => 'w');
    $f->Label( @labcon,-text => $ltext)->pack(@pl);
    for($i=0;$i<@text;$i++) {
	$f->Radiobutton(@radcon,
			-text=> $text[$i],
			-variable => $variable,
			-value => $value[$i])->pack(@pl);	
    }
    return $f;
}

########################################################################
# sub labentlist
# Args:
# $obj
# 'L' or 'E'  (for Label or Entry)
# if 'L' then take text
# if 'E' then take width,value-to-insert
# return $frame, @ents, (frame and entries)
sub labentlist { 
    my($obj,$what,@ents,$one);
    $obj=shift;
    my ($lab,$junk,$file);
    my $f = $obj->Frame(@fracon,);    
    $f->pack(-fill => 'both');
    my @pl = (-side => 'left', -pady => $YPAD1, -anchor => 'w');
    while(@_ != 0 ) {
	$what=shift;
	if($what eq 'L') {
	    $lab = $f->Button(@labcon,-text => shift,-state=>'disabled',
	      -disabledforeground=>'black',-highlightthickness=>'0');
	    $lab->pack(@pl);
	}
	elsif ($what =~ /^File/) {
	    eval "\$lab->bind('<Button-1>' => sub{display_help (\"$what\" ) })";
	    $lab->configure(-state=>'normal',-activebackground=>'green');
	}
	else {
	    my $one = $f->Entry(@entcon,-width => shift);
	    push @ents,$one;
	    $one->pack(@pl,@EF);
	    my $var = shift;
	    $one->insert('0',$var->get_value);
	}
    }
    return($f,@ents);
}    
########################################################################

sub bind_help  {
    my ($widget,$what) = @_;
	 $widget->configure(-activebackground=>'green',-highlightthickness=>'0');
	 $widget->configure(-state=>'disabled'
			   ,-disabledforeground=>'black') unless defined  $what and $what;
    eval "\$widget->bind('<Button-1>' => sub{display_help (\"$what\" ) })"
	if defined  $what and $what;  
}  
    

sub bind_history {
    my ($button ,$wname,$name,$type,$var );
    $button = shift;
    $var = shift;
    $wname = $var->get_name();
    ($type,$name) = split ':', $wname;
    if ($name) {
	if ($type =~ /^S/) {
	    $button->bind('<Button-3>' =>
			  sub { history_list($CONFIG{Styles}->{$STYLE}->{$name})  });
         $button->bind('<2>' => sub {
	     pop_tool($CONFIG{Styles}->{$STYLE}->{$name}) });
         $button->bind('<Shift-1>' => sub {
	     pop_tool($CONFIG{Styles}->{$STYLE}->{$name}) });
        }
        elsif ($type =~ /^D/) {
	 $button->bind('<Button-3>' =>
	    sub { history_list($CONFIG{Decors}->{$DECOR}->{$name})  });
         $button->bind('<2>' => sub {
	     pop_tool($CONFIG{Decors}->{$DECOR}->{$name}) });
         $button->bind('<Shift-1>' => sub {
	     pop_tool($CONFIG{Decors}->{$DECOR}->{$name}) });
        }
        elsif ($type =~ /^B/) {
	  my($num,$vname) = split '-',$name;
	 $button->bind('<Button-3>' =>
	    sub { history_list(button_style_ref->{$vname})  });
         $button->bind('<2>' => sub {
	     pop_tool(button_style_ref->{$vname}) });
         $button->bind('<Shift-1>' => sub {
	     pop_tool(button_style_ref->{$vname}) }) ;
        }
    }
    else {
# $type is actually entire Global name      
      $button->bind('<Button-3>' => sub {history_list($var)});
         $button->bind('<2>' => sub {
	     pop_tool($var) });
         $button->bind('<Shift-1>' => sub {
	     pop_tool($var) });
    }
}



sub make_help_dismiss {
#    my ($obj,$text) = @_; 
    my ($one,$hflag,$dflag,$obj,$text);
    $hflag=0;$dflag=0;
    while($one = shift @_) {
	if ($one eq 'NoDismiss') {   $dflag = 1;}
	elsif ($one eq 'NoHelp') {  $hflag = 1; }
	elsif( $obj ) {$text = $one;}
	else { $obj = $one }
    }
    my $f = $obj->Frame(@fracon,-relief=>'raised',-bd=>'2');
    $f->pack(-side=> 'top'  , anchor => 'e', -fill => 'x');    
    if ($dflag != 1) {
	my $dismiss = $f->Button(
				 @hbutcon,
				 -activebackground => 'yellow',
				 -text => 'Dismiss',
				 -command => sub{$obj->destroy});
	$dismiss->pack(-side => 'left', -anchor => 'w', -ipadx => 0,-ipady => 0);
    }
    if ($hflag != 1) {
	my $help = $f->Button(
			      @hbutcon,
			      -activebackground => 'green',
			      -text => 'HELP',
			      -command => [\&display_help, $text],
			      );
	$help->pack(-side => 'right', -anchor => 'ne', -ipadx => 0,-ipady => 0);
    }
    return $f;
}
########################################################################

sub make_decor_style_frame {
    my $w = shift;
    my $lbg = '#41a6ff';
    my @el = (-expand=>'y', -fill => 'x');
    my @lb = (@labcon,-background => $lbg,-bd=>3);
    my $f2 = $w->Frame(@fracon);
    my @pl = (-side=>'right',@el,);
    $f2->pack(-fill => 'x');
    $f2->Label(@lb,-textvariable => \$DECOR)->pack(@pl);
    $f2->Label(@lb, -text => "   Decor: ")->pack(@pl);
    $f2->Label(@lb,-textvariable => \$STYLE)->pack(@pl);
    $f2->Label(@lb, -text => "Style: ")->pack(@pl);
}


#########################################################################
sub make_dismiss {
    my ($obj) = shift; # not a method
    my $f = $obj->Frame(@fracon,);
    $f->pack(-side=> 'top'  , anchor => 'w');
    my $dismiss = $f->Button(
      @hbutcon,
	     -activebackground => 'yellow',
      -text => 'Dismiss',
	  -command => sub{$obj->destroy});
    $dismiss->pack(-side => 'left', -anchor => 'w');
    return ($f) ;  # may want more in frame
}


#########################################################################
sub display_help {
    my $text = shift;
#    $DIS_HELP->destroy if Exists($DIS_HELP);
    my $DIS_HELP = $MW->Toplevel(@topcon);
    my $w = $DIS_HELP;
    $w->title("Help: FvwmConf");
    make_dismiss($w);
    my $t = $w->Text(@textcon,-width => $htwidth,
		     -height=> $htheight, -font => $hfont, -bg => $labbg);
    my @files;

    if($text =~ /^File\:/) {
	my($word,$file) = split ':',$text;
	if (not open HELPIN, "<$help_dir/$file") {
	    debug 0,"Can't find help file $help_dir/$file";return;
	}
	my ($line,$count);
	my $ln = 0;
	$t->insert('end',"    ") ;
	my @parts;
	for(;;) {
	    last if eof(HELPIN);
	    ($count,$line) = read_a_line(HELPIN);
#	    debug 0,"$count:$line";
	    chomp $line; $line =~ s/\\n/\n/g;
	    $t->insert('end',"\n    ") if $count > 0;
	    @parts = split "&&",$line;
	    my $flag = 0;
#	    debug 0, "parts ". scalar(@parts). "\n";
	    my($fn,$words);
	    foreach (@parts) {
		if ($flag == 0) {
		    $t->insert('end'," $_ ");
		    $flag = 1;
		}
		else {
		    ($fn,$words) = split ":",$_;
		    $ln++;
		    $t->insert('end'," $words ","t$ln");
#		    debug 0, "set $ln";
		    push @files,$fn;
		    $flag = 0;
		}
	    }
	}
	close HELPIN;
    }
    else {$t->insert('end',$text);}
    my $i;
    for($i=1;$i<=@files;$i++) {
#	debug 0, "conf $i";
	$t->tag('configure', "t$i", -background => 'green' );
#	debug 0, "#File:$files[$i-1]#";
	$t->tag('bind', "t$i", '<1>' => 
		eval "sub{display_help('File:' . $files[$i-1]) }");
    }
    $t->pack(-expand=>'1', -fill=>'both');
    $t->configure(-state=>'disabled');
    $w->bind('<Page_Down>' => sub { 
	$t->yview(scroll => 1, 'pages');});
    $w->bind('<Page_Up>' => sub { 
	$t->yview(scroll => -1, 'pages');});
    $w->bind('<Down>' => sub { 
	$t->yview(scroll => 1, 'unit');});
    $w->bind('<Up>' => sub { 
	$t->yview(scroll => -1, 'unit');});
}


################################################################################
sub change_configuration {

    $CHANGE->destroy if Exists($CHANGE);
    $CHANGE = $MW->Toplevel(@topcon);
    my $w = $CHANGE;
    $w->title('Load Configuration FvwmConf');
    make_help_dismiss($w,
'Click on the name of a configuration.
Then click on the load button to load the configuration
with the selected name.  Or double-click to load'
	      );
    my $read = sub {
	my($len,$name);
	my $maxwidth = 0;
	opendir SOMEDIR, $fvwm_conf_comm_dir;
	@confs =  sort grep !/^\.\.?$/,readdir SOMEDIR;
	closedir SOMEDIR;
	foreach $name (@confs) {
	    $len = length $name;
	    $maxwidth = $len if $len > $maxwidth;
	}
	$maxwidth +=2;
    };
    &$read;

    my $apsub;
    my $f = $w->Frame(@fracon,);
    $f->pack(-side => 'bottom', -expand => 'yes', -fill => 'both');
    my $s = $f->Scrollbar(@scalcon);
    my $l = $f->Listbox(@liscon,-yscrollcommand => ['set', $s], -setgrid => 1,
					 -width => $maxwidth, -height => 10);
    $s->configure(-command => ['yview', $l]);
    $s->pack(-side => 'right', -fill => 'y');
    $l->pack(-side => 'left', -expand => 'yes', -fill => 'both');
    $l->insert(0, @confs );
    $apsub =
       sub {
	   if ( is_saved() or  query_save()){
	       
# hangs the session, fix it later.	   
	       my $file = $confs[$l->curselection()];
	       $CONFFILE = $file;
	       $STATE{DefaultConfig} = $CONFFILE;
	       clear_config();reset_fvwm();$DECOR=$INIT_DECOR;$STYLE=$INIT_STYLE;
	       read_all_variables();
	       execute_all(0);
	       mysleep($SLEEP);recapture();load_all_to_panel();
	   }
       };   
    $l->bind('<Double-Button-1>'  => $apsub );  
    my $relist = sub {$l->delete('0','end' );&$read;$l->insert(0, @confs);};

    my $f2 = $w->Frame(@fracon,);
    $f2-> pack(-side => 'top', -expand => 'yes', -fill => 'both');
    my $b1 = $f2->Button(@butcon, -text => 'Load',
         -command => $apsub
);
    $b1->pack(-side => 'left');
$f2->Button(@butcon, -text => 'Update',-command => $relist)->pack(-side => 'left');
$f2->Button(@butcon,-activebackground => 'red', -text => 'Delete',-command => 
sub {	   my $file = $confs[$l->curselection()];
 system "/bin/rm -f $fvwm_conf_comm_dir/$file"; &$relist})->pack(-side => 'left');

}



########################################################################################

sub command_line {

    $COMMAND_LINE->destroy if Exists($COMMAND_LINE);
    $COMMAND_LINE = $MW->Toplevel(@topcon);
    my $w = $COMMAND_LINE ; 
    make_help_dismiss($w,
'Enter a command in the entry box.
Typing <Return> sends the command to Fvwm for interpretation.
Try entering \'Beep\', for example.'
	      );
    $w->title('Command to Fvwm');
    my $f = $w->Frame(@fracon,);
    $f->pack (-side => 'top',-expand => 1, -anchor => 'e' );
my $w_label =  $w->Label(@labcon, -text => 'Fvwm Command', -anchor => 'e',
-font => $editorfont
);
my $w_entry = $w->Entry(@entcon,-width => 60 , -relief => 'sunken',
      -font => $editorfont
);
    $w_entry -> insert(0,$STATE{last_command_line})
	if exists $STATE{last_command_line} ;
$w_entry -> bind ('<Return>' => sub {
    $STATE{last_command_line}  = $w_entry->get;
    sendInfo(0,$STATE{last_command_line});
});
$w_entry -> pack(-side => 'right');
$w_label -> pack(-side => 'right');
}


############################################################################

sub command_edit {
    $COMMAND_EDIT->destroy if Exists($COMMAND_EDIT);
    $COMMAND_EDIT = $MW->Toplevel((@topcon));
    my $w = $COMMAND_EDIT ; 
    make_help_dismiss($w,"File:commandedit");

    my $f = $w->Frame(@fracon,);
    $w->title('* Fvwm Command Editor');
    $f->pack(-fill => 'both', -expand => '1');

    my $testtext = $w->Text(@textcon,-wrap=>'none');
#    $testtext->insert('0.0',"# Edit commands here\n# Click on send to send them to fvwm");
    $testtext->pack( -fill => 'both', -expand => '1');
#    $testtext->pack();
    my $send = $f->Button(
 @butcon,
			     -text => 'Send',
	     -command => sub{
		 my $string = $testtext->get('0.0','end');
		 my @lines = split "\n",$string;
		 my $each;
		 foreach $each (@lines) {
		     send_command $each unless $each =~ /^#/;
		     print "comm: $each\n" if $DEBUG;
		     }
	     });
    $send->pack(-side => 'left');
    my $sendsel = $f->Button(
			     @butcon,
			     -text => 'Send Selected',
			     -command => sub{
				 my $string = $testtext->get('sel.first','sel.last');
				 my @lines = split "\n",$string;
				 my $each;
				 foreach $each (@lines) {
				     send_command $each unless $each =~ /^#/;
				     print "comm: $each\n" if $DEBUG;
				 }
			     });
    $sendsel->pack(-side => 'left');
    my $f1 = $w->Frame(@fracon);
    $f1->pack( -side=>'bottom');
    my $w_label =  $f1->Label(@labcon,
			      -text => 'Single Command', -anchor => 'e',
			      -font => $editorfont
			      );
    my $w_entry = $f1->Entry(@entcon,-width => 60 , -relief => 'sunken',
			     -font =>  $editorfont
			     );
    $w_entry -> insert(0,$STATE{last_edit_command_line})
	if exists $STATE{last_edit_command_line} ;
    my $lsub;
    $w_entry -> bind ('<Return>' => $lsub = sub {
	$STATE{last_edit_command_line}  = $w_entry->get;
	sendInfo(0,$STATE{last_edit_command_line});
    });
    $w_entry -> bind ('<Double-Button-1>' =>  $lsub);
    $w_entry -> pack(-side => 'right');
    $w_label -> pack(-side => 'right');
	 
}


############################################################

sub editor {
    $EDITWINDOW->destroy if Exists($EDITWINDOW) ;
    my ($callerref) = shift;
    $EDITWINDOW = $callerref->Toplevel;
    my $w = $EDITWINDOW;
    my $file=shift;
    $w->title('Editor');
    my @textcon = ( -wrap => 'word', -exportselection => 1
		,);
    my $f = make_help_dismiss($w,'NoHelp');
    my $t=$w->Text(@textcon);

    if(open EDITINHAND, "<$file") {
	my (@lines) = <EDITINHAND>;
	close EDITINHAND;
#	debug 0, join '',@lines;
	foreach $_ (@lines) {
	    chomp ;
	    $t->insert('end',"$_\n");
	}
    }
    $t->pack();
    $f->Button(-text=>'Save',-command=>
	       sub {my $string = $t->get('0.0','end');
		    open EDITOUTHAND,">$file";
		    chomp $string;
		    print EDITOUTHAND "$string"; close EDITOUTHAND;
		}
     )->pack(-side=>'right');
}

# end editor
##################################################################


############################################################################################

sub pad {
    my($string,$x,$side) = @_;
    my($l) = length $string;
    return $string if $l >= $x;
    return $string . ' ' x ($x-$l) if not defined $side or $side ne 'left';
    return ' ' x ($x-$l) . $string;
}

sub pad_list {
    my @list = @_;
    my $max = 0;
    foreach (@list) {
	$max = length $_ if length $_ > $max;
    }
    foreach (@list) {
	$_ = pad($_,$max,'left');
    } 
    return @list;
}

sub max_length {
    my @list = @_;
    my $max = 0;
    foreach (@list) {
	$max = length($_) if length($_) > $max;
    }
    return $max;
}



#############################################################################################
sub load_all_to_panel {
    put_decor_values_on_panel();  # must do for buttons regardless of $SETDECOR
    put_style_values_on_panel() if Exists $SETSTYLE;
    put_global_values_on_panel() if Exists $SETGLOBAL;
    put_history_vars_on_panel();
}




##############################################################################
sub read_image_paths {
    local *IMPATHHAND;
    my @lines;my $one;
    if(open IMPATHHAND , "<$fvwm_conf_user_dir/imagepaths") {
	for(;;) {
	    last if eof(IMPATHHAND);
	    $one = read_a_line(IMPATHHAND);
	    next unless defined $one;
	    $one =~ s/\/$//;
	    push @lines,$one unless $one =~ /^\s*$/;
	}
#	@lines = <IMPATHHAND>;
	close IMPATHHAND;
    @imagepath=@lines;
    }
}
###############################################################



## If Style or Decor is changed, the other follows
## $master is 'Styles' or 'Decors', $species is value of $DECOR or $STYLE
#  currently ignore '*' s
sub link_change {
    my($master,$species) = @_; 
    my $newdecor='';
    my $newstyle='';
    my $stripped;
    my $s = $CONFIG{Styles};
    my $d = $CONFIG{Decors};
    return unless  $LINK_STYLE_DECOR eq 'Yes';
    if($master eq 'Styles') {
	if(exists $s->{$STYLE}->{UseDecor}
	   and defined $s->{$STYLE}->{UseDecor}
	   and $s->{$STYLE}->{UseDecor}->get_value ne '' )
	{ $stripped = $s->{$STYLE}->{UseDecor}->get_value ;
	  $stripped =~ s/\*//g; # remove glob symbols
# probably never globs here anyway
	  $newdecor = $stripped;}
	else {
	    $newdecor = 'default';
	}
	return if $newdecor eq $DECOR;
	$DECOR = $newdecor;
	create_decor_variables($DECOR) unless exists $d->{$DECOR};
	if(Exists $SETDECOR) {
	    initialize_decor_panel();
	    put_decor_values_on_panel() if Exists $SETDECOR;
	    return;
	}
    }
    else { #  $master eq 'Decors'
	
	$newstyle = '*';
	foreach(keys %$s) {
	    $stripped = $s->{$_}->{UseDecor}->get_value ;
	    $stripped =~ s/\*//g; # remove glob symbols
	    $newstyle = $_ if $stripped eq $DECOR;
	}
	if ($newstyle ne $STYLE) {
	    $STYLE = $newstyle;
	    $STYLE = '*' if $DECOR eq 'default';
	    put_style_values_on_panel() if Exists $SETSTYLE;
	}
    }
}

# this doesn't appear to speed things up any.
sub AUTOLOAD {
#    debug 0, " here we are";
    if ($AUTOLOAD =~ /color_tool|coledit/) {
	require 'colortool.pl';
	color_tool(@_);
    }
    elsif ($AUTOLOAD =~ /set_images/) {
	require 'images.pl';
        set_images(@_);
    }
    elsif ($AUTOLOAD =~ /set_fonts/) {
	require 'setfonts.pl';
        set_fonts(@_);
    }
    elsif ($AUTOLOAD =~ /set_global/) {
	require 'global.pl';
        set_global(@_);
    }
    elsif ($AUTOLOAD =~ /set_decor|decor_panel|put_decor/) {
	require 'decor.pl';
	no strict 'refs';
        &$AUTOLOAD(@_); # This is frowned on , I think
    }    
    elsif ($AUTOLOAD =~ /set_style/) {
	require 'style.pl';
        set_style(@_);
    }
    elsif ($AUTOLOAD =~ /set_pager/) {
	require 'pager.pl';
        set_pager(@_);

    }
    elsif ($AUTOLOAD =~ /set_winlist/) {
	require 'winlist.pl';
        set_winlist(@_);
    }
    elsif ($AUTOLOAD =~ /write_fvwm2rc_query/) {
	require 'writefvwm2rc.pl';
        write_fvwm2rc_query(@_);
    }
=pod
  No idea what this is about
    elsif ($AUTOLOAD =~ /set_menus/) {
	use FVWMCONF::Menus;
        FVWMCONF::Menus::set_menus(@_);
    }
=cut
    else {
	die "Autoload: Unknown subroutine, $AUTOLOAD";
    }

}

############################################################################################

#debug_box();
#require 'colortool.pl';
#require 'images.pl';
#require 'setfonts.pl';
#require 'global.pl';

find_support_programs();
read_state();
set_state();
setcons();
set_derived_file_names();
create_global_variables();
create_decor_variables($DECOR);
create_style_variables($STYLE);
require 'main.pl';
main_window();
require 'buttons.pl';
require 'readfvwm2rc.pl';
require 'mail.pl';
require 'errlog.pl';
read_all_variables();
execute_all(0);
set_saved();
read_image_paths();

get_root_size();
open_windows_from_state();
clean_tmp_directory();

##################
# we only want one at a time !
$oldpidfile = "$fvwm_conf_user_dir/confpid";
$oldpid = `cat $oldpidfile`;
system "kill -9 $oldpid" if $oldpid;
open PIDHAND, ">$oldpidfile";
print PIDHAND $$;
close PIDHAND;
###########################################################################################

#system("$fvwm_conf_dir/bin/clearFvwmConfwait 1");
recapture();
MainLoop;
