This "package" is inspired by the install-fvwm2-menu from the debian fvwm2,
but it tries to provide a somewhat more general interface for
menu-building. With the update-menus command from this package,
(and the /usr/lib/menu/$package files),
no package needs to be modified for every X window manager again,
and it provides a unified interface for both text- and X-oriented
programmes.

************************
*It works like this:

Each package includes a file in /usr/lib/menu/package-name. In this
file, it will have one line per menu-entry, like this (from
/usr/lib/menu/xpuzzles):
   X11 Apps/Games/Puzzles xtriangle none "Xtriangle" /usr/games/xtriangles
   
This describes the type of interface the package needs (X11),
the menu section the menu entry should be in, an id, possibly
an icon, the menu text, and the command that should be executed.

Whenever root runs update-menus, it will check all new or
changed menufiles in /etc/menu and /usr/lib/menu,
and run the installation scripts display managers like fvwm2
should provide in /etc/menu-methods on them.

The menu package itself provides a set of default menu files,
for people to get the idea, and to speed things up a bit
(These files should be incorporated into the package).

************************
* (User-) Configuring the menu's

A user can specify her/his own menu entries in the ~/.menu directory.
the files in that directory should have names of installed packages, or
"local.name", as update-menus assumes any "package" who's name starts
with "local" is installed.

A system admin should place system-wide menuentries in /etc/menu, 
(not in /usr/lib/menu/package, those will be overridden after an upgrade 
of package). Again, filenames must have a name of an installed package,
or starting with "local".

************************
* Specifying "No-menu-entry"

If a user wants to remove an entry from the system menu (in /etc/menu),
then this will do the trick:
  echo -n  > ~/.menu/package
The zero-size file will tell update-menus that the corresponding
package should not have any menu-entries listed.

************************
* What should the each package do to use this:

-Include a conffile file in /etc/menu/$package.
 The name of the file should be $package, with $package the
 package name of the binary package the menufile will be distributed
 in. (in the case of single source packages that build many binary packages).
 This file should contain, for each programme it likes to make
 available in a menu:
   text Math gnuplot  none  "Gnuplot"  /usr/bin/gnuplot      
     ^   ^     ^      ^       ^    ^
     |   |     |      |       |     The binary to be executed
     |   |     |      |	      The menu-entry-name
     |	 |     |      The pixmap in the menu entry
     |   |     Some ID for this menu entry. .Please make this
     |   |     ${package}/someid, where ${package} is the package name of the
     |	 |     package the menu file will be distributed in, as
     |	 |     we may require this later.
     |   The section in which the menu entry should appear
     Type: X11 if this programme only runs on X11 displays
           text if it only runs on text-oriented terminals;
	        (the window manager should spawn an
		 xterm or rxvt in this case)
           vc   if the program only runs at the Linux console (i.e.: svgalib)

 A programme like gnuplot should NOT have an extra entry for
 X11 like this:	         	     	 
   X11 Apps/Math gnuplot  none "Gnuplot" "xterm -e /usr/bin/gnuplot"
 because it will then be next to impossible to configure the
 window mangers to spawn rxvt instead.
 
 If, on the other hand, a programme can both run like a real
 X application, and on a terminal (like emacs), then two
 entries should be listed (otherwise, emacs will also be run in
 an xterm).

-In your postinst and postrm script, add a line like:
  if test -x /usr/bin/update-menus; then update-menus; fi

-Do not make your package depend on the menu package.

