use strict; use warnings; use Data::Dumper; # The "use Tk" MUST be before "use POE"... use Tk; use Tk::DialogBox; use POE; use POE::Wheel::Run; # Create GUI window... my $top = $::poe_main_window; $top->geometry('300x50'); $top->title("PID=$$"); $top->protocol('WM_DELETE_WINDOW', sub{exit}); # Create button to push... $top->Button(-text=>"Don't Push Me - WAIT", -command=>sub{ print STDERR "Parent Asking User\n"; print STDERR "Got: ", AskUser("PID=$$"), "\n"; })->pack; print STDERR "Parent PID=$$\n"; my $session=_poeSetup(); # Go... $poe_kernel->run(); sub _poeSetup { my $session = POE::Session->create( inline_states=>{ KidAsk => sub { print STDERR "GUI Request from Child...\n"; my $ret=AskUser("PID=$$"); print STDERR "Got: $ret\n"; return($ret); }, KidOut => sub { my ($heap, $line, $wid)=@_[HEAP, ARG0, ARG1]; my $child = $heap->{Kids}{WID}{$wid}; print STDERR $child->PID . " OUT: $line\n"; }, KidErr => sub { my ($heap, $line, $wid)=@_[HEAP, ARG0, ARG1]; my $child = $heap->{Kids}{WID}{$wid}; print STDERR $child->PID . " ERR: $line\n"; }, KidClose => \&_DoClose, _start => sub { my ($kernel, $heap) = @_[KERNEL, HEAP]; $kernel->alias_set('GUI'); my $child = POE::Wheel::Run->new( Program => sub { print STDERR "Sleeping..."; system("sleep 3"); print STDERR "GUI Request from $$\n"; # Question 1 my $ret = $kernel->post('GUI','KidAsk'); # Question 2 my $ret = $kernel->yield('AskEvent'); print STDERR "DONE: $ret\n"; system("tail -f /etc/profile"); }, StdoutEvent => 'KidOut', StderrEvent => 'KidErr', CloseEvent => 'KidClose', # Question 2 AskEvent => 'KidAsk', ); $kernel->sig_child($child->PID, '_DoSig'); $heap->{Kids}{WID}{$child->ID} = $child; $heap->{Kids}{PID}{$child->PID} = $child; # Verification $kernel->yield('KidAsk'); } }, ); return($session); } ################################# # POE Session Supporting Routines ################################# sub _DoClose { my $wid = $_[ARG0]; my $child = $_[HEAP]{Kids}{WID}{$wid}; unless (defined $child) { print STDERR "wid $wid closed all pipes.\n"; return; } print STDERR "wid $wid closed all pipes.\n"; delete $_[HEAP]{Kids}{PID}{$child->PID}; } sub _DoSig { print STDERR "pid $_[ARG1] exited with status $_[ARG2].\n"; my $child = delete $_[HEAP]{Kids}{PID}{$_[ARG1]}; return unless defined $child; delete $_[HEAP]{Kids}{WID}{$child->ID}; } sub AskUser { my $txt = shift || 'No text passed'; print STDERR "$txt\n"; my $top = $::poe_main_window; # Create a dialog box to ask for a password... my $d = $top->DialogBox( -title=>"$txt", -buttons=>['Ok', 'Cancel'], -default_button=>'Ok', ); # Add the entry widget where user will type password... my $e = $d->add('Entry', -width=>30, -show => '*')->pack; $d->add('Label', -text => "What is your favorite color?")->pack; my $ans = $d->Show(); # If user didn't say ok... if ($ans ne "Ok") { die( "I give up, exiting...\n") }; # Get & return what the user typed... my $pw = $e->get; return($pw); }