ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Mozilla-Plugin/Plugin.pm
(Generate patch)

Comparing Mozilla-Plugin/Plugin.pm (file contents):
Revision 1.1 by root, Thu Feb 22 23:18:48 2001 UTC vs.
Revision 1.9 by root, Sun Mar 4 12:49:19 2001 UTC

6 6
7 use Mozilla::Plugin; 7 use Mozilla::Plugin;
8 8
9=head1 DESCRIPTION 9=head1 DESCRIPTION
10 10
11sorry...
12
11=over 4 13=over 4
12 14
13=cut 15=cut
14 16
15package Mozilla::Plugin; 17package Mozilla::Plugin;
16 18
17use base Exporter; 19use base Exporter;
20use Storable;
18#use XSLoader; 21#use XSLoader;
19 22
20$VERSION = 0.12; 23$VERSION = 0.01;
21@EXPORT = qw(); 24@EXPORT = qw();
22 25
23warn "in module [@ARGV]";#d#
24
25#XSLoader::load __PACKAGE__, $VERSION; 26#XSLoader::load __PACKAGE__, $VERSION;
26use Data::Dumper; 27
28my $interface; # Mozilla::Plugin::xxx (design weakness)
29
30sub NP_VERSION_MAJOR (){ 0 }
31sub NP_VERSION_MINOR (){ 9 }
32sub NP_EMBED (){ 1 }
33sub NP_FULL (){ 2 }
34sub NP_NORMAL (){ 1 }
35sub NP_SEEK (){ 2 }
36sub NP_ASFILE (){ 3 }
37sub NP_ASFILEONLY (){ 4 }
38sub NP_MAXREADY (){ 2147483647 }
39sub NPERR_NO_ERROR (){ 0 }
40sub NPERR_GENERIC_ERROR (){ 1 }
41sub NPERR_INVALID_INSTANCE_ERROR (){ 2 }
42sub NPERR_INVALID_FUNCTABLE_ERROR (){ 3 }
43sub NPERR_MODULE_LOAD_FAILED_ERROR (){ 4 }
44sub NPERR_OUT_OF_MEMORY_ERROR (){ 5 }
45sub NPERR_INVALID_PLUGIN_ERROR (){ 6 }
46sub NPERR_INVALID_PLUGIN_DIR_ERROR (){ 7 }
47sub NPERR_INCOMPATIBLE_VERSION_ERROR (){ 8 }
48sub NPERR_INVALID_PARAM (){ 9 }
49sub NPERR_INVALID_URL (){ 10 }
50sub NPERR_FILE_NOT_FOUND (){ 11 }
51sub NPERR_NO_DATA (){ 12 }
52sub NPERR_STREAM_NOT_SEEKABLE (){ 13 }
53sub NPVERS_HAS_STREAMOUTPUT (){ 8 }
54sub NPVERS_HAS_NOTIFICATION (){ 9 }
55sub NPVERS_HAS_LIVECONNECT (){ 9 }
56sub NPVERS_WIN16_HAS_LIVECONNECT (){ 10 }
27 57
28my $data; 58my $data;
29 59
60sub BIAS() { -2147483647 } # ugliest hack ever seen
61
30sub snd_cmd($) { 62sub snd_cmd {
31 $data = pack "NN", 0, ord($_[0]); 63 $data = pack "NN", 0, ord($_[-1]);
32} 64}
33 65
66sub snd_ptr {
67 $data .= $_[-1];
68}
69
34sub snd_i32($) { 70sub snd_u32 {
35 $data .= pack "N", $_[0]; 71 $data .= pack "N", $_[-1];
36} 72}
37 73
74sub snd_i32 {
75 $data .= pack "N", $_[-1] - BIAS;
76}
77
38sub snd_blk($) { 78sub snd_blk {
39 $data .= pack "NA*", length($_[0]), $_[0]; 79 $data .= pack "NA*", length($_[-1]), $_[-1];
40} 80}
41 81
42sub snd_snd($) { 82sub snd_snd {
43 substr ($data, 0, 4) = pack "N", length $data; 83 substr ($data, 0, 4) = pack "N", length $data;
44 length($data) == syswrite $_[0], $data; 84 length ($data) == syswrite FD, $data;
85}
86
87sub snd_dyn {
88 length ($_[-1]) == syswrite FD, $_[-1];
45} 89}
46 90
47sub rcv_cmd { 91sub rcv_cmd {
48 my $buf; 92 my $buf;
49 4 == sysread $_[0], $buf, 4 or exit; 93 4 == sysread FD, $buf, 4 or exit;
50 my $len = unpack "N", $buf; 94 my $len = unpack "N", $buf;
51 $len -= 4; 95 $len -= 4;
52 $len == sysread $_[0], $buf, $len or die; 96 $len == sysread FD, $buf, $len or die;
53 97
54 $data = substr $buf, 4; 98 $data = substr $buf, 4;
55 99
56 substr $buf, 3, 1; 100 substr $buf, 3, 1;
57} 101}
58 102
103sub rcv_ptr {
104 my $ptr = substr $data, 0, 8;
105 $data = substr $data, 8;
106 printf "RCV_PTR(%s)\n", unpack "H*", $ptr;
107 $ptr;
108}
109
59sub rcv_i32() { 110sub rcv_u32 {
60 my $i32 = unpack "N", $data; 111 my $u32 = unpack "N", $data;
112 $data = substr $data, 4;
113 $u32;
114}
115
116sub rcv_i32 {
117 my $i32 = BIAS + unpack "N", $data;
61 $data = substr $data, 4; 118 $data = substr $data, 4;
62 $i32; 119 $i32;
63} 120}
64 121
65sub rcv_blk() { 122sub rcv_blk {
66 my $len = unpack "N", $data; 123 my $len = unpack "N", $data;
67 my $str = substr $data, 4, $len; 124 my $str = substr $data, 4, $len;
68 $data = substr $data, 4 + $len; 125 $data = substr $data, 4 + $len;
69 $str; 126 $str;
70} 127}
71 128
72sub handle_cmd { 129sub rcv_dyn {
130 my $buf;
131 $_[-1] == sysread FD, $buf, $_[-1] or die "rcv_dyn: $!";
132 $buf;
133}
134
135=item my $fh = server_fh
136
137The design of this module is event-based. When the plug-in starts (there
138is always just one interpreter) it spawns one perl interpreter which
139will immediately go into a even loop. If you want to use your own event
140loop (e.g. using the Gtk or Event modules) you need to register a file
141input handler on the filehandle returned by C<server_fh> that calls
142C<server_event> whenever there is input pending on C<server_fh>. This will
143ensure proper operation of the plug-in.
144
145=item server_event
146
147Call this function whenever there is data available on the C<server_fh>. This function
148might not return.
149
150Due to this design (flaw?), sharing of different toolkits using this
151plug-in is difficult at best. Spawning a new perl interpreter for every
152plug-in is also not very viable, so in the future one might be able to
153specify a group on the embed statement (i.e. EMBED GROUP="gtk+").
154
155=cut
156
157sub server_fh() { \*FD }
158
159sub server_event() {
73 my $cmd = rcv_cmd *FD1; 160 my $cmd = rcv_cmd;
161
162 warn "cmd<$cmd>\n";#d#
74 163
75 if ($cmd eq "I") { 164 if ($cmd eq "I") {
76 rcv_i32 == 1 or die "protocol version mismatch\n"; 165 rcv_u32 == 1 or die "protocol version mismatch\n";
77 ($IFACE, $OSNAME, $OSVERS) = (rcv_blk, rcv_blk, rcv_blk); 166 ($IFACE, $OSNAME, $OSVERS) = (rcv_blk, rcv_blk, rcv_blk);
78 warn " ($IFACE, $OSNAME, $OSVERS) \n";#d# 167
79 } elsif ($cmd eq "+") { 168 } elsif ($cmd eq "+") { # New
80 my ($objid, $type, $mode, $save, $argc) 169 my ($objid, $type, $mode, $save, $argc)
81 = (rcv_i32, rcv_blk, rcv_i32, rcv_blk, rcv_i32); 170 = (rcv_ptr, rcv_blk, rcv_u32, rcv_blk, rcv_u32);
82 my %args; 171 my %args;
83 $args{rcv_blk} = rcv_blk while $argc--; 172 while ($argc--) {
173 my ($argn, $argv) = (rcv_blk, rcv_blk);
174 $args{$argn} = $argv;
175 }
84 176
85 $_OBJ{$objid} = new Mozilla::Plugin 177 $_OBJ{$objid} = $interface->new(
178 instance => $objid,
86 type => $type, 179 type => $type,
87 mode => $mode, 180 mode => $mode,
88 save => $save, 181 save => $save,
89 args => \%args; 182 args => \%args,
183 );
90 184
91 } elsif ($cmd eq "-") { 185 } elsif ($cmd eq "-") { # Destroy
92 my $objid = rcv_i32; 186 my $objid = rcv_ptr;
93 my $save = 187 my $save = (delete $_OBJ{$objid})->save;
94 $_OBJ{$objid}->save 188 snd_cmd "-";
189 snd_u32 length $save;
190 snd_snd and snd_dyn $save;
191
192 } elsif ($cmd eq "X") { # SetWindow
193 my $objid = rcv_ptr;
194 my %args = (
195 id => rcv_ptr,
196 x => rcv_i32,
197 y => rcv_i32,
198 w => rcv_i32,
199 h => rcv_i32,
200 );
201 if ($IFACE eq "UNIX") {
202 $args{id} = unpack "xxxxN", $args{id};
203 $args{ws_type} = rcv_i32;
204 $args{ws_depth} = rcv_u32;
205 }
206
207 snd_cmd 'X';
208 snd_u32 $_OBJ{$objid}->set_window(\%args);
209 snd_snd;
210
211 } elsif ($cmd eq "N") { # NewStream
212 my $obj = $_OBJ{+rcv_ptr};
213 my %args = (
214 instance => $obj,
215 mimetype => rcv_blk,
216 id => rcv_ptr,
217 url => rcv_blk,
218 end => rcv_u32,
219 lastmodified => rcv_u32,
220 notifydata => rcv_u32,
221 seekable => rcv_u32,
222 push_stream => 1,
223 );
224 my $str = $_OBJ{$args{id}} = new Mozilla::Stream \%args;
225
226 my ($stype, $err) = $obj->push_stream($str);
227
228 snd_cmd 'N';
229 snd_u32 $err;
230 snd_u32 $stype || NP_NORMAL;
231 snd_snd;
232
233 } elsif ($cmd eq "/") { # StreamAsFile
234 my $obj = $_OBJ{+rcv_ptr};
235 my $str = $_OBJ{+rcv_ptr};
236 my $path = rcv_blk;
237
238 $obj->stream_as_file($obj, $stream, $path);
239
240 } elsif ($cmd eq "R") { # WriteReady
241 my $obj = $_OBJ{+rcv_ptr};
242 my $str = $_OBJ{+rcv_ptr};
243
244 snd_cmd 'R';
245 snd_u32 $obj->write_ready($obj, $str);
246 snd_snd;
247
248 } elsif ($cmd eq "W") { # Write
249 my $obj = $_OBJ{+rcv_ptr};
250 my $str = $_OBJ{+rcv_ptr};
251 my $ofs = rcv_i32;
252 my $len = rcv_i32;
253 my $dta = rcv_dyn $len;
254
255 snd_cmd 'W';
256 snd_i32 $obj->write($str, $ofs, $len, $dta);
257 snd_snd;
258
259 } elsif ($cmd eq "D") { # DestroyStream
260 my $obj = $_OBJ{+rcv_ptr};
261 my $str = delete $_OBJ{+rcv_ptr};
262 my $why = rcv_u32;
263
264 $obj->destroy_stream($obj, $str, $why);
265
95 } else { 266 } else {
96 die "unknown command '$cmd' received"; 267 die "unknown command '$cmd' received";
97 } 268 }
98} 269}
99 270
100sub mainloop { 271sub mainloop {
101 handle_cmd while 1; 272 server_event while 1;
102} 273}
103 274
104sub _main { 275sub init {
105 $LIBDIR = shift @ARGV; 276 $interface = shift;
106 $IN_MOZILLA = 1; 277
107 (shift @ARGV) =~ /^(\d+),(\d+)$/ or die "init arg error";
108 my ($fd1, $fd2) = ($1, $2);
109 open FD1, "+<&=$fd1"; binmode FD1; 278 open FD, "+<&=$_[0]"; binmode FD;
110 open FD2, "+<&=$fd2"; binmode FD2;
111 279
112 mainloop; 280 $interface->mainloop;
113
114 close FD2;
115 close FD1;
116} 281}
117 282
118sub new { 283sub new {
119 warn "new: ".Dumper(\@_); 284 my $class = shift;
285 my $self = bless { @_ }, $class;
286 $self->{save} = $self->{save} ne ""
287 ? Storable::thaw $self->{save}
288 : {};
289 $self;
120} 290}
121 291
122sub set_window { 292sub set_window {
123 warn "set_window: ".Dumper(\@_); 293 my $self = shift;
294 my $new = shift;
295
296 if ($self->{wininfo}) {
297 if ($self->{wininfo}{id} ne $new->{id}) {
298 $self->window_delete($self->{wininfo});
299 } elsif ($self->{wininfo}{w} != $new->{w}
300 or $self->{wininfo}{h} != $new->{h}) {
301 $self->window_resize($new->{id}, $new->{w}, $new->{h});
302 }
303 $self->{wininfo} = $new;
304 }
305
306 unless ($self->{wininfo}) {
307 $self->{window} = $self->window_new($new) and $self->{wininfo} = $new;
308 }
309
310 ();
311}
312
313sub window_new {}
314sub window_resize {}
315
316sub window_delete {
317 my $self = shift;
318 delete $self->{wininfo};
319 delete $self->{window};
124} 320}
125 321
126sub save { 322sub save {
127 warn "save: ".Dumper(\@_); 323 my $self = shift;
128 "[save]"; 324 $self->set_window(undef);
325 $self->{destroy};
326 Storable::nfreeze $self->{save};
327}
328
329sub destroy {}
330sub DESTROY {}
331sub write_ready { 0xfffff }
332sub push_stream {}
333sub stream_as_file {}
334sub destroy_stream {}
335
336sub write {
337 my ($self) = shift;
338 shift->write(@_);
339}
340
341package Mozilla::Stream;
342
343sub new {
344 bless $_[1], $_[0];
345}
346
347sub write {
348 # ...
129} 349}
130 350
131sub DESTROY { 351sub DESTROY {
352 my $str = $_[0];
132 warn "DESTROY"; 353 warn "DESTROY stream";
354
355 my $obj = $str->{instance};
356 $obj->snd_cmd('d');
357 $obj->snd_ptr($obj);
358 $obj->snd_ptr($str);
359 $obj->snd_snd;
133} 360}
134 361
1351; 3621;
136 363
137=back 364=back

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines