ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Mozilla-Plugin/Plugin.pm
Revision: 1.4
Committed: Fri Feb 23 20:01:27 2001 UTC (23 years, 2 months ago) by root
Branch: MAIN
Changes since 1.3: +0 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Mozilla::Plugin - embed perl into mozilla/netscape.
4
5 =head1 SYNOPSIS
6
7 use Mozilla::Plugin;
8
9 =head1 DESCRIPTION
10
11 sorry...
12
13 =over 4
14
15 =cut
16
17 package Mozilla::Plugin;
18
19 use base Exporter;
20 use Storable;
21 #use XSLoader;
22
23 $VERSION = 0.01;
24 @EXPORT = qw();
25
26 #XSLoader::load __PACKAGE__, $VERSION;
27 use Data::Dumper;#d#
28
29 my $data;
30
31 sub BIAS() { -2000000000 } # ugliest hack ever seen
32
33 sub snd_cmd($) {
34 $data = pack "NN", 0, ord($_[0]);
35 }
36
37 sub snd_ptr($) {
38 $data .= $_[0];
39 }
40
41 sub snd_u32($) {
42 $data .= pack "N", $_[0];
43 }
44
45 sub snd_i32($) {
46 $data .= pack "N", $_[0] - BIAS;
47 }
48
49 sub snd_blk($) {
50 $data .= pack "NA*", length($_[0]), $_[0];
51 }
52
53 sub snd_snd() {
54 substr ($data, 0, 4) = pack "N", length $data;
55 length ($data) == syswrite FD, $data;
56 }
57
58 sub snd_dyn($) {
59 length ($_[0]) == syswrite FD, $_[0];
60 }
61
62 sub rcv_cmd() {
63 my $buf;
64 4 == sysread FD, $buf, 4 or exit;
65 my $len = unpack "N", $buf;
66 $len -= 4;
67 $len == sysread FD, $buf, $len or die;
68
69 $data = substr $buf, 4;
70
71 substr $buf, 3, 1;
72 }
73
74 sub rcv_ptr() {
75 my $ptr = substr $data, 0, 8;
76 $data = substr $data, 8;
77 $ptr;
78 }
79
80 sub rcv_u32() {
81 my $u32 = unpack "N", $data;
82 $data = substr $data, 4;
83 $u32;
84 }
85
86 sub rcv_i32() {
87 my $i32 = BIAS + unpack "N", $data;
88 $data = substr $data, 4;
89 $i32;
90 }
91
92 sub rcv_blk() {
93 my $len = unpack "N", $data;
94 my $str = substr $data, 4, $len;
95 $data = substr $data, 4 + $len;
96 $str;
97 }
98
99 =item my $fh = server_fh
100
101 The design of this module is event-based. When the plug-in starts (there
102 is always just one interpreter) it spawns one perl interpreter which
103 will immediately go into a even loop. If you want to use your own event
104 loop (e.g. using the Gtk or Event modules) you need to register a file
105 input handler on the filehandle returned by C<server_fh> that calls
106 C<server_event> whenever there is input pending on C<server_fh>. This will
107 ensure proper operation of the plug-in.
108
109 =item server_event
110
111 Call this function whenever there is data available on the C<server_fh>. This function
112 might not return.
113
114 Due to this design (flaw?), sharing of different toolkits using this
115 plug-in is difficult at best. Spawning a new perl interpreter for every
116 plug-in is also not very viable, so in the future one might be able to
117 specify a group on the embed statement (i.e. EMBED GROUP="gtk+").
118
119 =cut
120
121 sub server_fh() { *FD }
122
123 sub server_event() {
124 my $cmd = rcv_cmd;
125
126 warn "cmd<$cmd>\n";#d#
127
128 if ($cmd eq "I") {
129 rcv_u32 == 1 or die "protocol version mismatch\n";
130 ($IFACE, $OSNAME, $OSVERS) = (rcv_blk, rcv_blk, rcv_blk);
131
132 } elsif ($cmd eq "+") {
133 my ($objid, $type, $mode, $save, $argc)
134 = (rcv_ptr, rcv_blk, rcv_u32, rcv_blk, rcv_u32);
135 my %args;
136 while ($argc--) {
137 my ($argn, $argv) = (rcv_blk, rcv_blk);
138 $args{$argn} = $argv;
139 }
140
141 warn "new obj $objid\n";#d#
142 $_OBJ{$objid} = new Mozilla::Plugin
143 objid => $objid,
144 type => $type,
145 mode => $mode,
146 save => $save,
147 args => \%args;
148
149 } elsif ($cmd eq "-") {
150 my $objid = rcv_ptr;
151 my $save = (delete $_OBJ{$objid})->save;
152 snd_cmd "-";
153 snd_u32 length $save;
154 snd_snd and snd_dyn $save;
155
156 } elsif ($cmd eq "W") {
157 my $objid = rcv_ptr;
158 my %args = (
159 window => rcv_ptr,
160 x => rcv_i32,
161 y => rcv_i32,
162 w => rcv_i32,
163 h => rcv_i32,
164 );
165 if ($IFACE eq "UNIX") {
166 $args{window} = unpack "xxxxN", $args{window};
167 $args{ws_type} = rcv_i32;
168 $args{ws_depth} = rcv_u32;
169 }
170
171 $_OBJ{$objid}->set_window(\%args);
172
173 } else {
174 die "unknown command '$cmd' received";
175 }
176 }
177
178 sub mainloop {
179 server_event while 1;
180 }
181
182 sub init {
183 $IN_MOZILLA = 1;
184
185 open FD, "+<&=$_[1]"; binmode $FD;
186
187 warn "init: ".Dumper(@_);
188 mainloop;
189 }
190
191 sub new {
192 my $class = shift;
193 my $self = bless { @_ }, $class;
194 $self->{save} = $self->{save} ne ""
195 ? Storable::thaw $self->{save}
196 : {};
197 warn "new: ".Dumper($self);
198 $self;
199 }
200
201 sub set_window {
202 my $self = shift;
203 my $new = shift;
204 if ($self->{window}) {
205 if ($self->{window}{window} ne $new->{window}) {
206 $self->window_delete($self->{window});
207 } else {
208 $self->window_resize($new->{window}, $new->{w}, $new->{h});
209 }
210 $self->{window} = $new;
211 } else {
212 $self->{window} = $new;
213 $self->window_new($new->{window}, $new->{w}, $new->{h});
214 }
215 warn "set_window: ".Dumper($self);
216 }
217
218 sub window_new {}
219 sub window_resize {}
220 sub window_delete {}
221
222 sub save {
223 $_[0]->{save}{test} = ['t1',5,7];
224 Storable::nfreeze $_[0]->{save};
225 }
226
227 sub DESTROY {
228 warn "DESTROY";
229 }
230
231 1;
232
233 =back
234
235 =head1 BUGS
236
237 =head1 SEE ALSO
238
239 L<PApp>.
240
241 =head1 AUTHOR
242
243 Marc Lehmann <pcg@goof.com>
244 http://www.goof.com/pcg/marc/
245
246 =cut
247