houbin 发表于 2018-9-1 08:47:02

GTK2-Perl程序示例:远程桌面客户端gtkremote-HVH

  这个例子说明了如何将Glade界面直接放在程序中方便在邮件列表和论坛上直接发布程序,以及如何用Gtk2::Helper调用网络程序防止连接超时导致界面阻塞。程序中 用Expect实现了VNC密码输入。
  


[*]#! /usr/bin/perl -w
[*]
[*]#----------------------------------------------------------------------
[*]# gtkremote.pl
[*]#
[*]# A remote desktop frontend of Gtk2/GladeXML
[*]#
[*]# Copyright (C) 2008 Viperii (hominid@tom.com)
[*]#
[*]#This library is free software; you can redistribute it and/or
[*]#modify it under the terms of the GNU Lesser General Public
[*]#License as published by the Free Software Foundation; either
[*]#version 2 of the License, or (at your option) any later version.
[*]#
[*]#This library is distributed in the hope that it will be useful,
[*]#but WITHOUT ANY WARRANTY; without even the implied warranty of
[*]#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU
[*]#Lesser General Public License for more details.
[*]#
[*]#You should have received a copy of the GNU Lesser General Public
[*]#License along with this library; if not, write to the
[*]#Free Software Foundation, Inc., 59 Temple Place - Suite 330,
[*]#Boston, MA 02111-1307, USA.
[*]#
[*]#----------------------------------------------------------------------
[*]
[*]use strict;
[*]use warnings;
[*]
[*]use Glib qw/TRUE FALSE/;
[*]use Gtk2 '-init';
[*]use Gtk2::Helper;
[*]use Gtk2::GladeXML;
[*]
[*]use FindBin qw($Bin);
[*]use Expect;
[*]
[*]my $CMD;
[*]my $PID;
[*]my $TAG;
[*]my $CONN = 0;
[*]my $PREFIX = '@PREFIX@';
[*]my $BIN_DIR = (-d $PREFIX ? "$PREFIX/bin" : $Bin);
[*]my $VNC_TMP = "/tmp/vncpasswd.tmp";
[*]
[*]$| = 1;
[*]
[*]my $glade_data; {local $/ = undef; $glade_data = ;}
[*]my $gladexml = Gtk2::GladeXML->new_from_buffer($glade_data);
[*]#my $gladexml = Gtk2::GladeXML->new($BIN_DIR.'/gtkremote.glade');
[*]$gladexml->signal_autoconnect_from_package('main');
[*]
[*]my $window = $gladexml->get_widget('main');
[*]my $host_entry = $gladexml->get_widget('entry1');
[*]my $port_entry = $gladexml->get_widget('entry2');
[*]my $user_entry = $gladexml->get_widget('entry3');
[*]my $pass_entry = $gladexml->get_widget('entry4');
[*]my $combobox = $gladexml->get_widget('combobox1');
[*]my $button = $gladexml->get_widget('button1');
[*]my $status_icon = $gladexml->get_widget('image2');
[*]
[*]my @prot_list = ("VNC", "RDP");
[*]$combobox->append_text($_) foreach (@prot_list);
[*]$combobox->set_active(0);
[*]
[*]$window->show_all();
[*]Gtk2->main();
[*]$window->destroy;
[*]exit 0;
[*]
[*]sub on_main_delete_event
[*]{
[*]    kill 15 => $PID if $PID;
[*]    unlink $VNC_TMP if -f $VNC_TMP;
[*]    Gtk2->main_quit;
[*]    exit;
[*]}
[*]
[*]sub on_combobox1_changed
[*]{
[*]    $combobox->get_active_text eq "VNC" ? $user_entry->set_sensitive(FALSE) : $user_entry->set_sensitive(TRUE);
[*]}
[*]
[*]sub on_button1_clicked
[*]{
[*]    unless($CONN)
[*]    {
[*]    remote_connect();
[*]    }
[*]    else
[*]    {
[*]    kill 15 => $PID if $PID;
[*]    }
[*]}
[*]
[*]sub status_connect
[*]{
[*]    $CONN = 1;
[*]    $button->child->set_text("Disconnect");
[*]    $status_icon->set_from_stock('gtk-connect', 'large-toolbar');
[*]}
[*]
[*]sub status_disconnect
[*]{
[*]    $CONN = 0;
[*]    $button->child->set_text("Connect");
[*]    $status_icon->set_from_stock('gtk-disconnect', 'large-toolbar');
[*]}
[*]
[*]sub message_dialog_show
[*]{
[*]#$icon can be: a) 'info'
[*]#            b) 'warning'
[*]#            c) 'error'
[*]#            d) 'question'
[*]#$button_type can be: a) 'none'
[*]#                     b) 'ok'
[*]#                     c) 'close'
[*]#                     d) 'cancel'
[*]#                     e) 'yes-no'
[*]#                     f) 'ok-cancel'
[*]
[*]    my ($parent,$icon,$text,$button_type) = @_;
[*]
[*]    my $dialog = Gtk2::MessageDialog->new_with_markup ($parent,
[*]                               ,
[*]                               $icon,
[*]                               $button_type,
[*]                               sprintf "$text");
[*]    my $retval = $dialog->run;
[*]    $dialog->destroy;
[*]    return $retval;
[*]}
[*]
[*]sub remote_connect
[*]{
[*]    status_connect();
[*]
[*]    my $host = $host_entry->get_text;
[*]    my $port = $port_entry->get_text;
[*]    my $user = $user_entry->get_text;
[*]    my $pass = $pass_entry->get_text;
[*]    my $prot = $combobox->get_active_text;
[*]
[*]    if($host)
[*]    {
[*]    if($prot eq "VNC")
[*]    {
[*]      unlink $VNC_TMP if -f $VNC_TMP;
[*]
[*]      $CMD = "vncviewer $host";
[*]      $CMD .= "::$port" if $port =~ /^(\d+)$/;
[*]      if(length($pass) >= 6)
[*]      {
[*]      my $sh = Expect->spawn('/bin/sh') or die "Cannot spawn shell: $!\n";
[*]      my $exp = new Expect;
[*]      my $command = "vncpasswd $VNC_TMP";
[*]      $exp->spawn($command) or die "Cannot spawn $command: $!\n";
[*]      $exp->expect(10, 'Password:');
[*]      $exp->send("$pass\n");
[*]      $exp->expect(10, 'Verify:');
[*]      $exp->send("$pass\n");
[*]      $exp->interact();
[*]      $exp->soft_close();
[*]      $sh->hard_close();
[*]
[*]      $CMD .= " -passwd $VNC_TMP";
[*]      }
[*]      else
[*]      {
[*]      message_dialog_show($window,
[*]                  'error',
[*]                  'VNC password too short.',
[*]                  'ok'
[*]            );
[*]      status_disconnect();
[*]      return;
[*]      }
[*]    }
[*]    elsif($prot eq "RDP")
[*]    {
[*]      $CMD = "rdesktop $host";
[*]      $CMD .= ":$port" if $port =~ /^(\d+)$/;
[*]      $CMD .= " -u $user" if $user;
[*]      $CMD .= " -p $pass" if $pass;
[*]    }
[*]    else
[*]    {
[*]      status_disconnect();
[*]      return;
[*]    }
[*]    }
[*]    else
[*]    {
[*]    status_disconnect();
[*]    return;
[*]    }
[*]
[*]    $PID = open my $pipe, '-|', "$CMD" or die "Failed open pipe: $CMD\n";
[*]
[*]    $TAG = Gtk2::Helper->add_watch(fileno($pipe), in => sub
[*]                   {
[*]                     if(eof($pipe))
[*]                     {
[*]                     Gtk2::Helper->remove_watch($TAG);
[*]                     close($pipe);
[*]                     unlink $VNC_TMP if -f $VNC_TMP;
[*]                     status_disconnect();
[*]                     0;
[*]                     }
[*]                     else
[*]                     {
[*]                     #my $line = ; # stdout string.
[*]                     #print "OUTPUT: ".$line."\n" if $line;
[*]                     }
[*]
[*]                     1;
[*]                   } );
[*]}
[*]
[*]__DATA__
[*]
[*]
[*]
[*]
[*]
[*]    True
[*]    GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]    GTK_WIN_POS_CENTER
[*]    GDK_WINDOW_TYPE_HINT_DIALOG
[*]   
[*]   
[*]      
[*]      True
[*]      GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]      
[*]         
[*]            True
[*]            GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]            
[*]            
[*]                71
[*]                63
[*]                True
[*]                GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                gtk-network
[*]                6
[*]            
[*]            
[*]                53
[*]            
[*]            
[*]         
[*]      
[*]      
[*]         
[*]            True
[*]            GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]            
[*]            
[*]                True
[*]                GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]               
[*]                  
[*]                  39
[*]                  22
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  Host:
[*]                  
[*]                  
[*]                  1
[*]                  10
[*]                  
[*]               
[*]               
[*]                  
[*]                  125
[*]                  25
[*]                  True
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  
[*]                  
[*]                  78
[*]                  10
[*]                  
[*]               
[*]               
[*]                  
[*]                  34
[*]                  23
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  Port:
[*]                  
[*]                  
[*]                  205
[*]                  10
[*]                  
[*]               
[*]               
[*]                  
[*]                  50
[*]                  25
[*]                  True
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  5
[*]                  
[*]                  
[*]                  240
[*]                  10
[*]                  
[*]               
[*]            
[*]            
[*]            
[*]            
[*]                True
[*]                GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]               
[*]                  
[*]                  61
[*]                  22
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  Protocol:
[*]                  
[*]                  
[*]                  7
[*]                  
[*]               
[*]               
[*]                  
[*]                  86
[*]                  27
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  
[*]                  
[*]                  
[*]                  
[*]                  79
[*]                  6
[*]                  
[*]               
[*]            
[*]            
[*]                1
[*]            
[*]            
[*]            
[*]            
[*]                True
[*]                GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]               
[*]                  
[*]                  76
[*]                  22
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  Username:
[*]                  
[*]                  
[*]                  8
[*]                  
[*]               
[*]               
[*]                  
[*]                  115
[*]                  25
[*]                  True
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  128
[*]                  
[*]                  
[*]                  79
[*]                  6
[*]                  
[*]               
[*]               
[*]                  
[*]                  71
[*]                  21
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  Password:
[*]                  
[*]                  
[*]                  36
[*]                  
[*]               
[*]               
[*]                  
[*]                  115
[*]                  25
[*]                  True
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  128
[*]                  False
[*]                  
[*]                  
[*]                  79
[*]                  34
[*]                  
[*]               
[*]            
[*]            
[*]                2
[*]            
[*]            
[*]            
[*]            
[*]                True
[*]                GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]               
[*]                  
[*]                  True
[*]                  True
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  Connect
[*]                  0
[*]                  
[*]                  
[*]                  
[*]                  77
[*]                  10
[*]                  
[*]               
[*]               
[*]                  
[*]                  32
[*]                  32
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  gtk-disconnect
[*]                  3
[*]                  
[*]                  
[*]                  3
[*]                  7
[*]                  
[*]               
[*]               
[*]                  
[*]                  295
[*]                  10
[*]                  True
[*]                  GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
[*]                  
[*]                  
[*]                  4
[*]                  43
[*]                  
[*]               
[*]            
[*]            
[*]                3
[*]            
[*]            
[*]         
[*]         
[*]            1
[*]         
[*]      
[*]      
[*]   
[*]
[*]
  



页: [1]
查看完整版本: GTK2-Perl程序示例:远程桌面客户端gtkremote-HVH