#!/usr/bin/env perl # emwave2d.wrapper - Launcher for "emwave2d" main program # License: Creative Commons Attribution-NonCommercial-ShareAlike 2.5 # Revision: 080919 # Note: The license indicated above applies to this file. It doesn't # apply to the official EMWave2D package, or to any file derived from # that package. #--------------------------------------------------------------------- # license information #--------------------------------------------------------------------- # This section may not be modified except as approved by the author or # licensor, or to make non-content changes such as adjustments to par- # agraph formatting or white space. # This version of this software is distributed under the following # license: # # Creative Commons Attribution-NonCommercial-ShareAlike 2.5 # You may use, modify, and redistribute this software without fees or # royalties, but only under the terms and conditions set forth by the # license. In particular, copies and derived works cannot be used for # commercial purposes. Additionally, the license propagates to copies # and derived works. Furthermore, you must provide attribution "in the # manner specified by the author or licensor". The latter point is # discussed below. # The author [and licensor] hereby specifies that attribution must be # handled in the following manner: a. If the software is interactive, # any About or Credits dialog boxes, windows, or output text provided # by the original version must be preserved and readily accessible to # the end user at runtime. b. If the software is non-interactive, or # if it does not provide About or Credits dialog boxes, windows, or # output text, the operating system and/or desktop environment used # must provide attribution that is visible and/or readily accessible # to the end user at runtime. # The following techniques do not meet the attribution requirements: # Attribution through text files, attribution through printed docu- # mentation, verbal attribution, or postings on external web sites # [i.e., web sites that are not an intrinsic local component of the # operating system or desktop environment used]. These examples are # provided for illustrative purposes only. # It should be noted that trademarks are an additional issue. If this # software uses any trademarks, trademark-related restrictions may # apply. # This is not a complete explanation of the terms and conditions in- # volved. For more information, see the Creative Commons Attribution- # NonCommercial-ShareAlike 2.5 license. #--------------------------------------------------------------------- # explanation #--------------------------------------------------------------------- # 1. Overview: # This script performs some setup operations and starts the main # EMWave2D executable [which must be renamed to "emwave2d.bin"]. Pre- # sently, the following steps are implemented: # # a. It optionally verifies that multiple instances of the program # aren't running. If the test is done, and multiple instances # are running, a fatal-error message is displayed. # # b. It optionally verifies that the program isn't running through # VNC. If the test is done, and the program is running through # VNC, a fatal-error message is displayed. # # c. It optionally verifies that direct rendering is available. # If the test is done, and direct rendering isn't available, a # fatal-error message is displayed. # # d. If optionally checks for NVidia graphics hardware. If the # test is done, and NVidia graphics hardware is present, a # warning message is displayed. Note: The user may exit at this # point. # # e. It runs the target executable using appropriate arguments. # Additionally, it arranges for temporary files [if any] to be # deleted after the target exits. #--------------------------------------------------------------------- # 2. Requirements: # At the GUI level, this program requires Perl 5, "glxinfo", Perl- # Gtk2, and LACSUB. # These components are standard, except for LACSUB. You should be able # to obtain LACSUB from the same place as this file. Note: LACSUB # [like this file] is distributed under a Creative Commons license. # For more information about license issues, see the comments at the # start of this file. #--------------------------------------------------------------------- # standard module setup #--------------------------------------------------------------------- require 5.6.1; use strict; use Carp; use warnings; # Trap warnings $SIG {__WARN__} = sub { die @_; }; #--------------------------------------------------------------------- # add CPAN module[s] #--------------------------------------------------------------------- use Gtk2 '-init'; use Gtk2::SimpleList; #--------------------------------------------------------------------- # add LACSUB module[s] #--------------------------------------------------------------------- use LACSUB::GUI ( @LACSUB::GUI::EXPORT_OK ); #--------------------------------------------------------------------- # basic constants #--------------------------------------------------------------------- use constant ZERO => 0; # Zero use constant ONE => 1; # One use constant FALSE => 0; # Boolean FALSE use constant TRUE => 1; # Boolean TRUE #--------------------------------------------------------------------- # program parameters #--------------------------------------------------------------------- my $DIR_BASE = '__META_PREFIX__'; my $IE = 'Internal error'; my $PROGNAME = 'emwave2d'; my $REVISION = '080919'; # Revision [or release] string my $ALERT_ICON_PATH = "$DIR_BASE/misc/alert.png"; my $DIR_SELECT = "$DIR_BASE/data"; my $NEXT_PROGRAM = "$DIR_BASE/bin/$PROGNAME.bin"; my $LIST_TITLE = 'Objects'; my $MAIN_TITLE = 'Start EMWave2D'; my $MAIN_WIDTH = 775; my $MAIN_HEIGHT = 360; #--------------------------------------------------------------------- # $DEFAULT_PATTERN may be defined or undefined. If it's defined, it # should specify a Perl pattern string enclosed in parentheses. This # program checks filenames associated with the selection list used # against the specified pattern. Note: The check is done using base # filenames. For the purposes of this check, pathname components and # filename extensions are ignored. # If one file's name matches the specified pattern [ignoring alphabet- # ic case], an entry named "(default)" is added to the selection list, # and the "(default)" entry selects the matching file. If there's a # match for more than one file, "(default)" is added [regardless], and # an arbitrary selection is made. my $DEFAULT_PATTERN = '(sample-emwave2d)'; #--------------------------------------------------------------------- # If this program requires direct-rendering support, set $FLAG_CHECK_ # DIRECT_RENDERING equal to TRUE. Otherwise, set this flag equal to # FALSE. my $FLAG_CHECK_DIRECT_RENDERING = TRUE; #--------------------------------------------------------------------- # If this program has difficulties with NVidia graphics hardware, set # $FLAG_CHECK_NVIDIA equal to TRUE. Otherwise, set this flag equal to # FALSE. my $FLAG_CHECK_NVIDIA = FALSE; #--------------------------------------------------------------------- # If you'd like to prohibit multiple instances, set $FLAG_PROHIBIT_ # MULTI_INSTANCE to TRUE. Otherwise, set this flag to FALSE. my $FLAG_PROHIBIT_MULTI_INSTANCE = TRUE; #--------------------------------------------------------------------- # If this program shouldn't try to run under VNC, set $FLAG_PROHIBIT_ # VNC equal to TRUE. Otherwise, set this flag equal to FALSE. my $FLAG_PROHIBIT_VNC = TRUE; #--------------------------------------------------------------------- # $SELECT_EXT specifies the filename extension that this program # looks for when it's scanning for user-selectable files. Note: Lead- # ing periods are optional. my $SELECT_EXT = 'png'; #--------------------------------------------------------------------- # If @EXTRAPARAM is non-empty, its contents are added to the end of # the target-program argument list used. my @EXTRAPARAM = ( "$DIR_BASE/data/refindex.dat" ); #--------------------------------------------------------------------- # global variables #--------------------------------------------------------------------- my %DataMap = (); # Maps data-set descriptions to path- # names my $MainWindow; # GTK2 main window #--------------------------------------------------------------------- # The following variable[s] is/are Perl-Gtk2 objects: my $SimpleList; # SimpleList: List of data-set names #--------------------------------------------------------------------- # support routines #--------------------------------------------------------------------- # "ExecTarget" runs the target program, taking the currently-specified # options and/or settings into account. sub ExecTarget { my $str; # Scratch my @tmpfiles = (); # List of temporary-file pathnames #--------------------------------------------------------------------- # Initial setup. my ($model, $iter) = $SimpleList->get_selection->get_selected; my $selected = $model->get ($iter, ZERO); my $DataFile = $DataMap {$selected}; # Sanity check die "$IE #0001\n" unless defined $DataFile; #--------------------------------------------------------------------- # Create temporary file[s]. my $tmpfile = "/tmp/$PROGNAME-$>-$$.bmp"; system << "END"; pngtopnm < $DataFile | ppmtobmp --bpp=24 > $tmpfile END push (@tmpfiles, $tmpfile); #--------------------------------------------------------------------- # Change working directory. chdir $DIR_SELECT; #--------------------------------------------------------------------- # Build target-program argument list. my @ARGS = (); # Target-program argument list push (@ARGS, $tmpfile); # Add temporary file push (@ARGS, @EXTRAPARAM); # Add more argument[s] #--------------------------------------------------------------------- # Wrap it up. if (scalar @tmpfiles) { my $args = join ' ', @ARGS; my $tmpfiles = join ' ', @tmpfiles; system << "END"; ( $NEXT_PROGRAM $args ; rm -f $tmpfiles ) & END exit ZERO; } else { exec $NEXT_PROGRAM, @ARGS; exit ONE; } exit ONE; } #--------------------------------------------------------------------- # special-key handler #--------------------------------------------------------------------- sub SpecialKeyHandler { my $widget = shift; my $event = shift; my $keypress = $event->keyval; if ($keypress == $Gtk2::Gdk::Keysyms {Escape}) { Gtk2->main_quit; $MainWindow->destroy; exit (ONE); } if ($keypress == $Gtk2::Gdk::Keysyms {KP_Enter} || $keypress == $Gtk2::Gdk::Keysyms {Return }) { &ExecTarget(); # Shouldn't get here &PanicDialog ("#$REVISION-0001"); #ifdef NOTDEF # Not presently used # return TRUE; # Consume the event #endif } return FALSE; # Pass the event on to GTK2 } #--------------------------------------------------------------------- # main routine #--------------------------------------------------------------------- sub Main { my $dirent; # Directory entry my $str; # Scratch #--------------------------------------------------------------------- # Go to user's home directory. my $HOME = $ENV {HOME}; $HOME = '/' unless defined $HOME; chdir $HOME; #--------------------------------------------------------------------- # Verify that program isn't already running. &VerifyNotRunning ( -icon_path => $ALERT_ICON_PATH , -name => $PROGNAME , -pattern_this => ':\d\d\s(perl |)(\S+/|)' . $PROGNAME . '(|\.wrapper)\s' , -pattern_next => ':\d\d\s(perl |)(\S+/|)' . $PROGNAME . '\.bin\s' ) if $FLAG_PROHIBIT_MULTI_INSTANCE; #--------------------------------------------------------------------- # Handle VNC test (if enabled). &AbortIfVNC ( -icon_path => $ALERT_ICON_PATH , -name => $PROGNAME ) if $FLAG_PROHIBIT_VNC; #--------------------------------------------------------------------- # Handle direct-rendering test (if enabled). &AbortUnlessDRI ( -icon_path => $ALERT_ICON_PATH , -name => $PROGNAME ) if $FLAG_CHECK_DIRECT_RENDERING; #--------------------------------------------------------------------- # NVidia-related kludge. &CheckNVidia ( -icon_path => $ALERT_ICON_PATH , -name => $PROGNAME ) if $FLAG_CHECK_NVIDIA; #--------------------------------------------------------------------- # Are any arguments specified? if (scalar (@ARGV)) { # Yes - Proceed immediately exec $NEXT_PROGRAM, @ARGV; } #--------------------------------------------------------------------- # Build list of user-selectable files. my $DEFAULT_PATH; $SELECT_EXT =~ s@^\.@@; die "$IE #0002\n" unless length $SELECT_EXT; opendir (DIR, $DIR_SELECT) || die "$IE #0003\n"; while (defined ($dirent = readdir (DIR))) { next unless $dirent =~ m@^([a-z0-9_\-]+)\.$SELECT_EXT\z@i; my $path = "$DIR_SELECT/$dirent"; next unless -f $path; $str = $1; $str =~ s@-+@ @g; $str =~ s@_+@ @g; $str =~ s@([a-z0-9])([A-Z])@$1 $2@; $str =~ s@(^| )([a-z])@$1 . uc ($2)@geis; $DataMap {$str} = $path; $str = $dirent; $str =~ s@\.\w+\z@@i; if (defined ($DEFAULT_PATTERN) && ($str =~ m@$DEFAULT_PATTERN@i)) { $DEFAULT_PATH = $path; } } closedir DIR; $DataMap {'(default)'} = $DEFAULT_PATH if defined $DEFAULT_PATH; #--------------------------------------------------------------------- # Create main window. $MainWindow = Gtk2::Window->new; $MainWindow->set_position ('GTK_WIN_POS_CENTER'); $MainWindow->set_title ($MAIN_TITLE); $MainWindow->signal_connect (delete_event => sub { Gtk2->main_quit; TRUE; }); $MainWindow->signal_connect ('destroy', sub { Gtk2->main_quit; } ); $MainWindow->set_default_size ($MAIN_WIDTH, $MAIN_HEIGHT); my $white = Gtk2::Gdk::Color->new (0xFFFF,0xFFFF,0xFFFF); $MainWindow->modify_bg ('normal', $white); $MainWindow->signal_connect ('key_release_event' => \&SpecialKeyHandler); #--------------------------------------------------------------------- # Create some regions. my $vbox = Gtk2::VBox->new (FALSE, 6); $MainWindow->add ($vbox); my $frame2 = Gtk2::Frame->new(); $vbox->pack_start ($frame2, TRUE, TRUE, ZERO); $frame2->set_border_width (3); #--------------------------------------------------------------------- # Create a Gtk2 "SimpleList" for the selectable-entry list. $SimpleList = Gtk2::SimpleList->new ($LIST_TITLE => 'text'); my @list = sort keys %DataMap; if (((scalar @list) > ONE) && ($list [ONE] =~ m@\(default@)) { $str = $list [ZERO]; $list [ZERO] = $list [ONE]; $list [ONE ] = $str; } # This part is admittedly complicated @{$SimpleList->{data}} = map { $_ = [ $_ ]; } @list; $SimpleList->signal_connect (row_activated => \&ExecTarget); $SimpleList->select (ZERO); #--------------------------------------------------------------------- # Put the "SimpleList" in a Gtk2 "ScrolledWindow". my $ListWindow = Gtk2::ScrolledWindow->new (undef, undef); $ListWindow -> set_policy ('automatic', 'automatic'); $ListWindow -> add ($SimpleList); #--------------------------------------------------------------------- # Define message text (with tags). # Note: The message text can use certain HTML-like tags, but HTML per # se isn't supported. For more information, see LACSUB. my $text = << 'END';

