import from Internet Archive
[vncperl.git] / VNC / Server.pm
1 package VNC::Server;\r
2 \r
3 require 5.002;   # becase we use prototypes\r
4 \r
5 use IO::Select;\r
6 use IO::Socket;\r
7 use IO::Socket::INET;\r
8 use Socket;\r
9 use warnings;\r
10 use strict;\r
11 use VNC::ServerConnection;\r
12 use vars qw(@ISA @EXPORT_OK);\r
13 require Exporter;\r
14 @ISA = qw(Exporter);\r
15 @EXPORT_OK = qw();\r
16 \r
17 sub new {\r
18         my $proto = shift;\r
19         my $class = $proto;\r
20 \r
21         my %args = @_ ;\r
22 \r
23         my $self  = {};\r
24         bless ($self, $class);\r
25 \r
26         # Get the port number\r
27         my $port = $args{Port} ||= 0 ;\r
28         # Port number less than 100 is treated as display number\r
29         if ($port < 100 ) {$port += 5900;}\r
30         $self->{PORT} = $port ;\r
31 \r
32         # Get the idle Interval\r
33         $self->{IDLE_INTERVAL} = $args{Idle} || 1 ;\r
34         $self->{IdleHandler} = $args{IdleHandler};\r
35         $self->{KeyEventHandler} = $args{KeyEventHandler};\r
36         $self->{PointerEventHandler} = $args{PointerEventHandler};\r
37         $self->{CutTextHandler} = $args{CutTextHandler};\r
38         $self->{UpdateDisplayHandler} = $args{UpdateDisplayHandler};\r
39         $self->{PixelFormat} = $args{PixelFormat};\r
40         $self->{Caption} = $args{Caption};\r
41         $self->{Width} = $args{Width};\r
42         $self->{Height} = $args{Height};\r
43         $self->{ClientConnectHandler} = $args{ClientConnectHandler};\r
44         $self->{ClientDisconnectHandler} = $args{ClientDisconnectHandler};\r
45         $self->{Password} = $args{Password};\r
46 \r
47         return $self;\r
48 }\r
49 \r
50 sub update_all_displays {\r
51         my ($self) = @_ ;\r
52 \r
53         my $vncref = $self->{VNC_CONNECTIONS} ;\r
54         my %vncs = %{$vncref} ;\r
55 \r
56         foreach (values %vncs) {\r
57                 $_->update_display ;\r
58         }\r
59 }\r
60 \r
61 sub disconnect_client {\r
62         my ($self, $vnc, $sock_handle) = @_ ;\r
63 \r
64         my $vncref = $self->{VNC_CONNECTIONS} ;\r
65         my %vncs = %{$vncref} ;\r
66 \r
67         my $sel = $self->{SELECTOR};\r
68 \r
69         shutdown($sock_handle,2);\r
70 \r
71         delete $vncs{$sock_handle};\r
72         $sel->remove($sock_handle) ;\r
73         $vnc = undef ;\r
74         $sock_handle = undef ;\r
75 \r
76         print "Client Disconnectd\n";\r
77 }\r
78 \r
79 sub vnc_server_loop {\r
80         my ($self) = @_ ;\r
81 \r
82         my $listen_sock = new IO::Socket::INET(Listen => 1, LocalPort => $self->{PORT} );\r
83         my $sel    = new IO::Select( $listen_sock );\r
84 \r
85         my %vncs = () ;\r
86 \r
87         $self->{VNC_CONNECTIONS} = \%vncs;\r
88         $self->{SELECTOR} = $sel ;\r
89 \r
90         while (1) {\r
91                 my @ready_handles; \r
92                 if (@ready_handles = $sel->can_read( $self->{IDLE_INTERVAL} ) ) {\r
93                         foreach my $fh (@ready_handles) {\r
94                                 if ($fh == $listen_sock) {\r
95                                         #accept new connection from client\r
96 \r
97                                         my $client_sock = $listen_sock->accept;\r
98                                         $client_sock->blocking(1);\r
99                                 \r
100                                         my $vnc = new VNC::ServerConnection( Server => $self,\r
101                                                                                                                  Caption => $self->{Caption},\r
102                                                                                                                  Socket => $client_sock,\r
103                                                                                                                  Width => $self->{Width},\r
104                                                                                                                  Height => $self->{Height},\r
105                                                                                                                  Password => $self->{Password},\r
106                                                                                                                  PixelFormat => $self->{PixelFormat},\r
107                                                                                                                  KeyEventHandler => $self->{KeyEventHandler},\r
108                                                                                                                  PointerEventHandler => $self->{PointerEventHandler},\r
109                                                                                                                  CutTextHandler => $self->{CutTextHandler},\r
110                                                                                                                  UpdateDisplayHandler => $self->{UpdateDisplayHandler}\r
111                                                                                 \r
112                                                                                                            );\r
113                                         print "Accepted new connection from ",$client_sock->sockhost(),"\n" ;\r
114 \r
115                                         my $ok = 1 ;\r
116                                         my $handler = $self->{ClientConnectHandler};\r
117                                         if (defined $handler) {\r
118                                                 $ok = &$handler($self, $client_sock, $vnc);\r
119                                         }\r
120 \r
121                                         if (defined $ok) {\r
122                                                 $sel->add($client_sock);\r
123                                                 $vnc->start_conversation();\r
124                                                 $vncs{$client_sock} = $vnc ;\r
125                                         } else {\r
126                                                 $vnc = undef ;\r
127                                                 shutdown($client_sock,2) ;\r
128                                                 $client_sock = undef; \r
129                                         }\r
130                                 } else {\r
131                                         my $vnc = $vncs{$fh} ;\r
132 \r
133                                         die "Error! got data from un-connected socket" unless (defined $vnc);\r
134 \r
135                                         if (!defined $vnc->handle_client_data()) {\r
136                                                         $vnc->disconnect;\r
137                                         }\r
138                                 }\r
139                         }\r
140                 } else {\r
141                         my $sub = $self->{IdleHandler};\r
142                         if (defined $sub) {\r
143                                 &$sub($self) ;\r
144                         }\r
145                 }\r
146         }\r
147 }\r
148 \r
149 1;