#!/bin/sh 

# Some time ago, Martin Kraemer <Martin.Kraemer@mch.sni.de> posted an
# incomplete script to convert fvwm-1 'rc' files to fvwm-2. I've just
# recently fixed and enhanced that script; it's complete (or nearly
# so) now. This should help if you choose to convert.
# 
# I've also made a couple of other minor changes to make life easier
# for our users here: I changed the default initialization from "Read
# .fvwmrc" to "Read .fvwm2rc" (in fvwm/fvwmc), and I installed fvwm 2
# as "fvwm2". With these changes, users can easily convert at their
# leisure.
# 
# Herewith the script. It's using GNU awk (gawk), but will run with
# any "new" awk (nawk on Suns (SunOS 4, Solaris), awk on most other
# systems). If you do not use gawk, it will be case-sensitive (the
# case of the fvwm commands must match those in the script
# exactly). With gawk, it'll be case-insensitive.

#
# Convert fvwm 1.x configuration file to 2.0
#
# Originally written by Martin Kraemer <Martin.Kraemer@mch.sni.de>
# Corrected, extended, and modified by Grant McDorman <grant@isgtec.com>
# 24 May 95
# Addtional corrections and extensions by Bill Oswald <wamo@vnet.ibm.com>
# 8 Mar 96 thru 18 Jul 96
# Minor corrections to make it easier to customize by Charles Hines 08/01/96
#

echo "Fvwm 1->2 converter for Dotfile Generator's Fvwm2 module"
echo ""
echo "Based on fvwmrc_convert for fvwm-2.0.45 by"
echo "  Martin Kraemer <Martin.Kraemer@mch.sni.de>"
echo "  Grant McDorman <grant@isgtec.com>"
echo "  Bill Oswald <wamo@vnet.ibm.com>"
echo "  Charles Hines <chuck_hines@VNET.IBM.COM>"
echo ""

AWK=/usr/bin/awk

source=${1:-$HOME/.fvwmrc}
dest=${2:-$HOME/.fvwm2rc}
if [ "$dest" != "-" ] ;then
	echo "Output to $dest"
	if [ -f $dest ] ; then
	  mv $dest $dest.bak
	  echo "Saving existing $dest as $dest.bak"
	fi
	exec >$dest
fi
cat $source | $AWK '
BEGIN   {
        printf ("# Trying to compile an old .fvwrc to the  new fvwm-2.0 Format\n");
	TRUE=1; FALSE=0;

	IGNORECASE=TRUE;

	hiforecolor="";             dflt["hiforecolor"] = "black";
	hibackcolor="";             dflt["hibackcolor"] = "CadetBlue";
	hilightcolor = FALSE;

	stdforecolor="";            dflt["stdforecolor"] = "black";
	stdbackcolor="";            dflt["stdbackcolor"] = "grey70";

	menuforecolor="";           dflt["menuforecolor"] = "black";
	menubackcolor="";           dflt["menubackcolor"] = "grey70";
	menustipplecolor="";        dflt["menustipplecolor"] = "grey40";
	font="";                    dflt["font"] = "-adobe-helvetica-medium-r-*-*-18-*-*-*-*-*-iso8859-1";
	mwmmenus="";                dflt["mwmmenus"] = "fvwm";
	menustyle=FALSE;

	inpopup=FALSE;
	infunction=FALSE;
	prefix="";

        placement = FALSE;           dflt["placement"] = "ActivePlacement, DumbPlacement"
}

/^[ \t]*#/			{   # Comment, pass it thru
        print $0;
	next;
}

/^$/                            {   # Empty line, pass it thru
	print $0;
	next;
}
	
################ Rename common items ##############
/Restart/ && /fvwm/             { gsub("fvwm", "fvwm2"); } # try and leave paths alone
/GoodStuff/                     { gsub("GoodStuff", "FvwmButtons"); }

################ Highlight Colors ##############
/^[ \t]*HiBackColor[ \t]*/	{
        dflt["hibackcolor"]=hibackcolor=$2;
	printf ("#!%s (new command=HilightColor)\n", $0);
	if (hibackcolor != "" && hiforecolor != "" && !hilightcolor) {
           printf ("\n#Set the foreground and background color for selected windows\n");
	   printf ("HilightColor   %s %s\n", hiforecolor, hibackcolor);
	   hilightcolor=TRUE;
        } else
	   hilightcolor=FALSE;
        next;
}