simulates electromagnetic waves. It uses the finite difference time domain (FDTD) method to solve Maxwell's Equations.

This is a quick-start screen for Use the box on the left to select a mode. Left-click on a mode name, then press Enter or click OK. If you double-click, you shouldn't need to press any keys. To abort at this stage, press Escape or alt-Q, or click Quit.

After starts, press Play to start a simulation. Press Pause to stop it. To exit, left-click on the x in the upper-right corner of the main window.

Note: This program needs a fast system (2 GHz CPU or faster). Output may be sluggish on slower systems.

 

END #--------------------------------------------------------------------- # Create a Gtk2 "TextView" for the message text. my $textview = &LACGTK2_CreateTextView ( -text => $text , -top_space => ONE ); #--------------------------------------------------------------------- # Assemble all the pieces. my $FrameText = Gtk2::Frame->new ('Instructions'); $FrameText -> set_border_width (3); $FrameText -> add ($textview); my $RightSide = Gtk2::VBox->new (FALSE, 6); $RightSide -> pack_start ($FrameText , TRUE , 0, 1); my $MainTable = Gtk2::Table->new (1, 4, TRUE); $MainTable -> attach_defaults ($ListWindow , 0, 1, 0, 1); $MainTable -> attach_defaults ($RightSide , 1, 4, 0, 1); $frame2 -> add ($MainTable); #--------------------------------------------------------------------- # Add OK/Quit buttons. &LACGTK2_AddButtons ( -vbox => $vbox , -action_ok => '&ExecTarget' , -action_quit => 'quit' ); #--------------------------------------------------------------------- # Wrap it up. $MainWindow->show_all; Gtk2->main; undef; } #--------------------------------------------------------------------- # main program #--------------------------------------------------------------------- &Main(); # Call the main routine exit ZERO; # Normal exit