home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Tk.pm < prev    next >
Encoding:
Perl POD Document  |  2003-12-12  |  5.4 KB  |  209 lines

  1. # $Id: Tk.pm,v 1.43 2003/12/12 04:05:06 rcaputo Exp $
  2.  
  3. # Tk-Perl event loop bridge for POE::Kernel.
  4.  
  5. # Empty package to appease perl.
  6. package POE::Loop::Tk;
  7.  
  8. # Include common things.
  9. use POE::Loop::PerlSignals;
  10. use POE::Loop::TkCommon;
  11.  
  12. use vars qw($VERSION);
  13. $VERSION = do {my@r=(q$Revision: 1.43 $=~/\d+/g);sprintf"%d."."%04d"x$#r,@r};
  14.  
  15. use Tk 800.021;
  16. use 5.00503;
  17.  
  18. # Everything plugs into POE::Kernel.
  19. package POE::Kernel;
  20.  
  21. use strict;
  22.  
  23. # Hand off to POE::Loop::TkActiveState if we're running under
  24. # ActivePerl.
  25. BEGIN {
  26.   if ($^O eq "MSWin32") {
  27.     require POE::Loop::TkActiveState;
  28.     POE::Loop::TkActiveState->import();
  29.     die "not really dying";
  30.   }
  31. }
  32.  
  33. my @_fileno_refcount;
  34.  
  35. #------------------------------------------------------------------------------
  36. # Loop construction and destruction.
  37.  
  38. sub loop_initialize {
  39.   my $self = shift;
  40.  
  41.   $poe_main_window = Tk::MainWindow->new();
  42.   die "could not create a main Tk window" unless defined $poe_main_window;
  43.   $self->signal_ui_destroy($poe_main_window);
  44. }
  45.  
  46. sub loop_finalize {
  47.   # does nothing
  48. }
  49.  
  50. #------------------------------------------------------------------------------
  51. # Maintain filehandle watchers.
  52.  
  53. sub loop_watch_filehandle {
  54.   my ($self, $handle, $mode) = @_;
  55.   my $fileno = fileno($handle);
  56.  
  57.   my $tk_mode;
  58.   if ($mode == MODE_RD) {
  59.     $tk_mode = 'readable';
  60.   }
  61.   elsif ($mode == MODE_WR) {
  62.     $tk_mode = 'writable';
  63.   }
  64.   else {
  65.     # The Tk documentation implies by omission that expedited
  66.     # filehandles aren't, uh, handled.  This is part 1 of 2.
  67.     confess "Tk does not support expedited filehandles";
  68.   }
  69.  
  70.   # Start a filehandle watcher.
  71.  
  72.   $poe_main_window->fileevent
  73.     ( $handle,
  74.       $tk_mode,
  75.  
  76.       # The handle is wrapped in quotes here to stringify it.  For
  77.       # some reason, it seems to work as a filehandle anyway, and it
  78.       # breaks reference counting.  For filehandles, then, this is
  79.       # truly a safe (strict ok? warn ok? seems so!) weak reference.
  80.       [ \&_loop_select_callback, $fileno, $mode ],
  81.     );
  82.  
  83.   $_fileno_refcount[fileno $handle]++;
  84. }
  85.  
  86. sub loop_ignore_filehandle {
  87.   my ($self, $handle, $mode) = @_;
  88.  
  89.   # The Tk documentation implies by omission that expedited
  90.   # filehandles aren't, uh, handled.  This is part 2 of 2.
  91.   confess "Tk does not support expedited filehandles"
  92.     if $mode == MODE_EX;
  93.  
  94.   # The fileno refcount just dropped to 0.  Remove the handle from
  95.   # Tk's file watchers.
  96.  
  97.   unless (--$_fileno_refcount[fileno $handle]) {
  98.     $poe_main_window->fileevent
  99.       ( $handle,
  100.  
  101.         # It can only be MODE_RD or MODE_WR here (MODE_EX is checked a
  102.         # few lines up).
  103.         ( ( $mode == MODE_RD ) ? 'readable' : 'writable' ),
  104.  
  105.         # Nothing here!  Callback all gone!
  106.         ''
  107.       );
  108.   }
  109.  
  110.   # Otherwise we have other things watching the handle.  Go into Tk's
  111.   # undocumented guts to disable just this watcher without hosing the
  112.   # entire fileevent thing.
  113.  
  114.   else {
  115.     my $tk_file_io = tied( *$handle );
  116.     die "whoops; no tk file io object" unless defined $tk_file_io;
  117.     $tk_file_io->handler
  118.       ( ( ( $mode == MODE_RD )
  119.           ? Tk::Event::IO::READABLE()
  120.           : Tk::Event::IO::WRITABLE()
  121.         ),
  122.         ''
  123.       );
  124.   }
  125. }
  126.  
  127. sub loop_pause_filehandle {
  128.   my ($self, $handle, $mode) = @_;
  129.  
  130.   my $tk_mode;
  131.   if ($mode == MODE_RD) {
  132.     $tk_mode = Tk::Event::IO::READABLE();
  133.   }
  134.   elsif ($mode == MODE_WR) {
  135.     $tk_mode = Tk::Event::IO::WRITABLE();
  136.   }
  137.   else {
  138.     # The Tk documentation implies by omission that expedited
  139.     # filehandles aren't, uh, handled.  This is part 2 of 2.
  140.     confess "Tk does not support expedited filehandles";
  141.   }
  142.  
  143.   # Use an internal work-around to fileevent quirks.
  144.   my $tk_file_io = tied( *$handle );
  145.   die "whoops; no tk file io object" unless defined $tk_file_io;
  146.  
  147.   $tk_file_io->handler($tk_mode, "");
  148. }
  149.  
  150. sub loop_resume_filehandle {
  151.   my ($self, $handle, $mode) = @_;
  152.   my $fileno = fileno($handle);
  153.  
  154.   # The Tk documentation implies by omission that expedited
  155.   # filehandles aren't, uh, handled.  This is part 2 of 2.
  156.   confess "Tk does not support expedited filehandles"
  157.     if $mode == MODE_EX;
  158.  
  159.   # Use an internal work-around to fileevent quirks.
  160.   my $tk_file_io = tied( *$handle );
  161.   die "whoops; no tk file io object" unless defined $tk_file_io;
  162.  
  163.   $tk_file_io->handler( ( ( $mode == MODE_RD )
  164.                           ? Tk::Event::IO::READABLE()
  165.                           : Tk::Event::IO::WRITABLE()
  166.                         ),
  167.                         [ \&_loop_select_callback,
  168.                           $fileno,
  169.                           $mode,
  170.                         ]
  171.                       );
  172. }
  173.  
  174. # Tk filehandle callback to dispatch selects.
  175. sub _loop_select_callback {
  176.   my ($fileno, $mode) = @_;
  177.   $poe_kernel->_data_handle_enqueue_ready($mode, $fileno);
  178.   $poe_kernel->_test_if_kernel_is_idle();
  179. }
  180.  
  181. 1;
  182.  
  183. __END__
  184.  
  185. =head1 NAME
  186.  
  187. POE::Loop::Tk - a bridge that supports Tk's event loop from POE
  188.  
  189. =head1 SYNOPSIS
  190.  
  191. See L<POE::Loop>.
  192.  
  193. =head1 DESCRIPTION
  194.  
  195. This class is an implementation of the abstract POE::Loop interface.
  196. It follows POE::Loop's public interface exactly.  Therefore, please
  197. see L<POE::Loop> for its documentation.
  198.  
  199. =head1 SEE ALSO
  200.  
  201. L<POE>, L<POE::Loop>, L<Tk>
  202.  
  203. =head1 AUTHORS & LICENSING
  204.  
  205. Please see L<POE> for more information about authors, contributors,
  206. and POE's licensing.
  207.  
  208. =cut
  209.