/^[ \t]*HiForeColor[ \t]*/	{
        dflt["hiforecolor"]=hiforecolor=$2;
	printf ("#!%s (new command=HilightColor)\n", $0);
	if (hibackcolor != "" && hiforecolor != "" && !hilightcolor) {
           printf ("\n#Set the foreground and background color for selected windows\n");
	   printf ("HilightColor   %s %s\n", hiforecolor, hibackcolor);
	   hilightcolor=TRUE;
        } else
	   hilightcolor=FALSE;
        next;
}


########## Menu Colors, Style and Font ###########
/^[ \t]*MenuForeColor[ \t]*/	{
        dflt["menuforecolor"]=menuforecolor=$2;
	printf ("#!%s (new command=MenuStyle)\n", $0);
	if (menubackcolor != "" && menuforecolor != "" && menustipplecolor != "" && font != "" && mwmmenus != "" && !menustyle) {
           printf ("\n#Set the foreground, background and stipple color and font for menus\n");
	   printf ("MenuStyle   %s %s %s %s %s\n", menuforecolor, menubackcolor, menustipplecolor, font, mwmmenus);
	   menustyle=TRUE;
	} else
	   menustyle=FALSE;
        next;
}

/^[ \t]*MenuBackColor[ \t]*/	{
        dflt["menubackcolor"]=menubackcolor=$2;
	printf ("#!%s (new command=MenuStyle)\n", $0);
	if (menubackcolor != "" && menuforecolor != "" && menustipplecolor != "" && font != "" && mwmmenus != "" && !menustyle) {
           printf ("\n#Set the foreground, background and stipple color and font for menus\n");
	   printf ("MenuStyle   %s %s %s %s %s\n", menuforecolor, menubackcolor, menustipplecolor, font, mwmmenus);
	   menustyle=TRUE;
        } else
	   menustyle=FALSE;
        next;
}

/^[ \t]*MenuStippleColor[ \t]*/	{
        dflt["menustipplecolor"]=menustipplecolor=$2;
	printf ("#!%s (new command=MenuStyle)\n", $0);
	if (menubackcolor != "" && menuforecolor != "" && menustipplecolor != "" && font != "" && mwmmenus != "" && !menustyle) {
           printf ("\n#Set the foreground, background and stipple color and font for menus\n");
	   printf ("MenuStyle   %s %s %s %s %s\n", menuforecolor, menubackcolor, menustipplecolor, font, mwmmenus);
	   menustyle=TRUE;
        } else
	   menustyle=FALSE;
        next;
}

/^[ \t]*MWMMenus[ \t]*/		{
        dflt["mwmmenus"]=mwmmenus="mwm";
	printf ("#!%s (new command=MenuStyle)\n", $0);
	if (menubackcolor != "" && menuforecolor != "" && menustipplecolor != "" && font != "" && mwmmenus != "" && !menustyle) {
           printf ("\n#Set the foreground, background and stipple color and font for menus\n");
	   printf ("MenuStyle   %s %s %s %s %s\n", menuforecolor, menubackcolor, menustipplecolor, font, mwmmenus);
	   menustyle=TRUE;
	} else
	   menustyle=FALSE;
	next;
}

/^[ \t]*Font[ \t]*/		{
        dflt["font"]=font=$2;
	printf ("#!%s (new command=MenuStyle)\n", $0);
	if (menubackcolor != "" && menuforecolor != "" && menustipplecolor != "" && font != "" && mwmmenus != "" && !menustyle) {
           printf ("\n#Set the foreground, background and stipple color and font for menus\n");
	   printf ("MenuStyle   %s %s %s %s %s\n", menuforecolor, menubackcolor, menustipplecolor, font, mwmmenus);
	   menustyle=TRUE;
	} else
	   menustyle=FALSE;
	next;
}


# Translate both old ButtonStyle formats to the new format:
/^[ \t]*ButtonStyle[ \t]*/	{
        if ($2 == ":") {  # new style already
           if (NF != $4+4)
	       print "ERROR: ButtonStyle command incorrect" >"/dev/stderr";
	   printf ("%s %d %d", $1, $3, $4);
	   for (i=5; i<=NF; ++i)
	       printf (" %s", $i);
	   printf ("\n");
	} else {
           print "Note: Conversion of old ButtonStyle; values rounded" \
			>"/dev/stderr"
	   printf ("#!         Old line was: %s\n", $0);
	   p=index ($3,"x");
	   x=substr($3,1,p-1)/2;
	   y=substr($3,p+1)/2;
	   printf ("%s %s 5 %dx%d@0 %dx%d@0 %dx%d@0 %dx%d@1 %dx%d@1\n",
		    $1, $2, 50-x,50+y, 50+x,50+y, 50-x,50-y, 50+x,50-y,
		    50-x,50+y);
	}
	next;
}

