--- Protocol.pm.orig Fri Aug 22 18:39:18 2003 +++ Protocol.pm Sun Oct 12 11:57:47 2003 @@ -15,7 +15,7 @@ @EXPORT_OK = qw(pad padding padded hexi make_num_hash default_error_handler); -$VERSION = "0.51"; +$VERSION = "0.51_2"; sub padding ($) { my($x) = @_; @@ -571,23 +571,28 @@ return $mask; } +sub make_error_msg { + my($self, $data) = @_; + my($type, $seq, $info, $minor_op, $major_op) + = unpack("xCSLSCxxxxxxxxxxxxxxxxxxxxx", $data); + my($t); + $t = join("", "Protocol error: bad $type (", + $self->do_interp('Error', $type), "); ", + "Sequence Number $seq\n", + " Opcode ($major_op, $minor_op) = ", + ($self->do_interp('Request', $major_op) + or $self->{'ext_request'}{$major_op}[$minor_op][0]), "\n"); + if ($type == 2) { + $t .= " Bad value $info (" . hexi($info) . ")\n"; + } elsif ($self->{'error_type'}[$type] & 1) { + $t .= " Bad resource $info (" . hexi($info) . ")\n"; + } + return $t; +} + sub default_error_handler { - my($self, $data) = @_; - my($type, $seq, $info, $minor_op, $major_op) - = unpack("xCSLSCxxxxxxxxxxxxxxxxxxxxx", $data); - my($t); - $t = join("", "Protocol error: bad $type (", - $self->do_interp('Error', $type), "); ", - "Sequence Number $seq\n", - " Opcode ($major_op, $minor_op) = ", - ($self->do_interp('Request', $major_op) - or $self->{'ext_request'}{$major_op}[$minor_op][0]), "\n"); - if ($type == 2) { - $t .= " Bad value $info (" . hexi($info) . ")\n"; - } elsif ($self->{'error_type'}[$type] & 1) { - $t .= " Bad resource $info (" . hexi($info) . ")\n"; - } - croak($t); + my($self, $data) = @_; + croak($self->make_error_msg($data)); } sub handle_input { @@ -597,8 +602,13 @@ $type_b = $self->get(1); $type = unpack "C", $type_b; if ($type == 0) { - &{$self->{'error_handler'}}($self, $type_b . $self->get(31)); - return 0; + my $data = $type_b . $self->get(31); + my ($type, $seq, $info, $minor_op, $major_op) + = unpack("xCSLSCxxxxxxxxxxxxxxxxxxxxx", $data); + &{$self->{'error_handler'}}($self, $data); + # return 0 to denote an error & the sequence number to identify + # which request it applies to. + return (0, $seq); } elsif ($type > 1) { if ($self->{'event_handler'} eq "queue") { push @{$self->{'event_queue'}}, $type_b . $self->get(31); @@ -2031,6 +2041,7 @@ my($op, $args, $major, $minor) = (@_, 0); my($data); ($data, $minor) = (&{$op->[1]}($self, @$args), $minor); + # print($op->[0] . " req has seq: " . $self->{sequence_num} . "\n"); $minor = 0 unless defined $minor; my($len) = (length($data) / 4) + 1; croak "Request too long!\n" if $len > $self->{'maximum_request_length'}; @@ -2054,8 +2065,13 @@ $self->give($self->assemble_request($op, \@args, $major, $minor)); $seq = $self->next_sequence(); $self->add_reply($seq & 0xffff, \$data); - $self->handle_input() until $data; + while (1) + { + my @ret = $self->handle_input(); + last if ($data || ($ret[0] == 0 && $ret[1] == $seq)); + } $self->delete_reply($seq & 0xffff); + return undef unless $data; return &{$op->[2]}($self, $data); } elsif (@$op == 4) { # Many replies my($seq, $data, @stuff, @ret); @@ -2063,7 +2079,17 @@ $seq = $self->next_sequence(); $self->add_reply($seq & 0xffff, \$data); for (;;) { - $data = 0; $self->handle_input() until $data; + $data = 0; + while (1) + { + my @ret = $self->handle_input(); + last if ($data || ($ret[0] == 0 && $ret[1] == $seq)); + } + if (!$data) + { + $self->delete_reply($seq & 0xffff); + return undef; + } @stuff = &{$op->[2]}($self, $data); last unless @stuff; if ($op->[3] eq "ARRAY") { @@ -2392,8 +2418,13 @@ $self->give($self->assemble_request($op, \@_, $major, $minor)); $seq = $self->next_sequence(); $self->add_reply($seq, \$data); - $self->handle_input() until $data; + while (1) + { + my @ret = $self->handle_input(); + last if ($data || ($ret[0] == 0 && $ret[1] == $seq)); + } $self->delete_reply($seq); + return undef unless $data; return &{$op->[2]}($self, $data); }; } else { # ListFontsWithInfo