************************
* The preferred layout of the menu (currently suggestion only):

       Apps            -- all normal apps
         Editors       -- editors (run it in xterm, if nothing else)
         Net           -- mail, news, web, irc, etc
         Programming   -- debuggers, etc
         Shells        -- Different shells, like bash, ksh, zsh, ...
         Tools         -- other tools: xclock, xmag, xman,
         Viewers       -- Picture viewers, gs, ...
         Math          -- Math apps like: gnuplot, octave, oleo,..
         Graphics      -- xpaint, xfig, xtiff, 
         Emulators     -- Dosemu, ...
         Sound         --
         System        -- system administration and monitoring
       Games           -- games and recreations
         Adventure     -- walk around virtual space, zork, MOO's, etc
         Arcade        -- (any game where reflexes count)
         Board         -- Like: Gnuchess, pente, gnugo
         Card          -- solitaire, etc
         Puzzles       -- Stuff from xpuzzles, ...
	 Sports        -- Games derived from "real world" sports
	 Strategy      -- Build your world (Games like lincity, freeciv)
         Tetris-like   -- games involving falling blocks
         Toys          -- (oneko, xeyes, etc.)
       Screen          --
         Lock          -- xlock, etc.
         Screen-saver  --
         Root-window   -- things that fill the root window
       Window-managers -- (change between fvwm, afterstep, etc)
         Modules       -- fvwm modules, etc. 
       XShells         -- shells (like xterm, rxvt, ...)
                          (running the user's login shell in them).

   This is basically what Joey Hess posted on debian-devel, with
   Also, I moved the shells to the root, as I don't like to have to
   go two levels deep for my shell -- but if others prefer that, I'll
   happily revert this (and I moved xclock in tools, is that OK?)

************************
* What should each menu-manager (fvwm*, twm, pdmenu, ...) do?

Provide a configfile-script in /etc/menu-methods that can read 
the menu-files. This script will be executed by update-menus
with the to be installed menu-entries passed to the script via
stdin.

The scripts in /etc/menu-methods should be configfiles, if the user
can tune the behaviour in the script (as is the case in the scripts
provided in this package in /usr/share/doc/menu/examples/$wm).

Run update-menus (if it exists) in the postinst, and remove the
execute bit from the /etc/menu-methods in the postrm when called
with remove. 
Example bash post{rm,inst} script:

#postrm:
 #!/bin/sh
 set -e
 inst=/etc/menu-methods/twm  #or fvwm, ... whatever manager you're installing
 case "$1" in
     remove)
         chmod a-x $inst
     ;;
     purge)
         #remove the files that install-fvwmgenmenu creates:
         rm /etc/X11/twm/{system.twmrc,menus.dat,menudefs.hook}
         #maybe also rm $inst, if dpkg doesn't do that itself.
     ;;
     upgrade);;
     *)
         echo "postrm called with unknown argument \`$1'" >&2
         exit 0
     ;;
 esac

#postinst:
 #!/bin/sh
 set -e
 inst=/etc/menu-methods/pdmenu #or fvwm, ... whatever manager you're installing
 if [ -x /usr/bin/update-menus ] ; then 
   if [ -f $inst ]; then
       chmod a+x $inst
       update-menus; 
   fi  
 fi

The menu package should not include any installer scripts for
window managers (that's the job of the packages that install the
window managers), but I do provide scripts for nearly all
debian window managers in /usr/share/doc/menu/examples. See the readme
on how to activate them. For an example, see the latest fvwm95 package
(or olvwm).

************************
* Options to update-menus
  
  -v         verbose (generate a lot of output)
  -d         debug (loads of more output)
  --show-time

************************
* What does update-menus do?

when update-menu starts, it:
  1 sets a variable $dirs to 
         dirs="/etc/menu /usr/lib/menu /usr/lib/menu/default"
      (and if a user runs runs it, it will add ~/.menu to the front
      of that list)
  2 it reads the list of installed packages.
  3 for d in $dirs; do
     - read files in $d
     - check if corresponding package is installed, and, is listed
       in the $d/.updated-menus file, checking the mod time in 
       $d/.updated-menus.
       Depending on that information, either put the menufile $file in the
       the install-menu-list, or the menuentry in the $remove-entries,
       and do put the entries in the  already-correctly-installed-list
  4 after going through all dirs, do
      for method in `ls /etc/menu-methods`; do
	$cat install-menu-list | method -f --stdin 
      done