########## Standard Colors ###########
/^[ \t]*StdForeColor[ \t]*/	{
        dflt["stdforecolor"]=stdforecolor=$2;
	printf ("#!%s (new command=Style \"*\" Color f/b)\n", $0);
	print "Style \"*\" ForeColor " $2;
	next;
}

/^[ \t]*StdBackColor[ \t]*/	{
	dflt["stdbackcolor"]=stdbackcolor=$2;
	printf ("#!%s (new command=Style \"*\" Color f/b)\n", $0);
	print "Style \"*\" BackColor " $2;
	next;
}

########## Icon Related Stuff ##########
/^[ \t]*IconBox[ \t]*/		{ print "Style \"*\" " $0; next; }
/^[ \t]*IconFont[ \t]*/		{ print $0; next; }
/^[ \t]*SuppressIcons[ \t]*/	{ print "Style \"*\" NoIcon"; next; }
/^[ \t]*StickyIcons[ \t]*/	{ print "Style \"*\" StickyIcon"; next; }
/^[ \t]*ModulePath[ \t]*/	{ gsub("/fvwm", "/fvwm2"); print $0; next; }
/^[ \t]*PixmapPath[ \t]*/	{ gsub("/fvwm", "/fvwm2"); print $0; next; }
/^[ \t]*IconPath[ \t]*/		{ gsub("/fvwm", "/fvwm2"); print $0; next; }
# note: Icon must be followed by some white space
/^[ \t]*Icon[ \t]+/		{ printf "Style %s Icon %s\n", $2, $3; next; }

########## MWM hints ##########
/^[ \t]*MWMFunctionHints[ \t]*/	{ printf ("Style \"*\" MWMFunctions\n"); next; }
/^[ \t]*MWMDecor[ \t]*/		{ printf ("Style \"*\" MWMDecor\n"); next; }
/^[ \t]*MWMDecorHints[ \t]*/	{ printf ("Style \"*\" MWMDecor\n"); next; }
/^[ \t]*MWMBorders[ \t]*/	{ printf ("Style \"*\" MWMBorder\n"); next; }
/^[ \t]*MWMButtons[ \t]*/	{ printf ("Style \"*\" MWMButtons\n"); next; }
/^[ \t]*MWMHintOverride[ \t]*/	{ printf ("Style \"*\" HintOverride\n"); next; }

########## Placement & Focus styles ##########
/^[ \t]*RandomPlacement[ \t]*/	{ print "Style \"*\" " $0; placement = TRUE; next; }
/^[ \t]*SmartPlacement[ \t]*/	{ print "Style \"*\" " $0; placement = TRUE; next; }
/^[ \t]*Sticky[ \t]*/		{ printf "Style \"%s\" Sticky\n", $2; next; }
/^[ \t]*NoPPosition[ \t]*/	{ print "Style \"*\" " $0; next; }
/^[ \t]*ClickToFocus[ \t]*/	{ print "Style \"*\" " $0; next; }
/^[ \t]*SloppyFocus[ \t]*/	{ print "Style \"*\" " $0; next; }
/^[ \t]*StaysOnTop[ \t]*/	{ printf "Style \"%s\" StaysOnTop\n", $2; next; }
/^[ \t]*AutoRaise[ \t]*/		{
        print "#! " $0 " (use Module FvwmAuto)";
	print "AddToFunc \"InitFunction\" \"I\" Module FvwmAuto " $2;
	print "AddToFunc \"RestartFunction\" \"I\" Module FvwmAuto " $2;
	next;
}

########## Decoration styles ##########
/^[ \t]*BorderWidth[ \t]*/	{ print "Style \"*\" " $0; next; }
/^[ \t]*HandleWidth[ \t]*/	{ print "Style \"*\" " $0; next; }
/^[ \t]*DecorateTransients[ \t]*/ { print "Style \"*\" DecorateTransient"; next; }
/^[ \t]*XORvalue[ \t]*/		{ print $0; next; }
/^[ \t]*BoundaryWidth[ \t]*/	{ printf "Style \"*\" HandleWidth %s\n", $2; next; }
/^[ \t]*NoBoundaryWidth[ \t]*/	{ print "Style \"*\" BorderWidth " $2; next; }
/^[ \t]*NoTitle[ \t]*/		{ print "Style \"*\" " $0; next; }
/^[ \t]*NoBorder[ \t]*/		{ print "Style \"*\" " $0; next; }



