ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/kgsueme/kgsueme/appwin.pl
Revision: 1.6
Committed: Thu Jun 5 10:09:11 2003 UTC (20 years, 11 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.5: +5 -3 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 package appwin;
2    
3 pcg 1.3 use Scalar::Util;
4    
5 pcg 1.1 use base KGS::Listener;
6 pcg 1.3 use base gtk::widget;
7 pcg 1.1
8     my %context_id;
9    
10 pcg 1.4 # static method to request the userimage and call the cb when it's available.
11     sub userpic {
12     my ($name, $cb) = @_;
13     $self->get_userpic ($name, $cb);
14     }
15    
16 pcg 1.1 sub status {
17     my ($type, $text) = @_;
18    
19     $self->{status}->pop($context_id{$type}) if $context_id{$type};
20     $self->{status}->push($context_id{$type} ||= $self->{status}->get_context_id($type), $text) if $text;
21     }
22    
23     sub new {
24     my $self = shift;
25     $self = $self->SUPER::new(@_);
26    
27     $appwin::self = $self; # singleton
28 pcg 1.3 Scalar::Util::weaken $appwin::self;
29 pcg 1.1
30     $self->{conn} = new KGS::Protocol;
31    
32     KGS::Listener::Debug->new->listen($self->{conn}, "any"); #d# debug only :)
33    
34 pcg 1.4 $self->listen($self->{conn}, qw(login userpic));
35 pcg 1.1
36     $self->{roomlist} = new roomlist conn => $self->{conn};
37    
38     $self->{window} = new Gtk2::Window 'toplevel';
39     $self->{window}->set_title('kgsueme');
40 pcg 1.3 gtk::state $self->{window}, "main::window", undef, window_size => [400, 400];
41 pcg 1.1 $self->{window}->signal_connect(delete_event => sub { main_quit Gtk2; 1 });
42    
43     $self->{window}->add(my $vbox = new Gtk2::VBox);
44    
45     $vbox->pack_start(($buttonbox = new Gtk2::HButtonBox), 0, 1, 0);
46     $buttonbox->set_spacing(0);
47    
48     my $button = sub {
49     $buttonbox->add(my $button = new Gtk2::Button $_[0]);
50     signal_connect $button clicked => $_[1];
51     };
52    
53     $button->("Login", sub { $self->login; });
54     $button->("Roomlist", sub { $self->{roomlist}->show; });
55 pcg 1.2 $button->("Save Config & Layout", \&util::save_config);
56 pcg 1.1 $button->("Quit", sub { main_quit Gtk2 });
57    
58     $vbox->pack_start((my $hbox = new Gtk2::HBox), 0, 1, 0);
59    
60     $hbox->add(new Gtk2::Label "Login");
61    
62     $hbox->add($self->{login} = new_with_max_length Gtk2::Entry 12);
63     $self->{login}->set_text($::config->{login});
64    
65     if ($::HACK) {
66     $self->{login}->signal_connect(activate => sub {
67     $self->{conn}{name} = $self->{login}->get_text;
68     });
69     }
70    
71     $hbox->add(new Gtk2::Label "Password");
72     $hbox->add($self->{password} = new Gtk2::Entry);
73     $self->{password}->set_visibility(0);
74    
75 pcg 1.3 $self->{gamelist} = new gamelist conn => $self->{conn};
76     $vbox->pack_start ($self->{gamelist}->widget, 1, 1, 0);
77    
78     $appwin::gamelist = $self->{gamelist};
79     Scalar::Util::weaken $appwin::gamelist;
80    
81 pcg 1.1 $vbox->pack_start(($self->{status} = new Gtk2::Statusbar), 0, 1, 0);
82    
83     $self->{window}->show_all;
84    
85     $self;
86     }
87    
88     sub login {
89     my ($self) = @_;
90    
91     $self->{conn}->disconnect;
92    
93     # initialize new socket and connection
94     my $sock = new IO::Socket::INET PeerHost => "kgs.kiseido.com", PeerPort => "2379"
95     or die;
96    
97     $sock->blocking(1);
98     $self->{conn}->handshake($sock);
99     $sock->blocking(0);
100    
101     my $input; $input = add_watch Glib::IO fileno $sock, [G_IO_IN, G_IO_ERR, G_IO_HUP], sub {
102     # this is dorked
103     my $buf;
104 pcg 1.6 my $len = sysread $sock, $buf, 16384;
105     if ($len) {
106     $self->{conn}->feed_data($buf);
107     } elsif (defined $len || (!$!{EINTR} and !$!{EAGAIN})) {
108     warn "disconnected";#d#
109 pcg 1.1 remove Glib::Source $input;
110     $self->event_disconnect;
111     }
112     1;
113     }, G_PRIORITY_HIGH;
114    
115     # now login
116 pcg 1.5 $self->{conn}->login($ENV{KGSUEME_CLIENTVER} || "kgsueme $VERSION $^O", # allow users to overwrite
117     $self->{login}->get_text,
118     $self->{password}->get_text);
119 pcg 1.1 }
120    
121     sub inject_login {
122     my ($self, $msg) = @_;
123    
124     appwin::status("login", "logged in as '$self->{conn}{name}' with status '$msg->{result}'");
125     $::config->{login} = $self->{conn}{name};
126    
127     if ($msg->{success}) {
128 pcg 1.3 # auto-join
129     for (values %{$::config->{rooms}}) {
130 pcg 1.1 $self->{roomlist}->join_room($_);
131     }
132     sound::play 3, "connect";
133     } elsif ($msg->{result} eq "user unknown") {
134     sound::play 2, "user_unknown";
135     } else {
136     sound::play 2, "warning";
137     }
138 pcg 1.4 }
139    
140     my %userpic;
141     my %userpic_cb;
142    
143     sub get_userpic {
144     my ($self, $name, $cb) = @_;
145    
146     if (exists $userpic{$name}) {
147     $cb->($userpic{$name});
148     } else {
149     if (!exists $userpic_cb{$name}) {
150     # after 10 seconds, flush callbacks
151     $self->msg (pic_req => name => $name);
152     add Glib::Timeout 10000, sub {
153     $_->() for @{delete $userpic_cb{$name} || []};
154     0;
155     };
156     }
157     push @{$userpic_cb{$name}}, $cb;
158     }
159     }
160    
161     sub inject_userpic {
162     my ($self, $msg) = @_;
163    
164     $userpic{$msg->{name}} = $msg->{data};
165     $_->($userpic{$msg->{name}}) for @{delete $userpic_cb{$msg->{name}} || []};
166 pcg 1.1 }
167    
168     sub event_disconnect { }
169    
170     1;
171