3 # Copyright (C) 2002-2009 Mikhael Goikhman <migo@cpan.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 # Filter this script to pod2man to get a man page:
20 # pod2man -c "Fvwm Module" FvwmPerl | nroff -man | less -e
26 use vars qw($prefix $datarootdir $datadir);
28 $datarootdir = "@datarootdir@";
29 $datadir = "@datadir@";
32 use lib "@FVWM_PERLLIBDIR@";
34 use General::FileSystem "-quiet";
38 # ----------------------------------------------------------------------------
41 my $line_to_eval = undef;
42 my $file_to_load = undef;
44 my $export_func_names = undef;
45 # whether continue running after --eval, --load or --preprocess, default is no
51 my $preprocess_options = undef;
52 my $pp_file_count = 0;
53 my $pp_main_quote_ref = undef;
55 sub init_preprocess_vars () {
57 $pp_args->{quote} = $$pp_main_quote_ref if $pp_main_quote_ref;
58 $pp_main_quote_ref = \$pp_args->{quote} unless $pp_main_quote_ref;
60 $preprocess_options = {
61 "c|cmd|command" => \$pp_args->{command},
62 "q|quote=s" => \$pp_args->{quote},
63 "w|winid=s" => \$pp_args->{winid},
64 "nosend" => \$pp_args->{nosend},
65 "noremove" => \$pp_args->{noremove},
69 init_preprocess_vars();
72 "e|eval=s" => \$line_to_eval,
73 "l|load=s" => \$file_to_load,
74 "p|preprocess" => \$preprocess,
75 "x|export:s" => \$export_func_names,
82 my $module = new FVWM::Module(
86 EnableOptions => $options,
88 Debug => \$debug, # $debug is not really ready yet
91 sub print_action_error ($$) {
94 return if $err_msg =~ /^!/;
95 $err_msg =~ s/\s+$//s;
96 print STDERR "[", $module->name, "][$action]: $err_msg\n";
99 # ----------------------------------------------------------------------------
100 # prepare the environment that may be used in the sent perl commands
102 my $version = "@VERSION@";
104 my ($a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k, $l, $m, $n, $o, $p)
105 = ("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
106 my (@a, @b, @c, @d, @e, @f, @g, @h, @i, @j, @k, @l, @m, @n, @o, @p);
107 my (%a, %b, %c, %d, %e, %f, %g, %h, %i, %j, %k, %l, %m, %n, %o, %p);
112 $module->send($command, $win_id);
115 *command = \*cmd; *command = \*command; # alias
118 # send a signal to the event loop to terminate the module
123 # send a signal to the event loop to terminate the current event handler
124 $module->terminate("continue");
128 # enable asynchronous evaluation
129 $module->send_unlock;
135 # main process skips the remaining evaluation
136 skip() unless defined $pid && $pid == 0;
138 # child process will exit after evaluation
142 sub show_message ($;$$) {
143 require FVWM::Module::Toolkit;
144 FVWM::Module::Toolkit->show_message(
145 $_[0], $_[1] || "FvwmPerl user message", $_[2]
150 my $func_names = shift || "";
151 my $do_unexport = shift || 0;
153 my @func_names = split(/[\s,]+/, $func_names);
154 @func_names = qw(Eval .) if $func_names eq "";
156 my $name = $module->name;
158 foreach (@func_names) {
162 /preprocess|pp/i || $_ eq "."? 'preprocess -c --':
163 die "Can't guess action for function '$_' to export\n";
167 ) . ($do_unexport ? "" : qq(
168 AddToFunc $_ I SendToModule $name $action \$*
174 my $filename = shift;
175 my $contents = load_file($filename);
176 if (!defined $contents) {
177 print_action_error("load", "Can't find and read $filename: $!");
181 print_action_error("load", "$@") if $@;
187 print_action_error("eval", "$@") if $@;
189 # let's hope we should not clean-up anything
194 sub preprocess_directives ($;$) {
195 my $text_ref = shift;
196 my $depth = shift || 0;
198 my $quote = $PreprocessNamespace::PPP_QUOTE1;
199 my $processed_text = "";
201 my $error_sub = sub ($) {
202 print_action_error("preprocess", "$_[0], preprocessing failed");
204 my ($start, $directive, $params, $end);
206 while ($$text_ref =~ m{\A(.*?)^$quote(\w+)[ \t]*(.*?)\n(.*)\z}ms) {
207 ($start, $directive, $params, $end) = ($1, $2, $3, $4);
209 #print "\t$depth $directive $params\n";
211 if (eqi($directive, "End")) {
213 $error_sub->("Unexpected ${quote}End");
216 $$text_ref = $processed_text . $start;
222 if (eqi($directive, "Repeat")) {
223 my $count = get_token($params);
224 unless (defined $count && $count =~ /^\d+$/) {
225 $error_sub->("Usage: ${quote}Repeat count");
228 $end = &preprocess_directives(\$subtext, $depth + 1);
229 return undef unless defined $end;
230 $start .= $subtext x $count;
234 if (eqi($directive, "ModuleConfig")) {
235 my ($module_name, $destroy) = get_tokens($params, 2);
236 unless (defined $module_name) {
237 $error_sub->("Usage: ${quote}ModuleConfig module-name");
240 if (defined $destroy && eqi($destroy, "destroy")) {
241 $start .= "DestroyModuleConfig $module_name: *\n";
243 $prefix = "*$module_name: ";
245 if (defined $prefix || eqi($directive, "Prefix")) {
246 $prefix = get_token($params) unless defined $prefix;
247 unless (defined $prefix) {
248 $error_sub->("Usage: ${quote}Prefix prefix");
251 $end = &preprocess_directives(\$subtext, $depth + 1);
252 return undef unless defined $end;
253 foreach (split(/\n/s, $subtext)) {
254 $start .= "$prefix$_\n" unless /^\s*$/;
259 $processed_text .= $start;
264 $$text_ref = $processed_text . $$text_ref if $processed_text ne "";
267 $error_sub->("No corresponding ${quote}End found");
271 sub preprocess ($;$) {
275 my $nosend = $args->{nosend};
276 my $noremove = $args->{noremove};
277 my $command = $args->{command};
278 my $quote = $args->{quote} || '%';
279 my $winid = $args->{winid} || undef;
281 my ($quote1, $quote2) = split(//, $quote, 2);
283 $winid = eval $winid if $winid && $winid =~ /^0(x[\da-f]+|[0-7]+)$/;
285 unlock() unless $command;
287 my $depth = $args->{depth};
290 print_action_error("preprocess", "Too deep include depth=$depth");
294 my $text_ref = $command? \$data: load_file($data);
295 unless (defined $text_ref) {
296 print_action_error("preprocess", "No file to preprocess ($data)");
300 # there should be another way without running external programs
301 my @dimentions = `xdpyinfo | grep dimensions` =~ /(\d+)x(\d+)/;
304 package PreprocessNamespace;
306 # OR-ing is a work around for "used once" warning
310 $PPP_QUOTE1 = $quote1;
311 $PPP_QUOTE2 = $PPP_QUOTE2 || $quote2;
312 $PPP_NOSEND = $nosend;
313 $PPP_NOREMOVE = $noremove;
314 $USER = $USER || $ENV{USER};
315 $DISPLAY = $DISPLAY || $ENV{DISPLAY};
316 $WIDTH = $WIDTH || $dimentions[0];
317 $HEIGHT = $HEIGHT || $dimentions[1];
318 $FVWM_VERSION = $FVWM_VERSION || $version;
319 $FVWM_MODULEDIR = $FVWM_MODULEDIR || $ENV{FVWM_MODULEDIR};
320 $FVWM_DATADIR = $FVWM_DATADIR || $module->site_data_dir;
321 $FVWM_USERDIR = $FVWM_USERDIR || $module->user_data_dir;
324 # perl code substitution first
325 $$text_ref =~ s/\Q$quote1\E { ( .*? ) } \Q$quote2\E/
328 package PreprocessNamespace;
332 print_action_error("preprocess", $@);
338 # line based directives
339 preprocess_directives($text_ref);
342 $module->send($$text_ref, $winid);
346 my $temp_filename = $module->user_data_dir . "/.FvwmPerl-preprocess-$$";
347 $temp_filename .= "-" . (++$pp_file_count);
348 save_file($temp_filename, $text_ref);
351 $module->send("Read $temp_filename", $winid);
352 $module->send("Exec rm -f '$temp_filename'")
357 sub PreprocessNamespace::include ($) {
360 depth => $PreprocessNamespace::PPP_DEPTH + 1,
361 quote => $PreprocessNamespace::PPP_QUOTE,
362 nosend => $PreprocessNamespace::PPP_NOSEND,
363 noremove => $PreprocessNamespace::PPP_NOREMOVE,
368 # ----------------------------------------------------------------------------
371 sub process_message ($$) {
373 my $string = $event->_text;
376 return if $string eq "";
377 my ($action, $rest) = split(/\s+/, $string, 2);
378 $action = lc($action);
380 if ($action eq "eval") {
381 return unless defined $rest;
385 elsif ($action eq "load") {
386 return unless defined $rest;
387 load(get_token($rest));
390 elsif ($action eq "preprocess") {
391 @ARGV = split(/ /, $rest);
392 init_preprocess_vars();
393 my $parser = new Getopt::Long::Parser(
394 config => [qw(pass_through require_order)]
396 $parser->getoptions(%$preprocess_options) || return;
397 $pp_args->{winid} = $event->_win_id || undef
398 unless defined $pp_args->{winid} && $pp_args->{winid} =~ /^\d/;
400 preprocess($pp_args, join(" ", @ARGV));
403 elsif ($action eq "export") {
407 elsif ($action eq "unexport") {
411 elsif ($action eq "stop") {
415 elsif ($action eq "dump") {
416 # will dump non-void variables in the future
420 print_action_error("process_message", "Unknown action ($action)");
424 $module->add_handler(M_STRING, \&process_message);
426 # ----------------------------------------------------------------------------
429 # unlock fvwm earlier if requested
430 $module->send_ready if $nolock;
432 if (defined $export_func_names) {
433 export($export_func_names);
437 if (defined $line_to_eval) {
438 do_eval($line_to_eval);
439 exit(0) unless $stay;
442 if (defined $file_to_load) {
444 exit(0) unless $stay;
448 preprocess($pp_args, join(" ", @ARGV));
449 exit(0) unless $stay;
456 # ----------------------------------------------------------------------------
461 FvwmPerl - the fvwm perl manipulator and preprocessor
465 FvwmPerl should be spawned by fvwm(1) for normal functionality.
467 To run this module, place this command somewhere in the configuration:
469 Module FvwmPerl [params]
473 ModuleSynchronize FvwmPerl [params]
475 if you want to immediately start to send commands to FvwmPerl.
479 This module is intended to extend fvwm commands with the perl scripting
480 power. It enables to embed perl expressions in the fvwm config files and
481 construct fvwm commands.
485 If you want to invoke the unique and persistent instanse of FvwmPerl, it is
486 suggested to do this from the I<StartFunction>. Calling it from the top is
487 also possible, but involves some issues not discussed here.
489 AddToFunc StartFunction I Module FvwmPerl
491 There are several command line switches:
496 [ B<--preprocess> [ B<--quote> char ] [ B<--winid> wid ] [ B<--cmd> ]
497 [ B<--nosend> ] [ B<--noremove> ] [ line | file ] ]
498 [ B<--export> [names] ]
503 Long switches may be abbreviated to short one-letter switches.
505 B<-e>|B<--eval> line - evaluate the given perl code
507 B<-l>|B<--load> file - evaluate perl code in the given file
509 B<-p>|B<--preprocess> [ file ] - preprocess the given fvwm config file
511 The following 5 options are only valid together with B<--preprocess>
514 B<-c>|B<--cmd> line - an fvwm command to be preprocessed instead of file
516 B<-q>|B<--quote> char - change the default '%' quote
518 B<-w>|B<--winid> wid - set explicit window context (should begin with
519 digit, may be in oct or hex form; this window id overwrites implicit
520 window context if any)
522 B<--nosend> - do not send the preprocessed file to I<fvwm> for B<Read>ing,
523 the default is send. Useful for preprocessing non fvwm config files.
525 B<--noremove> - do not remove the preprocessed file after sending
526 it to I<fvwm> for B<Read>ing, the default is remove. Useful for debugging.
528 B<-x>|B<--export> [names] - define fvwm shortcut functions (by default,
529 two functions named "Eval" and "."). This option implies B<--stay>.
531 B<-s>|B<--stay> - continues an execution after B<--eval>, B<--load> or
532 B<--preprocess> are processed. By default, the module is not persistent
533 in this case, i.e. B<--nostay> is assumed.
535 B<--nolock> - when one of the 3 action options is given, this option causes
536 unlocking I<fvwm> immediately. By default the requested action is executed
537 synchronously; this only makes difference when invoked like:
539 ModuleSynchronous FvwmPerl --preprocess someconfig.ppp
541 If B<--nolock> is added here, B<ModuleSynchronous> returns immediately.
542 Note that B<Module> returns immediately regardless of this option.
546 Aliases allow to have several module invocations and work separately
547 with all invocations, here is an example:
549 ModuleSynchronous FvwmPerl FvwmPerl-JustTest
550 SendToModule FvwmPerl-JustTest eval $a = 2 + 2; $b = $a
551 SendToModule FvwmPerl-JustTest eval cmd("Echo 2 + 2 = $b")
552 KillModule FvwmPerl FvwmPerl-JustTest
554 =head1 PREPROCESSING EXAMPLE
556 One of the effective proprocessing solutions is to pass the whole fvwm
557 configuration with embeded perl code to "FvwmPerl --preprocess".
558 An alternative approach is to write a perl script that produces fvwm
559 commands and sends them for execution, this script may be loaded using
560 "FvwmPerl --load". There are hovewer intermediate solutions that
561 preprocess only separate configuration lines (or alternatively,
562 execute separate perl commands that produce fvwm commands).
564 The following code snippet adds ability of arithmetics and string scripting
565 to certain lines that need this. To use this, you want to start FvwmPerl as
566 your first command so that other commands may be asked to be preprosessed.
568 ModuleSynchronize FvwmPerl
571 + I SendToModule FvwmPerl preprocess -c -- $*
573 . Exec exec xterm -name xterm-%{++$i}% # use unique name
575 . GotoDesk 0 %{ $[desk.n] + 1 }% # go to next desk
577 . Exec exec %{ -x "/usr/bin/X11/aterm" ? "aterm" : "xterm" }% -sb
580 Next (MyWindow) . Move \
581 %{($WIDTH - $[w.width]) / 2}%p %{($HEIGHT - $[w.height]) / 2}%p
583 . Exec exec xmessage %{2 + 2}% # simple calculator
585 . %{main::show_message(2 + 2, "Yet another Calculator"); ""}%
589 There are several actions that FvwmPerl may perform:
593 =item B<eval> perl-code
595 Evaluate a line of perl code.
597 A special function B<cmd(>"command"B<)> may be used in perl code to send
598 commands back to fvwm.
600 If perl code contains an error, it is printed to the standard error stream
601 with the I<[FvwmPerl][eval]:> header prepended.
603 =item B<load> file-name
605 Load a file of perl code.
606 If the file is not fully qualified, it is searched in the user
607 directory $FVWM_USERDIR (usually ~/.fvwm) and the system wide
608 data directory $FVWM_DATADIR.
610 A special function B<cmd(>"command"B<)> may be used in perl code to send
611 commands back to fvwm.
613 If perl code contains an error, it is printed to the standard error stream
614 with the I<[FvwmPerl][load]:> header prepended.
616 =item B<preprocess> [-q|--quote char] [-c|--cmd] [I<line> | I<file>]
618 Preprocess fvwm config I<file> or (if --cmd is given) I<line>.
619 This file contains lines that are not touched (usually fvwm commands)
620 and specially preformatted perl code that is processed and replaced.
621 Text enclosed in B<%{> ... B<}%> delimiters, that may start anywhere
622 on the line and end anywhere on the same or an other line, is perl code.
624 The I<quote> parameter changes perl code delimiters. If a single char
625 is given, like '@', the delimiters are B<@{> ... B<}@>.
626 If the given quote is 2 chars, like B<E<lt>E<gt>>, the quotes are
627 B<E<lt>{> ... B<}E<gt>>
629 The perl code is substituted for the result of its evaluation.
630 I.e. %{$a = "c"; ++$a}% is replaced with "d".
632 The evaluation is unlike B<eval> and B<load> is done under the
633 package PreprocessNamespace and without I<use strict>, so you are
634 free to use any variable names without fear of conflicts. Just don't
635 use uninitialized variables to mean undef or empty list (they may be in fact
636 initialized by the previous preprocess action), and do a clean-up if needed.
637 The variables and function in the I<main> package are still available,
638 like ::cmd() or ::skip(), but it is just not a good idea to access them
641 There is a special function B<include>(I<file>) that loads a file,
642 preprocesses it and returns the preprocessed result. Avoid recursion.
644 If any embedded perl code contains an error, it is printed to the standard
645 error stream and prepended with the I<[FvwmPerl][preprocess]:> header.
646 The result of substitution is empty in this case.
648 The following variables may be used in the perl code:
659 The following line based directives are recognized when preprocessing.
660 They are processed after the perl code (if any) is substituted.
664 =item %B<Repeat> I<count>
666 Causes the following lines to be repeated I<count> times.
668 =item %B<ModuleConfig> I<module-name> [ destroy ]
670 Causes the following lines to be interpreted as the given module configuration.
671 If "destroy" is specified the previous module configuration is destroyed first.
673 =item %B<Prefix> I<prefix>
675 Prefixes the following lines with the quoted I<prefix>.
677 =item %B<End> any-optional-comment
679 Ends any of the directives described above, may be nested.
685 %Prefix "AddToFunc SwitchToWindow I"
692 %ModuleConfig FvwmPager destroy
697 %End ModuleConfig FvwmPager
699 %Prefix "All (MyWindowToAnimate) ResizeMove "
700 100 100 %{($WIDTH - 100) / 2}% %{($HEIGHT - 100) / 2}%
702 br w+2c w+2c w-1c w-1c
705 br w-2c w-2c w+1c w+1c
709 Additional preprocess parameters --nosend and --noremove may be given too.
710 See their description at the top.
712 =item B<export> [I<func-names>]
714 Send to I<fvwm> the definition of shortcut functions that help to activate
715 different actions of the module (i.e. B<eval>, B<load> and B<preprocess>).
717 Function names (I<func-names>) may be separated by commas or/and whitespace.
718 By default, two functions "Eval" and "." are assumed.
720 The actual action defined in a function is guessed from the function name
721 if possible, where function name "." is reserved for B<preprocess> action.
723 For example, any of these two fvwm commands
725 SendToModule MyPerl export PerlEval,PP
726 FvwmPerl --export PerlEval,PP MyPerl
728 define the following two shortcut functions:
731 AddToFunc I SendToModule MyPerl eval $*
733 AddToFunc I SendToModule MyPerl preprocess -c -- $*
737 These 4 actions may be requested in one of 3 ways: 1) in the command line when
738 FvwmPerl is invoked (in this case FvwmPerl is short-lived unless B<--stay>
739 or B<--export> is also given), 2) by sending the corresponding message in
740 fvwm config using SendToModule, 3) by calling the corresponding perl function
745 There are several functions that perl code may call:
749 =item B<cmd(>I<$fvwm_command>B<)>
751 In case of B<eval> or B<load> - send back to fvwm a string I<$fvwm_command>.
752 In case of B<preprocess> - append a string I<$fvwm_command> to the output of
753 the embedded perl code.
755 =item B<do_eval(>I<$perl_code>B<)>
757 This function is equivalent to the B<eval> functionality
758 on the string I<$perl_code>, described above.
760 =item B<load(>I<$filename>B<)>
762 This function is equivalent to the B<load> functionality
763 on the file $filename, described above.
765 =item B<preprocess(>I<@params, ["-c $command"] [$filename]>B<)>
767 This function is equivalent to the B<preprocess> functionality
768 with the given parameters and the file $filename described above.
770 =item B<export(>I<$func_names, [$do_unexport]>B<)>
772 This function is equivalent to the B<export> functionality
773 with the given $func_names, described above. May also B<unexport>
774 the function names if the second parameter is true.
776 Function names should be separated by commas or/and whitespace.
777 If I<$func_names> is empty then functions "Eval" and "." are assumed.
781 Terminates the module.
785 Skips the rest of the event callback code, i.e. the module returns to listen
786 to new module events.
790 Unsynchronizes the event callback from fvwm. This may be useful to prevent
791 deadlocks, i.e. usually fvwm kills the non-responding module if the event
792 callback is not finished in I<ModuleTimeout> seconds. This prevents it.
794 This example causes FvwmPerl to suspend its execution for one minute:
796 SendModule FvwmPerl eval unlock(); sleep(60);
798 However, verify that there is no way a new message is sent by fvwm while the
799 module is busy, and fvwm stays locked on this new message for too long.
800 See also the B<detach> solution if you need long lasting operations.
804 Forks and detaches the rest of the event callback code from the main
805 process. This may be useful to prevent killing the module if its event
806 callback should take a long time to complete and it may be done in the
807 detached child. The detached child may still send commands to fvwm (don't
808 rely on this), but not receive the events of course, it exits immediately
809 after the callback execution is finished.
811 If you use detach(), better only send commands to fvwm in one process (the
812 main one or the detached one), doing otherwise may often cause conflicts.
814 =item B<show_message(>$msg, $title[, $use_stderr_too=1]B<)>
816 Shows a dialog window with the given message, using whichever X tool is
819 See B<FVWM::Module::Toolkit>::B<show_message> for more information.
825 There are several global variables in the I<main> namespace that may be used
832 They all are initialized to the empty value and may be used to store a state
833 between different calls to FvwmPerl actions (B<eval> and B<load>).
835 If you need more readable variable names, either write "no strict 'vars';"
836 at the start of every perl code or use a hash for this, like:
838 $h{id} = $h{first_name} . " " . $h{second_name}
840 or use a package name, like:
842 @MyMenu::terminals = qw( xterm rxvt );
843 $MyMenu::item_num = @MyMenu::terminals;
845 There may be a configuration option to turn strictness on and off.
849 FvwmPerl may receive messages using the fvwm command SendToModule.
850 The names, meanings and parameters of the messages are the same as the
851 corresponding actions, described above.
853 Additionally, a message B<stop> causes a module to quit.
855 A message B<unexport> [I<func-names>] undoes the effect of B<export>,
856 described in the ACTIONS section.
858 A message B<dump> dumps the contents of the changed variables (not yet).
864 SendToModule FvwmPerl eval $h{dir} = $ENV{HOME}
865 SendToModule FvwmPerl eval load($h{dir} . "/test.fpl")
866 SendToModule FvwmPerl load $[HOME]/test.fpl
867 SendToModule FvwmPerl preprocess config.ppp
868 SendToModule FvwmPerl export Eval,PerlEval,PerlLoad,PerlPP
869 SendToModule FvwmPerl unexport PerlEval,PerlLoad,PerlPP
870 SendToModule FvwmPerl stop
872 The following example handles root backgrounds in fvwmrc.
873 All these commands may be added to StartFunction.
875 Module FvwmPerl --export PerlEval
877 # find all background pixmaps for a later use
878 PerlEval $a = $ENV{HOME} . "/bg"; \
879 opendir DIR, $a; @b = grep { /xpm$/ } readdir(DIR); closedir DIR
881 # build a menu of background pixmaps
882 AddToMenu MyBackgrounds "My Backgrounds" Title
883 PerlEval foreach $b (@b) \
884 { cmd("AddToMenu MyBackgrounds '$b' Exec fvwm-root $a/$b") }
886 # choose a random background to load on start-up
887 PerlEval cmd("AddToFunc \
888 InitFunction + I Exec exec fvwm-root $a/" . $b[int(random(@b))])
892 B<SendToModule> just like any other fvwm commands expands several dollar
893 prefixed variables. This may clash with the dollars perl uses.
894 You may avoid this by prefixing SendToModule with a leading dash.
895 The following 2 lines in each pair are equivalent:
897 SendToModule FvwmPerl eval $$d = "$[DISPLAY]"
898 -SendToModule FvwmPerl eval $d = "$ENV{DISPLAY}"
900 SendToModule FvwmPerl eval \
901 cmd("Echo desk=$d, display=$$d")
902 SendToModule FvwmPerl preprocess -c \
903 Echo desk=%("$d")%, display=%{$$d}%
905 Another solution to avoid escaping of special symbols like dollars
906 and backslashes is to create a perl file in ~/.fvwm and then load it:
908 SendToModule FvwmPerl load build-menus.fpl
910 If you need to preprocess one command starting with a dash, you should
911 precede it using "--".
913 # this prints the current desk, i.e. "0"
914 SendToModule FvwmPerl preprocess -c Echo "$%{$a = "c"; ++$a}%"
916 SendToModule FvwmPerl preprocess -c -- -Echo "$%{"d"}%"
917 # this prints "$d" (SendToModule expands $$ to $)
918 SendToModule FvwmPerl preprocess -c -- -Echo "$$%{"d"}%"
920 -SendToModule FvwmPerl preprocess -c -- -Echo "$$%{"d"}%"
922 Again, it is suggested to put your command(s) into file and preprocess
927 FvwmPerl being written in perl and dealing with perl, follows the famous
928 perl motto: "There's more than one way to do it", so the choice is yours.
930 Here are more pairs of equivalent lines:
932 Module FvwmPerl --load "my.fpl" --stay
933 Module FvwmPerl -e 'load("my.fpl")' -s
935 SendToModule FvwmPerl preprocess --quote '@' my.ppp
936 SendToModule FvwmPerl eval preprocess({quote => '@'}, "my.ppp");
938 Warning, you may affect the way FvwmPerl works by evaluating appropriate
939 perl code, this is considered a feature not a bug. But please don't do this,
940 write your own fvwm module in perl instead.
944 The fvwm(1) man page describes all available commands.
946 Basically, in your perl code you may use any function or class method from
947 the perl library installed with fvwm, see the man pages of perl packages
948 B<General::FileSystem>, B<General::Parse> and B<FVWM::Module>.
952 Mikhael Goikhman <migo@homemail.com>.