########## Etc ##########
/^[ \t]*Lenience[ \t]*/		{ print "Style \"*\" " $0; next; }
/^[ \t]*Style[ \t]*/		{ print $0; next; }
/^[ \t]*Key[ \t]*/		{ print $0; next; }
/^[ \t]*Mouse[ \t]*/		{
	if (sub("[ 	]Pop[uU]p[ 	]", " Menu ")) {
	    if (!warn["Mouse"]) {
		print "Note: Setting mouse bindings to sticky menus">"/dev/stderr";
		warn["Mouse"] = TRUE;
	    }
	    if (index($6, "\"") == 1) {
	       gsub("\"", "")
	       if (NF > 6) {
	          for (i = 6; i <= NF; i++)
                    sub($i " ", $i)
	       }
	    } 
	    sub("$", " Nop");
 	}
	print $0; next;
}

/^[ \t]*WindowListSkip[ \t]*/	{ printf "Style %s WindowListSkip", $2; next; }
/^[ \t]*WindowFont[ \t]*/	{ print $0; next; }
/^[ \t]*ClickTime[ \t]*/		{ print $0; next; }
/^[ \t]*OpaqueMove[ \t]*/	{ print "OpaqueMoveSize " $2; next; }
/^[ \t]*EdgeScroll[ \t]*/	{ print $0; next; }
/^[ \t]*EdgeResistance[ \t]*/	{ print $0; next; }
/^[ \t]*DeskTopSize[ \t]*/	{ print $0; next; }
/^[ \t]*DeskTopScale[ \t]*/	{
	printf ("#!%s (new command=*FvwmPagerDeskTopScale <scale>)\n", $0);
	print "*FvwmPagerDeskTopScale " $2;
	next;
}

/^[ \t]**FvwmButtons[ \t]*/	{
	sub("[ 	]Swallow[ 	]*[^ 	]*", "& Exec");
	print $0;
	if (length($0) > 199)
	{
	    print "Warning: line too long" >"/dev/stderr";
	    print ">> " $0 >"/dev/stderr";
	}
	if (!warn["GoodStuff"])
	{
	    print "Note: GoodStuff renamed to FvwmButtons" >"/dev/stderr";
	    warn["GoodStuff"]=TRUE;
	}
	next;
}

/^\*/				{
        # other Module Configuration commands are passed thru
	print $0;
	next;
}

# hack: Modules spawned outside of a function, menu, or popup cannot have leading whitespace.
# add these to the initfunction
/^Module[ \t]*/                 { printf "AddToFunc \"InitFunction\" \"I\" %s \n", $0; next; }

# hack: function declarations cannot have leading whitespace
/^Function[ \t]*/		{
	if (inpopup)
	   print "ERROR: EndPopup missing\n" NR $0 >"/dev/stderr";
	inpopup=FALSE;
	if (infunction)
	   print "ERROR: EndFunction missing\n" NR $0 >"/dev/stderr";
	infunction=TRUE;
	prefix="AddToFunc " $2;
	next;
}

/^[ \t]*EndFunction[ \t]*/	{
        if (!infunction)
           print "ERROR: EndFunction outside of function" >"/dev/stderr";
	infunction=FALSE;
	prefix="";
	next;
}

# hack: popup declarations cannot have leading whitespace
/^Popup/                        {
        if (inpopup) 
	   print "ERROR: EndPopup missing\n" NR $0 >"/dev/stderr";
        if (infunction)
	   print "ERROR: EndFunction missing\n" NR $0 >"/dev/stderr";
        infunction=FALSE;
	inpopup=TRUE;

	if (index($2, "\"") == 1) {
	   tstr = ""
	   for (i = 2; index(substr($i, 2), "\"") < length($i) && i <= NF; i++)
              tstr = sprintf("%s%s", tstr, $i);
	   prefix = "AddToMenu " substr(tstr, 2, length(tstr) - 2)
        } else
	   prefix="AddToMenu " $2;
	next;
}

/^[ \t]*EndPopup[ \t]*/		{
        if (!inpopup)
	   print "ERROR: EndPopup outside of popup" >"/dev/stderr";
        inpopup=FALSE;
	prefix="";
	next;
}



