… | |
… | |
24 | @EXPORT = qw(); |
24 | @EXPORT = qw(); |
25 | |
25 | |
26 | #XSLoader::load __PACKAGE__, $VERSION; |
26 | #XSLoader::load __PACKAGE__, $VERSION; |
27 | |
27 | |
28 | my $interface; # Mozilla::Plugin::xxx (design weakness) |
28 | my $interface; # Mozilla::Plugin::xxx (design weakness) |
|
|
29 | |
|
|
30 | my $debug = 1; |
29 | |
31 | |
30 | sub NP_VERSION_MAJOR (){ 0 } |
32 | sub NP_VERSION_MAJOR (){ 0 } |
31 | sub NP_VERSION_MINOR (){ 9 } |
33 | sub NP_VERSION_MINOR (){ 9 } |
32 | sub NP_EMBED (){ 1 } |
34 | sub NP_EMBED (){ 1 } |
33 | sub NP_FULL (){ 2 } |
35 | sub NP_FULL (){ 2 } |
… | |
… | |
140 | my $buf; |
142 | my $buf; |
141 | $_[-1] == sysread FD, $buf, $_[-1] or die "rcv_dyn: $!"; |
143 | $_[-1] == sysread FD, $buf, $_[-1] or die "rcv_dyn: $!"; |
142 | $buf; |
144 | $buf; |
143 | } |
145 | } |
144 | |
146 | |
|
|
147 | # command from browser to plugin usually have capital letters while |
|
|
148 | # commands from perl to the browser always use lowercase letters |
145 | sub _handle_event($) { |
149 | sub _handle_event($) { |
146 | my $cmd = shift; |
150 | my $cmd = shift; |
147 | |
151 | |
|
|
152 | warn "handle_event($cmd)\n" if $debug; |
148 | if ($cmd eq "I") { |
153 | if ($cmd eq 'I') { |
149 | rcv_u32 == 1 or die "protocol version mismatch\n"; |
154 | rcv_u32 == 1 or die "protocol version mismatch\n"; |
150 | ($IFACE, $OSNAME, $OSVERS) = (rcv_blk, rcv_blk, rcv_blk); |
155 | ($IFACE, $OSNAME, $OSVERS) = (rcv_blk, rcv_blk, rcv_blk); |
151 | |
156 | |
152 | } elsif ($cmd eq "+") { # New |
157 | } elsif ($cmd eq '+') { # New |
153 | my ($objid, $type, $mode, $save, $argc) |
158 | my ($objid, $type, $mode, $save, $argc) |
154 | = (rcv_ptr, rcv_blk, rcv_u32, rcv_blk, rcv_u32); |
159 | = (rcv_ptr, rcv_blk, rcv_u32, rcv_blk, rcv_u32); |
155 | my %args; |
160 | my %args; |
156 | while ($argc--) { |
161 | while ($argc--) { |
157 | my ($argn, $argv) = (rcv_blk, rcv_blk); |
162 | my ($argn, $argv) = (rcv_blk, rcv_blk); |
… | |
… | |
164 | mode => $mode, |
169 | mode => $mode, |
165 | save => $save, |
170 | save => $save, |
166 | args => \%args, |
171 | args => \%args, |
167 | ); |
172 | ); |
168 | |
173 | |
169 | } elsif ($cmd eq "-") { # Destroy |
174 | } elsif ($cmd eq '-') { # Destroy |
170 | my $objid = rcv_ptr; |
175 | my $objid = rcv_ptr; |
171 | my $save = (delete $_OBJ{$objid})->save; |
176 | my $save = (delete $_OBJ{$objid})->save; |
172 | snd_cmd "-"; |
177 | snd_cmd "-"; |
173 | snd_u32 length $save; |
178 | snd_u32 length $save; |
174 | snd_snd and snd_dyn $save; |
179 | snd_snd and snd_dyn $save; |
175 | |
180 | |
176 | } elsif ($cmd eq "X") { # SetWindow |
181 | } elsif ($cmd eq 'X') { # SetWindow |
177 | my $objid = rcv_ptr; |
182 | my $objid = rcv_ptr; |
178 | my %args = ( |
183 | my %args = ( |
179 | id => rcv_ptr, |
184 | id => rcv_ptr, |
180 | x => rcv_i32, |
185 | x => rcv_i32, |
181 | y => rcv_i32, |
186 | y => rcv_i32, |
… | |
… | |
190 | |
195 | |
191 | snd_cmd 'X'; |
196 | snd_cmd 'X'; |
192 | snd_u32 $_OBJ{$objid}->set_window(\%args); |
197 | snd_u32 $_OBJ{$objid}->set_window(\%args); |
193 | snd_snd; |
198 | snd_snd; |
194 | |
199 | |
195 | } elsif ($cmd eq "N") { # NewStream |
200 | } elsif ($cmd eq 'N') { # NewStream |
196 | my $obj = $_OBJ{+rcv_ptr}; |
201 | my $obj = $_OBJ{+rcv_ptr}; |
197 | my %args = ( |
202 | my %args = ( |
198 | instance => $obj, |
203 | instance => $obj, |
199 | mimetype => rcv_blk, |
204 | mimetype => rcv_blk, |
200 | id => rcv_ptr, |
205 | id => rcv_ptr, |
… | |
… | |
212 | snd_cmd 'N'; |
217 | snd_cmd 'N'; |
213 | snd_u32 $err; |
218 | snd_u32 $err; |
214 | snd_u32 $stype || NP_NORMAL; |
219 | snd_u32 $stype || NP_NORMAL; |
215 | snd_snd; |
220 | snd_snd; |
216 | |
221 | |
217 | } elsif ($cmd eq "/") { # StreamAsFile |
222 | } elsif ($cmd eq '/') { # StreamAsFile |
218 | my $obj = $_OBJ{+rcv_ptr}; |
223 | my $obj = $_OBJ{+rcv_ptr}; |
219 | my $str = $_OBJ{+rcv_ptr}; |
224 | my $str = $_OBJ{+rcv_ptr}; |
220 | my $path = rcv_blk; |
225 | my $path = rcv_blk; |
221 | |
226 | |
222 | $obj->stream_as_file($obj, $stream, $path); |
227 | $obj->stream_as_file($obj, $stream, $path); |
223 | |
228 | |
224 | } elsif ($cmd eq "R") { # WriteReady |
229 | } elsif ($cmd eq 'R') { # WriteReady |
225 | my $obj = $_OBJ{+rcv_ptr}; |
230 | my $obj = $_OBJ{+rcv_ptr}; |
226 | my $str = $_OBJ{+rcv_ptr}; |
231 | my $str = $_OBJ{+rcv_ptr}; |
227 | |
232 | |
228 | snd_cmd 'R'; |
233 | snd_cmd 'R'; |
229 | snd_u32 $obj->write_ready($obj, $str); |
234 | snd_u32 $obj->write_ready($obj, $str); |
230 | snd_snd; |
235 | snd_snd; |
231 | |
236 | |
232 | } elsif ($cmd eq "W") { # Write |
237 | } elsif ($cmd eq 'W') { # Write |
233 | my $obj = $_OBJ{+rcv_ptr}; |
238 | my $obj = $_OBJ{+rcv_ptr}; |
234 | my $str = $_OBJ{+rcv_ptr}; |
239 | my $str = $_OBJ{+rcv_ptr}; |
235 | my $ofs = rcv_i32; |
240 | my $ofs = rcv_i32; |
236 | my $len = rcv_i32; |
241 | my $len = rcv_i32; |
237 | my $dta = rcv_dyn $len; |
242 | my $dta = rcv_dyn $len; |
238 | |
243 | |
239 | snd_cmd 'W'; |
244 | snd_cmd 'W'; |
240 | snd_i32 $obj->write($str, $ofs, $len, $dta); |
245 | snd_i32 $obj->write($str, $ofs, $len, $dta); |
241 | snd_snd; |
246 | snd_snd; |
242 | |
247 | |
243 | } elsif ($cmd eq "D") { # DestroyStream |
248 | } elsif ($cmd eq 'D') { # DestroyStream |
244 | my $obj = $_OBJ{+rcv_ptr}; |
249 | my $obj = $_OBJ{+rcv_ptr}; |
245 | my $str = delete $_OBJ{+rcv_ptr}; |
250 | my $str = delete $_OBJ{+rcv_ptr}; |
246 | my $why = rcv_u32; |
251 | my $why = rcv_u32; |
247 | |
252 | |
248 | $obj->destroy_stream($obj, $str, $why); |
253 | $obj->destroy_stream($obj, $str, $why); |
… | |
… | |
306 | if ($self->{wininfo}) { |
311 | if ($self->{wininfo}) { |
307 | if ($self->{wininfo}{id} ne $new->{id}) { |
312 | if ($self->{wininfo}{id} ne $new->{id}) { |
308 | $self->window_delete($self->{wininfo}); |
313 | $self->window_delete($self->{wininfo}); |
309 | } elsif ($self->{wininfo}{w} != $new->{w} |
314 | } elsif ($self->{wininfo}{w} != $new->{w} |
310 | or $self->{wininfo}{h} != $new->{h}) { |
315 | or $self->{wininfo}{h} != $new->{h}) { |
311 | $self->window_resize($new->{id}, $new->{w}, $new->{h}); |
316 | $self->window_resize($new->{w}, $new->{h}); |
312 | } |
317 | } |
313 | $self->{wininfo} = $new; |
318 | $self->{wininfo} = $new; |
314 | } |
319 | } |
315 | |
320 | |
316 | unless ($self->{wininfo}) { |
321 | unless ($self->{wininfo}) { |
… | |
… | |
329 | delete $self->{window}; |
334 | delete $self->{window}; |
330 | } |
335 | } |
331 | |
336 | |
332 | sub save { |
337 | sub save { |
333 | my $self = shift; |
338 | my $self = shift; |
334 | $self->set_window(undef); |
|
|
335 | $self->destroy; |
339 | $self->destroy; |
336 | Storable::nfreeze $self->{save}; |
340 | Storable::nfreeze $self->{save}; |
337 | } |
341 | } |
338 | |
342 | |
339 | sub destroy {} |
343 | sub destroy { |
340 | sub DESTROY {} |
344 | my $self = shift; |
|
|
345 | $self->set_window(undef); |
|
|
346 | } |
|
|
347 | |
341 | sub write_ready { 0xfffff } |
348 | sub write_ready { 0xfffff } |
342 | sub push_stream {} |
349 | sub push_stream {} |
343 | sub stream_as_file {} |
350 | sub stream_as_file {} |
344 | sub destroy_stream {} |
351 | sub destroy_stream {} |
|
|
352 | |
|
|
353 | sub DESTROY {} |
345 | |
354 | |
346 | sub write { |
355 | sub write { |
347 | my ($self) = shift; |
356 | my ($self) = shift; |
348 | shift->write(@_); |
357 | shift->write(@_); |
349 | } |
358 | } |
… | |
… | |
381 | |
390 | |
382 | =cut |
391 | =cut |
383 | |
392 | |
384 | sub get_url { |
393 | sub get_url { |
385 | my ($self, $url, $target) = @_; |
394 | my ($self, $url, $target) = @_; |
|
|
395 | my $error; |
|
|
396 | |
|
|
397 | snd_cmd 'u'; |
|
|
398 | snd_blk $url; |
|
|
399 | snd_blk $target; |
|
|
400 | if (snd_snd) { |
|
|
401 | rcv_cmd 'u'; |
|
|
402 | $error = rcv_i32; |
|
|
403 | } |
|
|
404 | $error; |
386 | } |
405 | } |
387 | |
406 | |
388 | sub Mozilla::Stream::new { |
407 | sub Mozilla::Stream::new { |
389 | bless $_[1], $_[0]; |
408 | bless $_[1], $_[0]; |
390 | } |
409 | } |