Ad step 3+4
  - The $d/.updated-menus file lists not only the files in that directory
    and it's mod-time (to check for changes), it also lists
    the known menu-managers (i.e., the output of `ls /etc/menu-methods`)
    at the time of the last installation. Based on this information,
    steps 3+4 are changed a bit, to update/remove new/old menu-managers.
Ad step 1+2+3+4
  although I've used a sh-like syntax here, it's written in C++.

************************
* The /usr/sbin/install-fvwmgenmenu programme

The files /etc/menu-methods/fvwm* are "executable" config files
that begin with
 #!/usr/sbin/install-fvwmgenmenu
and thus start that programme, handing it the configuration file for the
specific wm in argv[1]. This configuration consists of:
 - the compatibility mode (used to be fvwm, 9wm, .. but now "gen" for all wm's)
 - where the various files should be stored/read.
 - what "types" are supported, and what wrapper files should
   be used for each "type".
See /usr/share/doc/menu/examples/ for some more comments.

Options to install-fvwmgenmenu:
  -v              be verbose
  -d              Produce loads of debugging output
  -f              (always) force install (assume no packages are installed)
  --install-files take the next arguments to be files woos menuentries
                  should be installed
  --stdin         (always) read menuentries from stdin.

The -f and --stdin "options" exist because old versions used to
have cache files and other complicated stuff. This didn't result
in any speedups, and did complicate stuff. So we (Joey and I) decided
to make -f and --stdin options that are always on (and can thus be
ignored).

Some window managers  don't support the m4 or cpp
preprocessing, and cannot read the menudefs.hook file
from their system.*rc configfile. To still be able to use them,
install-fvwmgenmenu will copy the file $path/$examplercfile to
$path/$rcfile (with $path, $examplercfile and $rcfile defined 
in the install-fvwmgenmenu config file), and replace all 
occurrences of "install-menu-defs" with the $genmenu
file it just generated. Although this approach looks quite 
clumsy, it does allow for one $path/$examplercfile on the system,
(The m4/cpp approach puts a "include(/etc/X11/*/menudefs.hook)"
in the system.*rc file, so users will never load their menudefs.hook
file).
To activate the file-copying in this way, simply define
the $examplercfile and $rcfile variables in the install-fvwmgenmenu
configuration file (/etc/menu-methods/fvwm*), and make sure
there is a $path/$examplercfile ($path being either $rootprefix, or
$userprefix)


************************
* "supported" section  in the install-fvwmgenmenu config files.

Each definition defines a display type that this window-manager supports.
After the displaytype is the string that should be printed in the
system."$wm"rc file for each menu entry that matches that display type.

Install-fvwmgenmenu does the following variable expansions:
 variable in conffile     expands to        in example below this is:
   -                        -                     -  
  ${title}          ->    menutitle          Xtriangle
  ${section}	    ->	  lastpartofsection  Puzzles
  ${fullsection}    ->    full section	     Apps/Games/Puzzles
  ${id}		    ->	  menuentry id       xtriangle
  ${icon}	    ->	  icon		     none
  ${command}	    ->	  command	     /usr/games/xtriangles
  ${type}	    ->    type               X11

Example (see table above):
  X11 Apps/Games/Puzzles xtriangle none "Xtriangle" /usr/games/xtriangles

(where in the title, menu, ... are taken from the menuentry in the menufile).
As a special exception, if no "${command}" occurs in the wrapper, 
" ${command}" is added at the end, so empty wrapper files will at least
hand the command. A similar exception is made for "${title}" in the
fvwm2 compat mode.

Along the lines of ${var}, you can also use:

         example  example         example    purpose:
${var}   var	  "var"+'v'       none    |   just expand var
$d{var}  var	  \"var\"+'v'	  none	  |   escape Double quotes
$s{var}  var      "var"+\'v\'	  none	  |   escape Single quotes
$b{var}  var	  \"var\"+\'v\'   none	  |   escape Both single and double q
$%{var}  %var%	  %"var"%                 |   for icons

(In this table, the first line lists the value of ${var}, and the
other lines list what $d{var}, ... would have produced).

strings like \\n, \\t, ... for their ordinary will be substituted for
their C expansions (But not \0xx).

Note: the above only holds for "compat=gen". the other compat modes
will be disabled in the future, and currently don't support everything
that's described above

************************
* Other install-fvwmgenmenu config script items:
*
compat
  Please make this "gen" only. (Old versions of install-fvwmgenmenu
  used to take other compats, but "gen" is much more general).

startmenu
endmenu
submenutitle
  These define what to print for the beginning/end of a menu, and
  how to the print a menuentry that pops up another menuentry.
  They are substituted the same way as the "supported" stuff is.

treewalk:
  This string defines in what order to dump the $startmenu, $endmenu,
  and $submenutitle (and it's children). Each char in the string
  refers to :
    c  : dump children of menu.
    m  : dump this menu's $submenutitles
    (  : dump $startmenu
    )  : dump $endmenu
    M  : dump all $submenutitles of this menu and this menu's children.    
  The default is "c(m)". For olvwm, one needs: "(M)"

database:
  A cache file (old).

genmenu:
  The menufile to generate (usually something like system."$wm"rc).

rcfile:
  If the window manager doesn't support an "include filename" or
  "read(filename)" statement in it's config file, you can rename
  the wm's config file to system."$wm"rc-menu, and insert
  a "install-menu-defs" line (without the quotes, or whitespace around
  it, and "install-menu-defs" must be the only thing on the line)
  in the system."$wm"rc-menu file. This will then get replaced
  by the $genmenu file that was just created (see also $examplercfile).
  
examplercfile:
  if needed (see rcfile), this is the system.rc"$wm"-menu file.
  In that case, make rcfile=system.rc"$wm".

rootprefix:
  The prefix to use when running as root (applies to $genmenu, $rcfile,
  $examplercfile  and other old cache files)

userprefix:
  see rootprefix, but when running as user.

************************
* Icons
*

Please, make sure the icons you specify are always available on the system.
So, if you want to have an icon with your menuentry, the preferred method
is to supply the icon with that package. Also, to prevent the distribution
of icons files to turn too much into a mess, please put all icon
files in /usr/X11R6/include/X11/{bitmap,pixmap}.

If you, as a system admin, don't like the icons in the menu's, simply
remove the $%{icon} from the files in /etc/menu-methods/$wm, and 
type "update-menus"


If you want to specify an icon for a submenu (for example, the Editors 
submenu), just use the same syntax but leave the command empty:

  X11 Apps menu/apps /usr/X11R6/include/X11/pixmap/icon.xpm "Editors"

As there probably isn't one right package to include the submenu icons,
I guess (as Joey suggested) the menu package is the only right place
to have these menu's (Otherwise, problems arise when two packages
supply different icons for the same submenu, and we can never be sure
the icon files are available).


************************
* Taskbar/Titlebar (fvwm*)
*

The problem with the stuff in the taskbar is that all items are
displayed all of the time. So, if 200 debian packages all were to
register a button, the buttons would quickly fill the screen, making
the exercise useless. The few applications that are considered important
enough to be listed in the taskbar usually vary widely on each system,
making it impossible to select a ``happy few'' apps that are allowed
there on every debian system. If you want your fvwm2 to have a few
buttons, you can install files for those packages in /etc/menu/$package,
containing both the normal menu entries, and a line like
  button Games/Puzzles  xpuzzles/xmball   path-to-pixmap.xpm "Xmball"  /usr/games/xmball

Then, do the following:
cd /etc/menu-methods/
cp fvwm2 fvwm2button
vi fvwm2button
#and remove all the "supported" entries, adding the one below. For the rest,
leave everything the same except those listed below.

supported 
  button="+ Style \"${title}\" TitleIcon ${icon} Exec ${command}\\n"
endsupported
startmenu:   "AddToTitlebar \\n"
endmenu:     "\\n"
submenutitle:""
mainmenu:
genmenu:   "buttondefs.hook"



