stumped by graphics display problem...

Discussion in 'Perl Misc' started by kj, May 31, 2007.

  1. kj

    kj Guest

    I need to generate and view a large number of data plots. My plan
    for this was to have a loop that at each iteration would generate
    the plot, display it, and wait for keyboard input before proceeding
    to the next iteration. (FWIW, this code is to run on a remote
    Linux system, and the display should take place on a local Mac OS
    X workstation running an X11 server.)

    The code I've written succeeds in displaying the graph, but somehow
    the displaying of the graph the script's execution, so the script
    does not get to request for keyboard input to move on to the next
    iteration.

    The relevant portion of the code is shown below. (In this snippet
    I have omitted all error checking and other such details for clarity;
    still, I confirmed that this simplified version of the code displays
    the behavior I described above.) The place where the problem occurs
    is indicated with "###".

    # unbuffer selected output handle (STDOUT)
    $| = 1;

    for my $data ( @data ) {
    my $chart = GD::Graph::lines->new( 400, 300 );
    $chart->set( transparent => 0 );

    # next line produces a GD::Image object
    my $gd = $chart->plot( $data );

    open my $IMG, '|-', 'display';
    print $IMG $gd->png;

    # display won't happen without this line!
    close $IMG;

    ### script stalls before executing the next line

    print "Press any key to continue... ";
    ReadMode 'cbreak';
    ReadKey( 0 );
    ReadMode 'normal';
    print "\n";
    }

    If someone could explain to me why this snippet is not behaving as
    I expect it to I'd be most thankful.

    BTW, I found it surprising that I needed to close the $IMG handle
    for the display to appear; turning on autoflush on the handle was
    not enough.

    Maybe the problem with the code above has more to do with a
    peculiarity of the 'display' command (from the ImageMagick suite)
    than with the Perl code? If so, is there a better way to achieve
    what I trying to do?

    Any suggestions or comments would be much appreciated.

    TIA!

    kj

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
    kj, May 31, 2007
    #1
    1. Advertising

  2. kj

    Greg Bacon Guest

    In article <f3mk0m$e36$>,
    kj <> wrote:

    : [...]
    : # display won't happen without this line!
    : close $IMG;
    :
    : ### script stalls before executing the next line

    The perlfunc(1) manpage's section on the close operator makes the
    following note: "Closing a pipe also waits for the process executing
    on the pipe to complete . . ."

    Hope this helps,
    Greg
    --
    War is no longer merely a crime; it is an absurdity. It is no longer
    merely immoral and cruel; it is stupid. It is no longer merely murder
    on a large scale; it is suicide and voluntary ruin.
    -- Frederic Passy
    Greg Bacon, May 31, 2007
    #2
    1. Advertising

  3. kj

    Mumia W. Guest

    On 05/31/2007 08:53 AM, kj wrote:
    > [...]
    > open my $IMG, '|-', 'display';
    > print $IMG $gd->png;
    >
    > # display won't happen without this line!
    > close $IMG;
    >
    > ### script stalls before executing the next line
    >
    > print "Press any key to continue... ";
    > ReadMode 'cbreak';
    > ReadKey( 0 );
    > ReadMode 'normal';
    > print "\n";
    > }
    > [...]


    The method used to remotely display X programs is different from the
    method used to remotely display console programs, and Term::ReadKey
    doesn't have internal support for remote displays.

    Trying to mix console type user-interaction with graphical
    user-interaction will confound you. It's best just to make your program
    fully graphical with one of the toolkits available: Gtk, Perl-Tk, etc.
    Mumia W., May 31, 2007
    #3
  4. kj

    kj Guest

    In <oOD7i.11968$> "Mumia W." <> writes:

    >On 05/31/2007 08:53 AM, kj wrote:
    >> [...]
    >> open my $IMG, '|-', 'display';
    >> print $IMG $gd->png;
    >>
    >> # display won't happen without this line!
    >> close $IMG;
    >>
    >> ### script stalls before executing the next line
    >>
    >> print "Press any key to continue... ";
    >> ReadMode 'cbreak';
    >> ReadKey( 0 );
    >> ReadMode 'normal';
    >> print "\n";
    >> }
    >> [...]


    >The method used to remotely display X programs is different from the
    >method used to remotely display console programs, and Term::ReadKey
    >doesn't have internal support for remote displays.


    >Trying to mix console type user-interaction with graphical
    >user-interaction will confound you. It's best just to make your program
    >fully graphical with one of the toolkits available: Gtk, Perl-Tk, etc.


    There's no shortage of fully graphical programs for viewing PNG
    files, but what I need is a viewer that I can control *entirely*
    from the keyboard. Are you saying that this would be too difficult
    to program?

    kj
    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
    kj, May 31, 2007
    #4
  5. kj

    Mumia W. Guest

    On 05/31/2007 12:42 PM, Mumia W. wrote:
    > [...]
    > Trying to mix console type user-interaction with graphical
    > user-interaction will confound you [....]


    And me too. Mr. Bacon's comment is correct. The user must close
    'display' before your program continues.

    However, I would still avoid using both Term::ReadKey and X11 to
    interact with the same user.
    Mumia W., May 31, 2007
    #5
  6. kj

    Greg Bacon Guest

    It seems like that code ought to be a lot simpler. I tried using mjd's
    Secret Passage trick[*], but display never got the chance to start
    because the pipe filled up while I tried to write the image data to it.

    [*] <URL:http://perl.plover.com/LOD/199906.html#9>

    Hmm.. what about a double-fork.. That gets pretty close, but it leaves
    the display process running.

    #! /usr/local/bin/perl

    use warnings;
    use strict;

    open my $png, "<", "out.png" or die "$0: open: $!";

    my $pid = open my $display, "|-";
    die "$0: fork: $!" unless defined $pid;

    if ($pid) {
    print { $display } <$png>;
    close $display or warn "$0: pipe exited $?";
    }
    else {
    unless (fork) {
    exec "display", "-" or die "$0: exec: $!";
    }
    exit 0;
    }

    print "Press enter to exit...\n";
    my(undef) = scalar <>;

    Without the curlies around $display in the parent's print, I get a
    syntax error near "$png>" with perl v5.8.5. Weird.

    Greg
    --
    The people cannot delegate to government the power to do anything
    which would be unlawful for them to do themselves.
    -- John Locke
    Greg Bacon, May 31, 2007
    #6
  7. kj

    kj Guest

    In <f3nbv4$b0g$> (Alan Curry) writes:

    >In article <f3n312$evg$>,


    >What you're trying to do is separate closing the pipe from waiting on the
    >child process. The magical '|-' open ties those 2 actions together because
    >most of the time, having them tied together is convenient. If you want them
    >separate, you have to give up the magic and write it the long way with pipe()
    >and fork().


    Thanks, that worked like gangbusters.

    ># Create a pipe and a child process
    >my ($rd, $wr);
    >pipe($rd, $wr) or die "pipe: $!\n";
    >my $pid=fork();
    >defined($pid) or die "fork: $!\n";


    >if(!$pid) {
    > # Child process reads from the pipe on stdin
    > open(STDIN, '<&', $rd);
    > # Child process doesn't write to the pipe, so close that end.
    > close($wr);
    > #{ exec 'display' } # I don't have "display"
    > { exec 'xli', 'stdin' } # But I do have xli
    > die "exec: $!\n";
    >}


    I'm curious: why the curly brackets around the exec statement?

    Thanks again,

    kj

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
    kj, May 31, 2007
    #7
  8. On Thu, 31 May 2007 20:42:12 +0000, Alan Curry wrote:

    > (You can't quit the "display" program using the keyboard?)


    'q'

    HTH,
    M4
    Martijn Lievaart, Jun 1, 2007
    #8
  9. On Thu, 31 May 2007 18:09:38 +0000 (UTC),
    kj <> wrote:
    > In <oOD7i.11968$> "Mumia W." <> writes:
    >
    >>On 05/31/2007 08:53 AM, kj wrote:
    >>> [...]
    >>> open my $IMG, '|-', 'display';
    >>> print $IMG $gd->png;
    >>>
    >>> # display won't happen without this line!
    >>> close $IMG;
    >>>
    >>> ### script stalls before executing the next line
    >>>
    >>> print "Press any key to continue... ";
    >>> ReadMode 'cbreak';
    >>> ReadKey( 0 );
    >>> ReadMode 'normal';
    >>> print "\n";
    >>> }
    >>> [...]

    >
    >>The method used to remotely display X programs is different from the
    >>method used to remotely display console programs, and Term::ReadKey
    >>doesn't have internal support for remote displays.

    >
    >>Trying to mix console type user-interaction with graphical
    >>user-interaction will confound you. It's best just to make your program
    >>fully graphical with one of the toolkits available: Gtk, Perl-Tk, etc.

    >
    > There's no shortage of fully graphical programs for viewing PNG
    > files, but what I need is a viewer that I can control *entirely*
    > from the keyboard. Are you saying that this would be too difficult
    > to program?


    You could always use the Image::Magick module in a child process and
    control that child from the parent via a pipe, or signals if control is
    simple enough.

    The Image::Magick module can do pretty much everything the command line
    tools can do as well.


    Of course, you can also fork and exec a child for the display command
    line program, and then control that with a signal.

    Martien
    --
    |
    Martien Verbruggen | If it isn't broken, it doesn't have enough
    | features yet.
    |
    Martien verbruggen, Jun 2, 2007
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jheitmuller
    Replies:
    3
    Views:
    2,460
    Peter Rilling
    Feb 5, 2004
  2. harry

    Stumped on EJB problem?

    harry, Dec 11, 2004, in forum: Java
    Replies:
    0
    Views:
    298
    harry
    Dec 11, 2004
  3. Si
    Replies:
    7
    Views:
    443
  4. =?Utf-8?B?ZGF2ZQ==?=

    cache reseting problem stumped

    =?Utf-8?B?ZGF2ZQ==?=, Apr 13, 2007, in forum: ASP .Net
    Replies:
    1
    Views:
    373
  5. shanx
    Replies:
    2
    Views:
    91
    Bob Walton
    Mar 19, 2005
Loading...

Share This Page