Add "BugOpts QtDragnDropWorkaround"
[fvwm.git] / bin / fvwm-menu-desktop.in
blob08905cfd46146c7c82b15ca90bf36f4078317e1b
1 #!@PERL@
3 # ---------------------------------------------------------------------------
4 #  fvwm-menu-desktop
5 #  See the man page fvwm-menu-desktop.1 for instructions.
7 #  Created on 22/07/1999 by Olivier Chapuis
9 #  Updated on 15/08/1999 by Mikhael Goikhman
11 # ---------------------------------------------------------------------------
12 # COPYING
14 # The script is distributed by the same terms as fvwm itself.
15 # See GNU General Public License for details.
17 #----------------------------------------------------------------------------
18 # The script: Main
20 #--------
21 # Modules
22 use strict;
23 # For command line options
24 use Getopt::Long;
26 my $version = "@VERSION@";
28 #--------
29 # Defaults (most of them can be modified with the options)
31 # paths
33 my $GNOME_PREFIX = '/usr';              # gnome install-dir
34 # Default is "gnome" since fvwm is gnome compliant and not kde compliant.
35 my $APPS_DIR = -d "$GNOME_PREFIX/share/gnome/apps" ? 
36     "$GNOME_PREFIX/share/gnome/apps" :
37     "$GNOME_PREFIX/share/gnome/applications";
38 my $GNOME_APPS = $APPS_DIR;
39 my $KDE_PREFIX = $ENV{KDEDIR} || '/usr';
40 my $KDE_APPS = "$KDE_PREFIX/share/applnk";
41 my $KDE_MINI_ICONS = "$KDE_PREFIX/share/icons/mini/";
42 my $KDE3_MINI_ICONS = "$KDE_PREFIX/share/icons/hicolor/16x16/apps/";
43 my $KDE_ICONS = "$KDE_PREFIX/share/icons/";
44 my $KDE3_ICONS = "$KDE_PREFIX/share/icons/hicolor/48x48/apps/";
45 my $OPT_INSTALL_PREFIX = '';
47 # Default for the mini-icons is mini/ (relatively to the ImagePath)
48 my $MINI_ICONS_DIR = 'mini/';
49 # Then the default for icon is ImagePath (consistent with kde, fvwm2gnome
50 # and almost consistent with wm-icons)
51 my $ICONS_DIR = '';
52 # For png icons
53 my $PNG_ICONS = '';
54 # Default for mini-icons and icons translation
55 my $TRAN_MINI_ICONS = 'mini/';
56 my $TRAN_ICONS = '';
58 #Unused path at the present time
59 #$GNOME_ICONS = "$GNOME_PREFIX/share/pixmaps/";
61 # Name
62 my $MENU_TITLE = 'Gnome System Menu';  # default top title
63 my $MENU_NAME  = 'gnome-sys';   # default top menu name
64 my $MENU_TYPE  = 'fvwm';        # default menu type
65 my $DESKTOP    = '';            # will contain Kde or Gnome if possible
66 my $OPT_MENU_TITLE = '';
67 my $OPT_MENU_NAME  = '';
68 my $fvwmgtk_name = "FvwmGtk";   # FvwmGtk module name
70 # Default "icon"
72 # mini-icons default (app for application, folder for folder, title for
73 # submenu title, toptitle for the top title, fvwm_ for fvwm menu, gtk_ for
74 # FvwmGtk menu) the variable $flag will be fvwm_ or gtk_. Use kde
75 # default icons for fvwm menus and gnome icons for gtk menus
76 my %DI;
78 $DI{fvwm_app}      = 'mini-x.xpm:dh:%::'; # micon:law:placement:unused
79 $DI{fvwm_folder}   = 'folder.xpm:dh:%::'; # idem
80 $DI{fvwm_title}    = 'folder.xpm:dh:%::'; # micon:law:place:spic:color
81 $DI{fvwm_toptitle} = 'mini-k.xpm:no:%::'; # idem
82 $DI{gtk_app}       = 'gnome-default.png:dh:::'; # idem
83 $DI{gtk_folder}    = 'gnome-folder.png:dh:::';  # micon:law:unused
84 $DI{gtk_title}     = 'gnome-folder.png:dh:::';  # idem
85 $DI{gtk_toptitle}  = 'gnome-logo-icon-transparent.png:no:::'; # idem
87 my @list=();
88 my $i='';
90 my %dmicon;
91 my %law;
92 my %place;
93 my %spic;
94 my %scolor;
96 foreach $i (keys(%DI)) {
97         @list = split(':',$DI{$i});
98         $dmicon{$i} = $list[0]; # "default" mini-icon
99         $law{$i}    = $list[1]; # default law
100         $place{$i}  = $list[2]; # default position
101         $spic{$i}   = $list[3]; # sidepic icon
102         $scolor{$i} = $list[4]; # color for sidepic
103         $DI{$i} = '';
104 }       
106 my $MINI_ICONS = 0;             # mini-icon disabled  (enable =1)
107 my $TRAN       = 0;             # mini-icon translation disabled (enable =1)
108 my $wm_icons   = 0;             # use wm-icons compatible menu icon names
111 # default for style
112 my %dstyle;
113 $dstyle{mini_icon} = 'mini-x.xpm'; # default MiniIcons Style
114 $dstyle{gnome_mini_icon}  = 'gnome-default.xpm';
115 $dstyle{icon}      = 'x.xpm';   # default Icons Style
116 $dstyle{gnome_icon}       = 'gnome-default.xpm';
117 my $style_law   = 'dh';         # default law
118 my $addstyle    = '';           # a style to add every where
119 my $STYLE       = 0;            # style is disable (enable =1)
120 my $TRAN_STYLE  = 0;            # translation for style is disabled (enable =1)
121 my $STYLEOUTPUT = '';           # The styles are in this variable
122 my $ICON_STYLE  = '';
125 # default term for runnig applications in a terminal
126 my $TERM_CMD = "xterm -e";
129 # Other stuff
130 my $timelimit = 15;                    # limit runing time for the script
131 my $LANG      = $ENV{LANG} || "";      # Internationalization support :o)
132 my $UTF8      = 0;                     # KDE2 use UTF-8
133 my $UTF8_TR   = "";                    # charset type for UTF-8 translation
134 my $UNICONV   = "";                    # use a convert tool for UTF8 tr
135 my $UNICONV_EXEC = "";                 # iconv, uniconv or internal
136 my @PATH_DIRS = split(':',$ENV{PATH}); # for checking if applications exist
137 my $CHECK     = 1;                     # we check by default
138 my $MENU_DESTROY = '';
139 my $DESC_DIR = '';
140 my $SUBMENUS_PREFIX = '';
142 # Menu Style option
143 my $MENU_STYLE = "";
144 my @menus_for_style = ();
146 my $name = "";
147 my $l = "";
148 my $j = "";
149 my $tmp_icon ="";
150 my $level = 0;
151 my $nlevel = 0;
152 my $top_level = 0;
153 my $cdir = "";
154 my $dir = "";
155 my @Rec_Dir_List = ();
156 my @Main_List = ();
157 my $flag = "";
158 my $order ="";
159 my $add = 1;
160 # merge usr menu
161 my $merge_user_menu = 0;
162 my $merge_dir = "";
163 my $merge_user_dir = "";
164 my $sys_dir = "";
165 my $merge_dir_type = "";
166 my $user_menu_done = 0;
167 # check icons
168 my $check_icons = "";
169 my $check_mini_icons = "";
170 my @check_icons_path = ();
171 my @check_mini_icons_path = ();
173 #--------
174 # Read the options
176 GetOptions(
177         "help|h|?"                 => \&show_help,
178         "version|v|V"              => \&show_version,
179         "install-prefix:s"         => $OPT_INSTALL_PREFIX,
180         "desktop:s"                => \$MENU_NAME,
181         "type:s"                   => \$MENU_TYPE,
182         "fvwmgtk-alias=s"          => \$fvwmgtk_name,
183         "title:s"                  => \$OPT_MENU_TITLE,
184         "name:s"                   => \$OPT_MENU_NAME,
185         "enable-mini-icons"        => \$MINI_ICONS,
186         "enable-tran-mini-icons"   => \$TRAN,
187         "mini-icons-path:s"        => \$MINI_ICONS_DIR,
188         "png-icons-path:s"         => \$PNG_ICONS,
189         "tran-mini-icons-path:s"   => \$TRAN_MINI_ICONS,
190         "icon-toptitle:s"          => \$DI{"fvwm_toptitle"},
191         "icon-title:s"             => \$DI{"fvwm_title"},
192         "icon-folder:s"            => \$DI{"fvwm_folder"},
193         "icon-app:s"               => \$DI{"fvwm_app"},
194         "enable-style"             => \$STYLE,
195         "enable-tran-style"        => \$TRAN_STYLE,
196         "icon-style:s"             => \$ICON_STYLE,
197         "icons-path:s"             => \$ICONS_DIR,
198         "tran-icons-path:s"        => \$TRAN_ICONS,
199         "submenu-name-prefix:s"    => \$SUBMENUS_PREFIX,
200         "dir:s"                    => \$DESC_DIR,
201         "destroy-type:s"           => \$MENU_DESTROY,
202         "xterm:s"                  => \$TERM_CMD,
203         "lang:s"                   => \$LANG,
204         "utf8"                     => \$UTF8,
205         "uniconv=s"                => \$UNICONV,
206         "uniconv-exec=s"           => \$UNICONV_EXEC,
207         "menu-style=s"             => \$MENU_STYLE,
208         "check-app!"               => \$CHECK,
209         "wm-icons"                 => \$wm_icons,
210         "time-limit=s"             => \$timelimit,
211         "merge-user-menu"          => \$merge_user_menu,
212         "check-mini-icon=s"        => \$check_mini_icons,
213         "check-icons=s"            => \$check_icons,
214 ) || wrong_usage();
215 wrong_usage() if @ARGV;
217 die "fvwm-menu-desktop: Incorrect alias ($fvwmgtk_name) is given\n"
218         if $fvwmgtk_name !~ /^\w[\w\d\.-]*$/;
220 sub print_module_config (@) {
221         foreach (@_) {
222                 print "*${fvwmgtk_name}: $_\n";
223         }
226 #--------------------------------
227 # INITIALISATION of the variables
229 # for limiting running time to $timelimit
230 my $startime = time;
231 $timelimit = 300 if $timelimit <= 0 || $timelimit > 300;
233 # see if we build a gnome or a kde menu.
234 $DESKTOP = 'Kde'   if ( $MENU_NAME =~ /kde/ );
235 $DESKTOP = 'Gnome' if ( $MENU_NAME =~ /gnome/ );
237 if ( $OPT_INSTALL_PREFIX ne '' ) {
238         $APPS_DIR = $GNOME_APPS = "$OPT_INSTALL_PREFIX/share/gnome/apps";
239         $KDE_APPS = "$OPT_INSTALL_PREFIX/share/applnk";
240         $KDE_MINI_ICONS = "$OPT_INSTALL_PREFIX/share/icons/mini";
241         $KDE3_MINI_ICONS = "$OPT_INSTALL_PREFIX/share/icons/hicolor/16x16/apps/";
242         $KDE_ICONS = "$OPT_INSTALL_PREFIX/share/icons";
243         $KDE3_ICONS = "$OPT_INSTALL_PREFIX/share/icons/hicolor/48x48/apps/";
244         #$GNOME_ICONS = "$OPT_INSTALL_PREFIX/share/pixmaps";
247 if ( $MENU_TYPE eq 'gtk' ) {
248         $flag ='gtk_';
249         $MENU_DESTROY = 'no'  if ( ! $MENU_DESTROY =~ /^y/ );
250 } else {
251         $flag ='fvwm_';
252         $MENU_DESTROY = 'yes' if ( !($MENU_DESTROY =~ /^n/
253                 || $MENU_DESTROY =~ /^d/) );
256 if ( $MENU_NAME eq 'gnome-sys' && $merge_user_menu) {
257         $merge_user_dir = "$ENV{HOME}/.gnome/apps";
260 if ( $MENU_NAME eq 'gnome-user' ) {
261         $APPS_DIR   = "$ENV{HOME}/.gnome/apps";
262         $MENU_TITLE = 'Gnome User Menu';
265 if ( $MENU_NAME eq 'gnome-redhat' ) {
266         $APPS_DIR   = "$ENV{HOME}/.gnome/apps-redhat";
267         $MENU_TITLE = 'Gnome RedHat Menu';
269 if ( $MENU_NAME eq 'gnome-mandriva' ) {
270         $APPS_DIR   = "$ENV{HOME}/.gnome/apps-mdk";
271         $MENU_TITLE = 'Gnome Mandriva Menu';
274 if (! -d $KDE_APPS)
276         $KDE_PREFIX = '';
279 if ( $DESKTOP eq 'Kde' && $KDE_PREFIX eq '' && $DESC_DIR eq '') {
280         die "fvwm-menu-desktop: It seems that kde is _not_ installed on your\n"
281                 . "machine! If it is, please use the --install-prefix or the\n"
282                 . "--dir option (see the man page).\n";
285 if ( $MENU_NAME eq 'kde-sys' ) {
286         $APPS_DIR   = $KDE_APPS;
287         $MENU_TITLE = 'Kde System Menu';
288         if ($merge_user_menu) {
289                 $merge_user_dir = "$ENV{HOME}/.kde/share/applnk";
290         }
293 if ( $MENU_NAME eq 'kde-user' ) {
294         $APPS_DIR   = "$ENV{HOME}/.kde/share/applnk";
295         $MENU_TITLE = 'Kde User Menu';
298 if ( $DESC_DIR ne '') {
299         $APPS_DIR   = $DESC_DIR;
300         $DESC_DIR   =~ s/\/*$//;
301         $name       = substr($DESC_DIR,rindex($DESC_DIR,'/')+1);
302         $DESKTOP    = 'Kde' if ( $DESC_DIR =~ /kde/ && $DESKTOP eq '');
303         $DESKTOP    = 'Gnome' if ( $DESC_DIR =~ /gnome/ && $DESKTOP eq '');
304         $MENU_NAME  = $MENU_TITLE = "$name";
305         if ( $DESKTOP ne '' ) {
306                 $MENU_NAME  = "$DESKTOP-$MENU_NAME";
307                 $MENU_TITLE = "$DESKTOP $name";
308         }
311 # Menu Title is recomputed later if $opt_menu_name is undefined
312 # (try to use Desktop hints).
313 $MENU_NAME  = $OPT_MENU_NAME  if ( $OPT_MENU_NAME ne '' );
314 $MENU_TITLE = $OPT_MENU_TITLE if ( $OPT_MENU_TITLE ne '' );
316 # Prefix for submenu:
317 if ($SUBMENUS_PREFIX ne '')  { $SUBMENUS_PREFIX = "$SUBMENUS_PREFIX-" }
318 else { $SUBMENUS_PREFIX = "$MENU_NAME-" }
321 # ---------
322 # Icon init
324 if ($wm_icons) {
325         $MINI_ICONS = 1;
326         $MINI_ICONS_DIR = "";
327         $DI{"fvwm_toptitle"} = "menu/folder-open.xpm:ow";
328         $DI{"fvwm_title"}    = "menu/folder-open.xpm:ow";
329         $DI{"fvwm_folder"}   = "menu/folder.xpm:ow";
330         $DI{"fvwm_app"}      = "menu/utility.xpm:ow";
333 if ( $TRAN ) { $MINI_ICONS = 1 }
335 if ( $MINI_ICONS_DIR ne 'mini/' || $ICONS_DIR ne '') {
336         if ($MINI_ICONS_DIR ne '' ) { $MINI_ICONS_DIR =~ s/\/*$/\// };
337         if ( $ICONS_DIR eq '' ) {
338                 $ICONS_DIR = up_directory($MINI_ICONS_DIR)
339         } else {
340                 if ( $ICONS_DIR eq 'inpath' ) { $ICONS_DIR = '' }
341                 else { $ICONS_DIR =~ s/\/*$/\//  if ($MINI_ICONS_DIR ne '' ) }
342         }
345 if ( $TRAN_MINI_ICONS ne 'mini/' || $TRAN_ICONS ne '' ) {
346         if ($TRAN_MINI_ICONS ne '' ) { $TRAN_MINI_ICONS =~ s/\/*$/\// };
347         if ( $TRAN_ICONS eq '' ) {
348                 $TRAN_ICONS = up_directory($TRAN_MINI_ICONS)
349         } else {
350                 if ( $TRAN_ICONS eq 'inpath' ) { $TRAN_ICONS = '' }
351                 else { $TRAN_ICONS =~ s/\/*$/\// if ($TRAN_ICONS ne '' ) }
352         }
355 $PNG_ICONS =~  s/\/*$/\// if ($PNG_ICONS ne '');
357 # init default mini-icons, law, place, sidepic, color
359 foreach $i (qw(folder title toptitle app)) {
360         $DI{"gtk_$i"} =  $DI{"fvwm_$i"};
363 if ( $flag eq 'gtk_') {
364         foreach $i (qw(gtk_app gtk_folder gtk_title gtk_toptitle)) {
365                 $dmicon{$i} = "$PNG_ICONS$dmicon{$i}";
366                 @list       = split(':',$DI{$i});
367                 $l = @list;
368                 while ( $l <= 2 ) { push(@list,''); ++$l }
369                 $law{$i} = $list[1] if  ($list[1] eq 'no'  || $list[1] eq 'ow'
370                     ||  $list[1] eq 're' || $list[1] eq 'dh' );
371                 $dmicon{$i} = "$PNG_ICONS$list[0]" if ( $list[0] ne '' );
372                 $dmicon{$i} = '' if ( $law{$i} eq 'no' || !$MINI_ICONS );
373         }
374 } else {
375         foreach $i (qw(fvwm_app fvwm_folder fvwm_title fvwm_toptitle)) {
376                 # With the mini-icons-tran options we "use" gtk default
377                 if ( $TRAN ) {
378                         $j = substr($i,index($i,'_'));
379                         $j = "gtk$j";
380                         $law{$i} = $law{$j};
381                         $tmp_icon  = $dmicon{$j};
382                         $tmp_icon  =~ s/\.png$/\.xpm/;
383                         $dmicon{$i} = "$TRAN_MINI_ICONS$tmp_icon";
384                 } else {
385                         $dmicon{$i} = "$MINI_ICONS_DIR$dmicon{$i}";
386                 }
387                 @list = split(':',$DI{$i});
388                 $l = @list;
389                 while ( $l <= 5 ) { push(@list,''); ++$l }
390                 $law{$i}     = $list[1] if ($list[1] eq 'no'  || $list[1] eq 'ow'
391                         || $list[1] eq 're' || $list[1] eq 'dh' );
392                 $dmicon{$i}  = "$MINI_ICONS_DIR$list[0]" if ( $list[0] ne '' );
393                 $place{$i}   = '*' if ($list[2] eq 'up');
394                 $dmicon{$i}  = "$place{$i}$dmicon{$i}$place{$i}";
395                 $dmicon{$i}  = '' if ($law{$i} eq 'no' || $MINI_ICONS == 0);
396                 if ( $list[3] ne '' ) { $spic{$i}   = "\@$list[3]\@" }
397                 else { $spic{$i}   = '' }
398                 if ( $list[4] ne '' && $list[3] ne '' ) { $scolor{$i} = "\^$list[4]\^" }
399                 else {$scolor{$i} = ''};
400         }
403 # style init
404 if ( $TRAN_STYLE ) { $STYLE = 1 }
406 if ( $STYLE ) {
408         @list= split(':',$ICON_STYLE);
409         $l = @list;
410         while ( $l <= 4 ) { push(@list,''); ++$l }
412         if ( $TRAN_STYLE || $TRAN ) {
413                 if ( $list[0] ne '' ) { $dstyle{mini_icon} = $TRAN_MINI_ICONS . $list[0] }
414                 else { $dstyle{mini_icon} = $TRAN_MINI_ICONS . $dstyle{gnome_mini_icon} }
415                 if ( $list[1] ne '' ) { $dstyle{icon} = $TRAN_ICONS . $list[1] }
416                 else { $dstyle{icon} = $TRAN_ICONS . $dstyle{gnome_icon} }
417         } else {
418                 if ( $list[0] ne '' ) { $dstyle{mini_icon} = $MINI_ICONS_DIR . $list[0] }
419                 else { $dstyle{mini_icon} = $MINI_ICONS_DIR . $dstyle{mini_icon} }
420                 if ( $list[1] ne '' ) { $dstyle{icon} = $ICONS_DIR . $list[1] }
421                 else { $dstyle{icon} = $ICONS_DIR . $dstyle{icon} }
422         }
424         $style_law = $list[2] if ( $list[2] eq 'dh' ||   $list[2] eq 'ow'
425                 || $list[2] eq 're' );
426         $addstyle = $list[3] if ( $list[3] ne '' );
430 if ($check_mini_icons ne "") {
431         @check_mini_icons_path = split(":", $check_mini_icons);
433 if ($check_icons ne "") {
434         @check_icons_path = split(":", $check_icons);
437 #----------------
438 # LANG init for UTF-8
439 if ($UTF8) {
440         # check if we have perl >= 5.6
441         if ($] < 5.006) {
442                 $UTF8_TR = "";
443         } else {
444                 my $l = substr($LANG,0,2);
445                 # latin-1: not sure that all these lang are "latin1"!
446                 $UTF8_TR = '$tmpLabel =~ tr/\0-\x{ff}//UC'
447                         if " ca de es it fr gl hu is lt nl no pt sv " =~ / $l /;
448         }
451 if ($UNICONV ne "") {
452         # check whether internal method is available
453         if ($UNICONV_EXEC eq "" || $UNICONV_EXEC eq "internal") {
454                 eval "use Encode 'from_to';";
455                 if ($UNICONV_EXEC eq "internal" && $@) {
456                         die "You don't have a good perl version to use" .
457                                 " 'internal' unicode conversion:\n$@";
458                 }
459                 $UNICONV_EXEC = $@? "iconv": "internal";
460         }
461         # setup unicode conversion
462         if ($UNICONV_EXEC eq "iconv") {
463                 die "iconv not found in your path\n" 
464                         unless check_app("iconv");
465                 $UTF8_TR = q{
466                         $tmpLabel =~ s/'/'\\\\''/g;
467                         open(U, "echo '$tmpLabel' | iconv -f UTF8 -t $UNICONV |");
468                         while (<U>) { chomp; $tmpLabel = $_ }
469                         close(U);
470                 };
471         } elsif ($UNICONV_EXEC eq "uniconv") {
472                 die "uniconv not found in your path\n" 
473                         unless check_app("uniconv");
474                 $UTF8_TR = q{
475                         $tmpLabel =~ s/'/'\\\\''/g;
476                         open(U, "echo '$tmpLabel' | uniconv -I UTF8 -O $UNICONV |");
477                         while (<U>) { chomp; $tmpLabel = $_ }
478                         close(U);
479                 };
480         } elsif ($UNICONV_EXEC eq "internal") {
481                 $UTF8_TR = 'from_to($tmpLabel, "utf-8", "$UNICONV")';
482         } else {
483                 die "--uniconv argument must be iconv, uniconv or internal\n";
484         }
485         $UTF8 = 1;
488 #----------------
489 # "Main" variable: contains the directories to look at.
490 # + is the "level" separator, the menu is built level by level
491 # with a double loop
492 if ($merge_user_menu && -d $merge_user_dir) {
493         @Rec_Dir_List = ("$merge_user_dir","+");
494 } else {
495         @Rec_Dir_List = ("$APPS_DIR", "+");
496         $user_menu_done = 1;
497         $merge_user_menu = 0;
500 # init level
501 # what is the function count("/", $dir) ?
502 $level = 0;
503 $cdir = $APPS_DIR;
504 while ( $cdir =~ /\// ) {
505         $cdir =~ s/\///;
506         ++$level;
508 $top_level = $level;
509 $nlevel = $level +1;            # next level
510 my $is_top_level = 1;
512 #---------------------------------
513 # Main loop (double loop)
514 while( $Rec_Dir_List[0] ne '+') {
516         # construct a level (may add some .fvwm2rc comment here)
517         while( $Rec_Dir_List[0] ne '+') {
519                 $dir = $Rec_Dir_List[0]; # current working directory
520                 @Main_List=();  # will contain the list of the file and dir
521                 #               # of $dir (in good order)
522                 my $hidden = 0;
523                 my @orderedList = ();
524                 my @newDirList = ();
526                 my @sList = ();
527                 my @uList = ();
528                 my @sDir = ();
529                 my @uDir = ();
530                 my @list = ();
532                 if ($merge_user_menu) {
533                         $merge_dir = $dir;
534                         $sys_dir = $dir;
535                         $merge_dir =~ s#^$APPS_DIR#$merge_user_dir#;
536                         $sys_dir =~ s#^$merge_user_dir#$APPS_DIR#;
537                         if ("$sys_dir" eq "$dir") { $merge_dir_type = "s"; }
538                         else { $merge_dir_type = "u"; }
539                 }
541                 #--------
542                 # Construct the Main_List:
543                 # 1. look at an "order" hint and begin the list
544                 # 2. complete the list
546                 # 1. Look to the desktop order hint
547                 # For gnome there is an .order file. For kde the order is in the
548                 # .directory file.
550                 # for gnome
551                 if ( -f "$dir/.order" ) {
552                         open(ORDER, "$dir/.order") || print STDERR
553                         "fvwm-menu-desktop: Can't open $dir/.order: $!\n";
554                         while( defined ($name = <ORDER>)) {
555                                 chomp($name);
556                                 push(@orderedList, "$dir/$name");
557                         }
558                         close(ORDER);
559                 }
561                 # for kde
562                 # see if the user has over read the systeme .directory:
563                 if ("$merge_dir_type" eq "s" && -f "$merge_dir/.directory") {
564                         open(ORDER, "$merge_dir/.directory") || print STDERR
565                         "fvwm-menu-desktop: Can't open $merge_dir/.directory: $!\n";
566                         while(<ORDER>) {
567                                 $hidden = 1 if /^hidden=true/i;
568                                 if ( /^SortOrder=(.*)$/ ) {
569                                         @orderedList = ();
570                                         $order = "$1";
571                                         @list = split(/\s*,\s*/, "$order");
572                                         foreach $name (@list) {
573                                                 next if -f "$merge_dir/$name" && is_hidden("$merge_dir/$name");
574                                                 push(@orderedList, "$dir/$name"); 
575                                         }
576                                 }
577                         }
578                         close(ORDER);
579                 } elsif ( -f "$dir/.directory" ) {
580                         open(ORDER, "$dir/.directory") || print STDERR
581                         "fvwm-menu-desktop: Can't open $dir/.directory: $!\n";
582                         while(<ORDER>) {
583                                 $hidden = 1 if /^hidden=true/i;
584                                 if ( /^SortOrder=(.*)$/ ) {
585                                         @orderedList = ();
586                                         $order = "$1";
587                                         @list = split(/\s*[,;]\s*/, "$order");
588                                         foreach $name (@list) {
589                                                 next if $merge_user_menu && -f "$merge_dir/$name" && 
590                                                   is_hidden("$merge_dir/$name");
591                                                 push(@orderedList, "$dir/$name"); 
592                                         }
593                                 }
594                         }
595                         close(ORDER);
596                 }
597                 @orderedList = () if $hidden;
599                 # 2. Add to @Main_List the items not in the order.
600                 # AND WE UPDATE @Rec_Dir_List HERE
602                 # a system submenu has a submenu in the user menu:
603                 if ($merge_dir_type eq "s" && ! -d $dir && -d $merge_dir) {
604                         foreach $name (read_dir($merge_dir)) {
605                                 next if $name =~ /^\./;
606                                 $add = (-f "$dir/$name") || is_dir_not_empty("$dir/$name");
607                                 if (-d "$merge_dir/$name") {
608                                         next if -f "$merge_dir/$name/.directory" && 
609                                           is_hidden("$merge_dir/$name/.directory");
610                                         push(@uDir, "$dir/$name") if $add;
611                                 }
612                                 foreach $j (@orderedList) { $add=0 if "$dir/$name" eq "$j"; }
613                                 push(@uList, "$dir/$name") if $add ;
614                         }
615                 }
617                 if (-d $dir) {
618                         foreach $name (read_dir($dir)) {
619                                 next if $name =~ /^\./;
620                                 $add = (-f "$dir/$name") || is_dir_not_empty("$dir/$name");
621                                 if ( -d "$dir/$name" ) {
622                                         if ($merge_dir_type eq "s" && -f "$merge_dir/$name/.directory") {
623                                                 next if is_hidden("$merge_dir/$name/.directory");
624                                         }
625                                         elsif ($merge_dir_type eq "u" && -d "$sys_dir/$name") {
626                                                 next;
627                                         }
628                                         elsif ( -f "$dir/$name/.directory") {
629                                                 next if is_hidden("$dir/$name/.directory");
630                                         }
631                                         push(@sDir, "$dir/$name") if $add;
632                                 } elsif ($merge_dir_type eq "s" && -f "$merge_dir/$name") {
633                                         next if is_hidden("$merge_dir/$name");
634                                 }
635                                 foreach $j  (@orderedList) {
636                                         $add=0 if ("$dir/$name" eq "$j");
637                                 }
638                                 push(@sList, "$dir/$name") if $add;
639                         }
640                         close(DIR);
641                 }
642                 # added user entries in a "system" submenu
643                 if ($merge_dir_type eq "s" && -d "$merge_dir") {
644                         foreach $name (read_dir("$merge_dir")) {
645                                 next if $name =~ /^\./;
646                                 next if -d "$dir/$name" || -f "$dir/$name";
647                                 next if "$dir" eq "$APPS_DIR";
648                                 if (-d "$merge_dir/$name") {
649                                         push(@uDir, "$dir/$name") if -d "$merge_dir/$name";
650                                 } elsif (-f "$merge_dir/$name") {
651                                         next if is_hidden("$merge_dir/$name");
652                                 }
653                                 $add = 1;
654                                 foreach $j (@orderedList) {
655                                         $add=0 if ("$dir/$name" eq "$j");
656                                 }
657                                 push(@uList, "$dir/$name") if $add;
658                         }
659                 }
661                 # ---------
662                 # Build the menu of $dir
663                 if (!$hidden) {
664                         push @Rec_Dir_List, @uDir, @sDir;
665                         push @Main_List, @orderedList, @uList, @sList;
666                         build_a_level();
667                 }
669                 shift(@Rec_Dir_List);
670         }
672         # next level
673         $is_top_level = 0;
674         $level = $nlevel;
675         ++$nlevel;
676         shift @Rec_Dir_List;    # push out the "+"
677         push( @Rec_Dir_List, '+' );     # add a level separator
678         if ($merge_user_menu && $Rec_Dir_List[0] eq '+' && !$user_menu_done) {
679                 $user_menu_done = 1;
680                 $is_top_level = 1;
681                 @Rec_Dir_List = ("$APPS_DIR", "+");
682         }
683         # @Rec_Dir_List = (+) => END
686 # output the style
687 print "$STYLEOUTPUT" if ( $STYLE );
689 # output the menu style
690 if ($MENU_STYLE ne "") {
691         foreach (@menus_for_style) {
692                 print qq(ChangeMenuStyle "$MENU_STYLE" "$_"\n);
693         }
696 # end of main
697 #----------------------------------------------------------------------------
698 #----------------------------------------------------------------------------
699 # Subroutines:
700 #     read_dir
701 #     is_hidden
702 #     up_directory
703 #     build_a_level (build a (sub)Menu)
704 #     get_info (Read Desktop hints, compute icons)
705 #     update_style
706 #     check_app
708 #----------------------------------------------------------------------------
709 #----------------------------------------------------------------------------
711 sub read_dir {
712         my $dir = shift;
713                         
714         opendir(DIR, $dir) || return ();
715         # put the dirs first ...
716         my @f = ();
717         my @d = ();
718         my @l = ();
719         foreach $name (readdir(DIR)) {
720                 next if  $name =~ /^\./;
721                 if (-d "$dir/$name") {
722                         push (@d, "$name");
723                 }
724                 elsif (-f "$dir/$name") {
725                         push (@f, "$name");
726                 }
727         }
728         close(DIR);
729         return (@d, @f);
732 sub is_dir_not_empty {
733         my $dir = shift;
735         return 0 if (! -d $dir);
736         opendir(DIR, $dir) || return 0;
737         foreach $name (readdir(DIR)) {
738                 next if $name =~ /^\./;
739                 close(DIR);
740                 return 1;
741         }
742         return 0;
745 sub is_hidden {
746         my $file = shift;
747         my $return = 0;
749         return 0 if ! -f $file;
750         open(ISHIDDEN, "$file") || print STDERR
751           "fvwm-menu-desktop: Can't open $merge_dir/$file";
752         while(<ISHIDDEN>) { $return = 1 if /^hidden=true/i; }
753         close(ISHIDDEN);
754         return $return;
757 # Compute cd ..
758 sub up_directory {
759         my($dir) = @_;
761         if ( $dir eq '' ) { return '../' }
762         chop($dir);
763         if ( ! ($dir =~ /\//) ) { return '' }
764         $dir = substr($dir,0,rindex($dir,'/')+1);
765         return $dir;
768 #----------------------------------------------------------------------------
769 # Build a (sub)menu
770 sub build_a_level {
771         my ($label, $exec, $mini_icon) = ('', '', '');
772         my ($style_mini_icon,$style_icon) = ('', '');
773         my $titletype;
774         my $tmp_name;
775         my $name;
776         my $item;
779         # Head of the menu
780 #       if ( $level == $top_level ) {
781         if ($is_top_level) {
782                 $mini_icon = $dmicon{$flag .'toptitle'};
783                 $name = $MENU_NAME;
784                 if ($merge_dir_type eq "s" && -r "$merge_dir/.directory") {
785                         ($label, $mini_icon) = get_info("$merge_dir/.directory", 'toptitle')
786                 }
787                 if (-r "$dir/.directory") {
788                         ($label, $mini_icon) = get_info("$APPS_DIR/.directory", 'toptitle')
789                 }
790                 if ( $label eq '' || $OPT_MENU_TITLE ne '') { $label = $MENU_TITLE }
791                 else { $label = "$DESKTOP $label" }
792                 $titletype = 'toptitle';
793         } else {
794                 $tmp_name = substr($dir,rindex ($dir,'/')+1);
795                 $name = "$SUBMENUS_PREFIX$tmp_name-$level";
796                 $mini_icon = $dmicon{$flag . 'title'};
797                 if ($merge_dir_type eq "s" && -r "$merge_dir/.directory") {
798                         ($label, $mini_icon) = get_info("$merge_dir/.directory", 'title');
799                 }
800                 if (-r "$dir/.directory") {
801                         ($label, $mini_icon) = get_info("$dir/.directory", 'title');
802                 }
803                 $label = $tmp_name if ( $label eq '');
804                 $titletype = 'title';
805         }
807         # Now we can print the Head of the (sub)menu
808         if (!($is_top_level && $merge_user_menu && $user_menu_done)) {
809                 if ( $flag eq 'gtk_' ) {
810                         print_module_config qq(Destroy "$name")
811                           if ( $level == $top_level && $MENU_DESTROY =~ /^y/ );
812                         print_module_config qq(Menu "$name"),
813                         qq(Title "$label" $mini_icon),
814                         qq(Separator);
815                 } else {
816                 #               if ( $level != $top_level || $MENU_DESTROY =~ /^y/ ) {
817                         if ( (!$is_top_level || $MENU_DESTROY =~ /^y/) ) {
818                                 print "DestroyMenu \"$name\"\n";
819                         } elsif ( $MENU_DESTROY =~ /^d/ ) {
820                                 print "DestroyMenu recreate \"$name\"\n";
821                         }
822                         print "AddToMenu \"$name$spic{\"$flag$titletype\"}" .
823                           "$scolor{\"$flag$titletype\"}\" \"$label$mini_icon\" Title\n";
824                         push @menus_for_style, $name;
825                 }
826         } else {
827                 if ( $flag eq 'gtk_' ) {
828                         print_module_config qq(Menu "$name");
829                 } else {
830                         print "AddToMenu \"$name\" \n";
831                 }
832         }
834         # Items of the menu
835         for $item (@Main_List) {
837                 #PB (good place ??)
838                 if ( time - $startime >= $timelimit ) {
839                         die "fvwm-menu-desktop runs longer than time-limit; dying (see the man page)\n";
840                 }
841                 $label = '';
842                 $tmp_name = substr($item,rindex ($item,'/')+1);
844                 my $itemDD = "$item/.directory";
845                 if ($merge_dir_type eq "s" && -r "$merge_dir/$tmp_name") {
846                         $item = "$merge_dir/$tmp_name";
847                         $itemDD = "$item/.directory" if -r "$item/.directory";
848                 }
850                 # If it is a dir --> a pop up (folder)
851                 if ( -d "$item" ) {
852                         $name = "$SUBMENUS_PREFIX$tmp_name-$nlevel";
853                         ($label, $mini_icon) = get_info("$itemDD", 'folder')
854                                 if (-r "$itemDD");
855                         $label= $tmp_name if ( $label eq "");
856                         if ( $flag eq 'gtk_' ) {
857                                 print_module_config qq(Destroy "$name"),
858                                         qq(SubMenu "$label" "$name" $mini_icon);
859                         } else {
860                                 print "+ \"$label$mini_icon\" Popup \"$name\"\n";
861                         }
862                 }
864                 # a file --> application
865                 $exec = '';
866                 if (-r $item ) {
867                         ($name, $mini_icon, $exec) = get_info($item, 'app');
868                 }
869                 if ( $exec ne '' ) {
870                         if ( $flag  eq 'gtk_' ) {
871                                 print_module_config qq(Item "$name" "Exec exec $exec" $mini_icon);
872                         } else {
873                                 print "+ \"$name$mini_icon\" Exec exec $exec\n";
874                         }
875                 }
877                 # for kde
878                 if ( $item eq "$dir/SEPARATOR") {
879                         if  ( $flag  eq 'gtk_' ) {
880                                 print_module_config "Separator";
881                         } else {
882                                 print qq(+ "" Nop\n);
883                         }
884                 }
886         }
890 # ---------------------------------------------------------------------------
891 # Read Desktop hints, compute the (mini-)icon and build the STYLE (via a sub)
893 sub get_info {
894         my($file,$which) = @_;
895         my($label, $mini_icon, $exec) = ('', '', '', '');
896         my($icon, $tran_icon, $tran_mini_icon) = ('', '', '', '');
897         my $term = 0;
898         my($deflabel, $onelabel) = ('', '');
899         my $exec_exec = '';
900         my($style_icon, $style_mini_icon) = ('', '');
902         open(DESC,$file) || die "fvwm-menu-desktop: can't open $file: $!";
903         while(<DESC>) {
904                 if ( /^Name\[$LANG.*\]\s*=\s*(.*)$/ ) { 
905                         $label = $1;
906                         if ($UTF8) {
907                                 my $tmpLabel = $label;
908                                 if ($UTF8_TR ne "") { eval $UTF8_TR; $label = $tmpLabel } 
909                                 else { $label = ""; }
910                         }
911                         #$label =~ s/%/%%/g;
912                         #$label =~ s/&/&&/g;
913                         #$label =~ s/\*/\*\*/g;
914                         next;
915                 }
917                 if (/^Name\s*=\s*(.*)$/) {
918                         $deflabel = $1;
919                         if ($UTF8) {
920                                 my $tmpLabel = $deflabel;
921                                 # needed for user menu!
922                                 if ($UTF8_TR ne "") { eval $UTF8_TR; $deflabel = $tmpLabel } 
923                         }
924                         next;
925                 }
927                 # Mandrake creates lines like:
928                 # Exec=NO_XALF command args...
929                 if ( /^Exec\s*=\s*NO_XALF\s*((\S*).*$)/ ) {
930                         #print STDERR "FOUND X_ALF EXEC $1 EXEC_EXEC $2\n";
931                         $exec = $1;
932                         $exec_exec = $2;
933                         next;
934                 }
935                 if ( /^Exec\s*=\s*((\S*).*$)/ ) {
936                         $exec = $1;
937                         $exec_exec = $2;
938                         next;
939                 }
941                 if (/^Terminal\s*=\s*1/) {
942                         $term = 1;
943                         next;
944                 }
946                 if ( /^Icon=(.*)$/ ) { 
947                         $icon = substr($1,rindex($1,'/')+1);
948                         next;
949                 }
951                 # kde gives sometimes a mini-icon hint
952                 if ( /^MiniIcon=(.*)$/ ) { 
953                         $mini_icon = substr($1,rindex($1,'/')+1);
954                         next;
955                 }
956         }
957         
958         close(DESC);
959         # kde2 give just the name of the icons and use png icons
960         # try a more general fix.
961         my $tmp = "png";
962         $icon = "$icon.$tmp" if $icon !~ /\....$/ && $icon ne '';
963         $mini_icon = "$mini_icon.$tmp" 
964           if $mini_icon !~ /\....$/ && $mini_icon ne '';
965         #print STDERR "$icon,$mini_icon\n";
967         #----------------------
968         # See which info we get
970         $label = $deflabel if ( $label eq '');
971         $label = $onelabel if ( $label eq '');
973         if ( $which eq 'app' ) {
974                 # kde introduce some %foo things after the executable for options
975                 # "%c" is for the name (caption option)
976                 # other things seems useless for us !
977                 # (%i is for icon, %m is for mini-icon, %u is for ??user?? and
978                 # %f is for file I presume, but what file ???)
979                 # we use caption
980                 $exec =~ s/\"\%c\"/\"$label\"/;
981                 $exec =~ s/\%.//g;
983                 # check the existence of the app
984                 return('', '', '') if $CHECK && !check_app($exec_exec);
986                 # term
987                 $exec = "$TERM_CMD $exec" if $term;
989                 #sometimes kde workers forget the icons and the mini-icons:
990                 if ( $mini_icon eq '' && $APPS_DIR eq  $KDE_APPS) {
991                         $mini_icon = "$exec_exec.xpm"
992                                 if ( -f "$KDE_MINI_ICONS$exec_exec.xpm");
993                         $mini_icon = "$exec_exec.png"
994                                 if ( -f "$KDE3_MINI_ICONS$exec_exec.png");
995                         $icon = "$exec_exec.xpm"
996                                 if ( -f "$KDE_ICONS$exec_exec.xpm" );
997                         $icon = "$exec_exec.png"
998                                 if ( -f "$KDE3_ICONS$exec_exec.png" );
999                 }
1000         }
1002         #----------------------------
1003         # if no icons or ow and no style we can return now
1004         return($label, $dmicon{$flag . $which}, $exec)
1005                 if ( ($law{"$flag$which"} eq 'ow'
1006                         || $law{"$flag$which"} eq 'no'
1007                         || !$MINI_ICONS) && !$STYLE );
1009         #--------------
1010         # now the icons
1012         $mini_icon = $icon if ( $mini_icon eq '');
1013         $icon = $mini_icon if  ( $icon eq '');
1016         # Translation
1017         # for mini-icons-tran && style(-tran) (we translate only the mini-icon
1018         # since gnome do not specify mini icon ...).
1019         if ( ($TRAN && $flag eq 'fvwm_') || ($TRAN_STYLE) ) {
1020                 $tmp_icon = $mini_icon;
1021                 if ( $tmp_icon =~ /\.png$/ ) {
1022                         $tmp_icon =~ s/\.png$/\.xpm/;
1023                         $tran_mini_icon = $tmp_icon if ( (-f "$TRAN_MINI_ICONS$tmp_icon")
1024                                 || !($TRAN_MINI_ICONS =~ /^\//) );
1025                         $tran_icon = $tmp_icon if ( (-f "$TRAN_ICONS$tran_mini_icon")
1026                                 || !($TRAN_ICONS =~ /^\//) );
1027                 }
1028         }
1031         # no .png icons with fvwm menu
1032         #$mini_icon = '' if ( $flag eq 'fvwm_' && $mini_icon =~ /\.png$/ );
1034         if ($check_mini_icons ne "" && $mini_icon ne "") {
1035                 my $ok = 0;
1036                 my $d;
1037                 foreach $d (@check_mini_icons_path) {
1038                         $ok = 1 if -f "$d/mini_icon";
1039                 }
1040                 $mini_icon = "" if !$ok;
1041         }
1042         if ($check_icons ne "" && $icon ne "") {
1043                 my $ok = 0;
1044                 my $d;
1045                 foreach $d (@check_icons_path) {
1046                         $ok = 1 if -f "$d/icon";
1047                 }
1048                 $icon = "" if !$ok;
1049         }
1051         # Ok the icons are computed except the path.
1053         # Style
1054         if ( $STYLE && $which eq 'app' ) {
1055                 if ( $tran_mini_icon ne '' )  {
1056                         $style_mini_icon = $tran_mini_icon;
1057                 } else {
1058                         $style_mini_icon = $mini_icon;
1059                 }
1060                 if ( $tran_icon ne '' ) {
1061                         $style_icon = $tran_icon
1062                 }
1063                 else {
1064                         $style_icon = $icon;
1065                 }
1066                 update_style($style_mini_icon, $style_icon, $exec_exec)
1067         }
1069         # Add the path
1070         if ( $TRAN && $tran_mini_icon ne '' ) {
1071                 $mini_icon = "$TRAN_MINI_ICONS$tran_mini_icon";
1072         } elsif ( $mini_icon ne '' ) {
1073                 $mini_icon = "$MINI_ICONS_DIR$mini_icon";
1074                 if ( $mini_icon =~ /\.png$/ ) { $mini_icon = "$PNG_ICONS$mini_icon" }
1075                 else { $mini_icon =  "$MINI_ICONS_DIR$mini_icon" }
1076         }
1078         #return the info with icon
1080         return($label, $dmicon{$flag . $which}, $exec)
1081                 if ( $law{"$flag$which"} eq 'ow'
1082                         || $law{"$flag$which"} eq 'no'
1083                         || $MINI_ICONS == 0
1084                         || ($mini_icon eq '' && $law{"$flag$which"} eq 're') );
1086         return($label, $mini_icon, $exec)
1087                 if ($flag eq 'gtk_');
1089         return($label,
1090                          "$place{\"$flag$which\"}$mini_icon$place{\"$flag$which\"}",$exec)
1091         if $mini_icon ne '';
1093         return($label, '', $exec);
1097 # ---------------------------------------------------------------------------
1098 # Update style
1100 sub update_style {
1101         my($style_mini_icon, $style_icon, $exec_exec) = @_;
1103         # Gnome exception for $exec_exec, I probably forget some ...
1104         # seems that there is a rule ...
1105         $exec_exec = 'GnomeTerminal' if ( $exec_exec eq 'gnome-terminal' );
1106         $exec_exec = 'Imlib Config Editor' if ( $exec_exec eq 'imlib_config' );
1107         $exec_exec = 'GnomeHelpBrowser' if ( $exec_exec eq 'gnome-help-browser' );
1108         $exec_exec = 'GQview' if ( $exec_exec eq 'gqview' );
1110         # kde exceptions. Some families of apps have the same name, class, resource
1111         # for windows manager, but kwm; (I try the caption and icon option with
1112         # kcminfo but do not succeed ...)
1113         # Anyway some of the concerned applications are kwm specifics.
1115         if ( $exec_exec eq 'kfmclient' ) {
1116                 $style_icon = $style_mini_icon = 'kfm.xpm'; #kfm_home.xpm better ???
1117                 $exec_exec = 'kfm';
1118         }
1120         $style_icon = $style_mini_icon = 'information_settings.xpm'
1121                 if ( $exec_exec =~ /^kcminfo/ );
1122         $style_icon = $style_mini_icon = 'kcmkwm.xpm'
1123                 if ( $exec_exec =~ /^kcmdisplay/ );
1124         $style_icon = $style_mini_icon = 'input_device_settings.xpm'
1125                 if ( $exec_exec =~ /^kcminput/ );
1126         $style_icon = $style_mini_icon =  'kwm.xpm'
1127                 if ( $exec_exec =~ /^kcmkwm/ );
1129         # Now we add the good path
1130         if ( $TRAN_STYLE || $TRAN ) {
1131                 $style_mini_icon = "$TRAN_MINI_ICONS$style_mini_icon"
1132                         if ( $style_mini_icon ne '');
1133                 $style_icon = "$TRAN_ICONS$style_icon" if ( $style_icon ne '');
1134         } else {
1135                 $style_mini_icon =  "$MINI_ICONS_DIR$style_mini_icon"
1136                         if ( $style_mini_icon ne '' );
1137                 $style_icon =  "$ICONS_DIR$style_icon"  if ( $style_icon ne '' );
1138         }
1140         if (($style_mini_icon eq '' && $style_law eq 're') || ($style_law eq 'ow')) {
1141                 $style_mini_icon = $dstyle{mini_icon};
1142         }
1144         if (($style_icon eq '' && $style_law eq 're') || ($style_law eq 'ow')) {
1145                 $style_icon = $dstyle{icon};
1146         }
1148         # Update $STYLEOUTPUT
1149         if ( $style_mini_icon ne '' || $style_icon ne '' || $addstyle ne '' ) {
1150                 $STYLEOUTPUT .= "Style \"$exec_exec\" MiniIcon " . "$style_mini_icon\n"
1151                         if  ( $style_mini_icon ne '' );
1152                 $STYLEOUTPUT .= "Style \"$exec_exec\" Icon $style_icon\n"
1153                         if  ( $style_icon ne '' );
1154                 $STYLEOUTPUT .= "Style \"$exec_exec\" $addstyle\n"
1155                         if  ( $addstyle ne '' );
1156         }
1160 #--------------------------------------------------------------------------
1161 # Check if application binary is executable and reachable
1163 sub check_app {
1164         my($app) = @_;
1165        # If full path, dont use path, just check path
1166         if ( substr($app,0,1) eq '/' and -x $app ) { return 1 };
1167         # Check if an application is in the path
1168         foreach $dir (@PATH_DIRS) {
1169                 if ( -x "$dir/$app" ) { return 1 }
1170         }
1171         return 0;
1175 #----------------------------------------------------------------------------
1176 # Standard functions
1178 sub show_help {
1179         print <<END_HELP;
1180 A perl script which parses gnome/kde menus definitions to build
1181 the corresponding fvwm/FvwmGtk menu.  The script can also build
1182 Icon and MiniIcon style for the desktop applications.
1184 Usage: $0 [OPTIONS]
1185 Options:
1186         --help                    show this help and exit
1187         --version                 show version and exit
1188         --install-prefix DIR      install prefix of the desktop
1189         --desktop NAME            desktop to build the menu for it:
1190                 gnome-sys (default), gnome-user, gnome-redhat, gnome-madriva,
1191                 kde-sys, kde-user
1192         --type NAME               fvwm (default) or gtk for a FvwmGtk menu
1193         --fvwmgtk-alias NAME      FvwmGtk module name, default is FvwmGtk
1194         --title NAME              menu title, default depends on --desktop
1195         --name NAME               menu name, default depends on --desktop
1196         --merge-user-menu         merge the system menu with the user menu
1197         --enable-mini-icons       enable mini-icons in menu
1198         --enable-tran-mini-icons  enable mini-icons in menu and
1199                 translation of foo.png icon names to foo.xpm
1200         --mini-icons-path DIR     path of menus icons (relative to your
1201                 ImagePath), default is 'mini/'
1202         --png-icons-path DIR      path of .png icons, default is your ImagePath
1203         --tran-mini-icons-path DIR      path of menus icons for translation
1204         --check-mini-icons PATH   check if the mini icons are in PATH
1205         --icon-toptitle micon:law:place:sidepic:color  mini-icon for the top
1206                  title and sidepic for the top menu
1207         --icon-title micon:law:place:sidepic:color     as above for sub menus
1208         --icon-folder micon:law:place   mini-icons for folder item
1209         --icon-app micon:law:place      mini-icon for applications item
1210         --wm-icons                define menu icon names to use with wm-icons
1211         --enable-style            build icons and mini-icons style
1212         --enable-tran-style       as above with translation (for FvwmGtk menus)
1213         --icon-style micon:icon:law     icons for style
1214         --icons-path DIR          define the directory of the icons,
1215                 the default is very good
1216         --tran-icons-path DIR     similar to the above option.
1217         --check-icons PATH        check if the icons are in the PATH
1218         --submenu-name-prefix NAME      in general not useful
1219         --dir DIR                 use path as desktop menu description
1220         --destroy-type FLAG       how to destroy menu, valid values:
1221                 'yes', 'no', 'dynamic', the default depends on --type
1222         --xterm CMD               complete terminal command to run applications
1223                 in it, default is 'xterm -e'
1224         --lang NAME               language, default is \$LANG
1225         --utf8                    For desktop entries coded in UTF-8 (KDE2)
1226         --uniconv                 Use (un)iconv for UTF-8 translation
1227         --uniconv-exec            uniconv or iconv (default)
1228         --menu-style name         assign specified MenuStyle name to menus
1229         --[no]check-app           [do not] check that apps are in your path
1230         --time-limit NUM          limit script running time to NUM seconds
1231 Short options are ok if not ambiguous: -h, -x, -icon-a.
1232 END_HELP
1233         exit 0;
1236 sub show_version {
1237         print "$version\n";
1238         exit 0;
1241 sub wrong_usage {
1242         print STDERR "Try '$0 --help' for more information.\n";
1243         exit -1;