########## Deleted Commands ##########
/^[ \t]*DontMoveOff[ \t]*/	||
/^[ \t]*BackingStore[ \t]*/	||
/^[ \t]*AppsBackingStore[ \t]*/	||
/^[ \t]*SaveUnders[ \t]*/	||
/^[ \t]*StubbornIcons[ \t]*/	||
/^[ \t]*StubbornIconPlacement[ \t]*/ ||
/^[ \t]*StubbornPlacement[ \t]*/     ||
/^[ \t]*Cursor[ \t]*/		{ 
	print "#! " $0 " [deleted]";
	if (warned[$1]==FALSE) {
	   print "Warning: " $1 " not in Fvwm2, command dropped" >"/dev/stderr";
	   warned[$1] = TRUE;
	}
	next;
}

/^[ \t]*Pager[ \t]*/		{
        print "#! " $0 " [deleted]";
	if (warned[$1]==FALSE) {
           print "Warning: " $1 " omitted, internal pager is obsolete (use FvwmPager)" >"/dev/stderr";
	   warned[$1] = TRUE;
	}
	next;
}

/^[ \t]*PagingDefault[ \t]*/	||
/^[ \t]*TogglePage[ \t]*/	{
        print "#! " $0 " (use EdgeScroll 0 0)"; next;
	print "Warning: " $1 " not in Fvwm2, use EdgeScroll">"/dev/stderr";
}

########## Old Internal Pager Colors ###########
/^[ \t]*PagerForeColor[ \t]*/	||
/^[ \t]*PagerBackColor[ \t]*/	{
	printf ("#!%s (new command=Style FvwmPager Color fore_color/back_color)\n", $0);
	if (warned[$1]==FALSE) {
           print "Warning: " $1 " omitted, internal pager is obsolete (use FvwmPager)" >"/dev/stderr";
	   warned[$1] = TRUE;
	}
	next;
}

########## Sticky Colors ###########
/^[ \t]*StickyForeColor[ \t]*/	{
	printf ("#!%s (no sticky foreground color in fvwm2)\n", $0);
	if (warned[$1]==FALSE) {
	   print "Warning: StickyForeColor not in fvwm2, omitted" > "/dev/stderr"
           print "         Use the Style command to assign each sticky window the same ForeColor" > "/dev/stderr"
        }
	next;
}

/^[ \t]*StickyBackColor[ \t]*/	{
	printf ("#!%s (no sticky background color in fvwm2)\n", $0);
	if (warned[$1]==FALSE) {
	   print "Warning: StickyBackColor not in fvwm2, omitted" >"/dev/stderr"
           print "         Use the Style command to assign each sticky window the same BackColor" > "/dev/stderr"
        }
	next;
}


{
    if (infunction) {
        #gsub("[ 	]PopUp[ 	]", " "); }
	if ($2 == "\"Motion\"")
	    context="\"M\"";
	else if ($2 == "\"Click\"")
	    context="\"C\"";
	else if ($2 == "\"DoubleClick\"")
	    context="\"D\"";
	else if ($2 == "\"Immediate\"")
	    context="\"I\"";
	else context=$2;
		printf "%s", prefix " " context " " $1;
	for (i=3; i<=NF; ++i)
	    printf (" %s", $i);
	printf ("\n");
	prefix="+             ";
	next;
    } else if (inpopup) {
	# not going to handle escaped quotes
	label=$2;
	first=3;
	quoted=substr(label, 1, 1)=="\"" &&
		substr(label, length(label), 1)!="\"";
	for (i=3;i<=NF && quoted;i++) {
	    label=label " " $i;
	    quoted=substr(label, length(label), 1)!="\"";
	    first=i + 1;
	}
	printf ("%s %s %s", prefix, label, $1);
	for (i=first; i<=NF; ++i)
	    printf (" %s", $i);
	printf ("\n");
	prefix="+             ";
	next;
    }

    if (warned[$1]==FALSE) {
	printf ("#!Warning: Keyword \"%s\" not handled yet\n", $1);
	warned[$1]=TRUE;
	print "Warning: Unknown keyword "$1" passed through">"/dev/stderr";
    }
    print $0;
    next;
}

END {
    if (!menustyle) {
	printf ("\n#Set the foreground, background and stipple color and font for menus\n");
	printf ("MenuStyle   %s %s %s %s %s\n", dflt["menuforecolor"], dflt["menubackcolor"], dflt["menustipplecolor"], dflt["font"], dflt["mwmmenus"]);
    }
    if (!hilightcolor) {
	printf ("\n#Set the foreground and background color for selected windows\n");
	printf ("HilightColor   %s %s\n", dflt["hiforecolor"], dflt["hibackcolor"]);
    }
    if (!placement) {
        printf "# overide default RandomPlacement and SmartPlacement Styles\n";
        printf "Style \"*\" %s\n", dflt["placement"];
    }
}
'
exit

