Parent Directory | Revision Log
Don't pass window info struct as address from local variable
1 | /* |
2 | * Copyright (C) 2007 Koos Vriezen <koos.vriezen@gmail.com> |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Lesser General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
17 | */ |
18 | |
19 | /* |
20 | http://devedge-temp.mozilla.org/library/manuals/2002/plugin/1.0/ |
21 | */ |
22 | |
23 | #include <unistd.h> |
24 | #include <string.h> |
25 | #include <strings.h> |
26 | #include <stdio.h> |
27 | #include <stdarg.h> |
28 | #include <sys/types.h> |
29 | #include <sys/time.h> |
30 | #include <fcntl.h> |
31 | |
32 | #include <glib/gprintf.h> |
33 | #include <gdk/gdkx.h> |
34 | #include <gtk/gtk.h> |
35 | |
36 | #define XP_UNIX |
37 | #define MOZ_X11 |
38 | #include "moz-sdk/npupp.h" |
39 | |
40 | #include "npplayer.h" |
41 | |
42 | static int top_w, top_h; |
43 | static Window socket_id; |
44 | static int update_dimension_timer; |
45 | static gchar *start_url; |
46 | |
47 | static void *browser_data; |
48 | static NSNotify *browser_notify; |
49 | static NPNetscapeFuncs ns_funcs; |
50 | static NPPluginFuncs np_funcs; /* plugin functions */ |
51 | static NPP npp; /* single instance of the plugin */ |
52 | static NPWindow np_window; |
53 | static NPSetWindowCallbackStruct ws_info; |
54 | static NPObject *js_window; |
55 | static NPObject *scriptable_peer; |
56 | static NPSavedData *saved_data; |
57 | static NPClass js_class; |
58 | static NPClass window_class; |
59 | static NPClass location_class; |
60 | static GTree *stream_list; |
61 | static int stream_id_counter; |
62 | static GTree *identifiers; |
63 | typedef struct _StreamInfo { |
64 | NPStream np_stream; |
65 | /*unsigned int stream_buf_pos;*/ |
66 | unsigned int stream_pos; |
67 | unsigned int total; |
68 | unsigned int reason; |
69 | unsigned int post_len; |
70 | char *url; |
71 | char *mimetype; |
72 | char *target; |
73 | char *post; |
74 | bool notify; |
75 | bool called_plugin; |
76 | bool destroyed; |
77 | } StreamInfo; |
78 | typedef struct _JsObject { |
79 | NPObject npobject; |
80 | char * name; |
81 | } JsObject; |
82 | |
83 | /*----------------%<---------------------------------------------------------*/ |
84 | |
85 | static void print (const char * format, ...) { |
86 | va_list vl; |
87 | va_start (vl, format); |
88 | vfprintf (stderr, format, vl); |
89 | va_end (vl); |
90 | fflush (stderr); |
91 | } |
92 | |
93 | static void *nsAlloc (uint32 size) { |
94 | return g_malloc (size); |
95 | } |
96 | |
97 | static void nsMemFree (void* ptr) { |
98 | g_free (ptr); |
99 | } |
100 | |
101 | /*----------------%<---------------------------------------------------------*/ |
102 | |
103 | static gint streamCompare (gconstpointer a, gconstpointer b) { |
104 | return (long)a - (long)b; |
105 | } |
106 | |
107 | static void freeStream (StreamInfo *si) { |
108 | if (!g_tree_remove (stream_list, si->np_stream.ndata)) |
109 | print ("WARNING freeStream not in tree\n"); |
110 | g_free (si->url); |
111 | if (si->mimetype) |
112 | g_free (si->mimetype); |
113 | if (si->target) |
114 | g_free (si->target); |
115 | if (si->post) |
116 | g_free (si->post); |
117 | nsMemFree (si); |
118 | } |
119 | |
120 | static gboolean requestStream (void * p) { |
121 | StreamInfo *si = (StreamInfo *) g_tree_lookup (stream_list, p); |
122 | if (si) { |
123 | browser_notify->getUrl (npp, (int)(long)p, si->url, si->target, |
124 | si->post_len, si->post, browser_data); |
125 | } else { |
126 | print ("requestStream %d not found", (long) p); |
127 | } |
128 | return 0; /* single shot */ |
129 | } |
130 | |
131 | static gboolean destroyStream (void * p) { |
132 | StreamInfo *si = (StreamInfo *) g_tree_lookup (stream_list, p); |
133 | print ("FIXME destroyStream %d\n", (int)p); |
134 | if (si) |
135 | browser_notify->finishStream (npp, (int)(long)p, browser_data); |
136 | return 0; /* single shot */ |
137 | } |
138 | |
139 | static void removeStream (uint32_t stream) { |
140 | StreamInfo *si = (StreamInfo*)g_tree_lookup (stream_list, (gpointer)stream); |
141 | |
142 | if (si) { |
143 | print ("removeStream %d rec:%d reason:%d\n", stream, si->stream_pos, si->reason); |
144 | if (!si->destroyed) { |
145 | if (si->called_plugin && !si->target) |
146 | np_funcs.destroystream (npp, &si->np_stream, si->reason); |
147 | if (si->notify) |
148 | np_funcs.urlnotify (npp, |
149 | si->url, si->reason, si->np_stream.notifyData); |
150 | } |
151 | freeStream (si); |
152 | } |
153 | } |
154 | |
155 | static int32_t writeStream (uint32_t stream, const char *buf, uint32_t count) { |
156 | int32_t sz = -1; |
157 | StreamInfo *si = (StreamInfo*)g_tree_lookup (stream_list, (gpointer)stream); |
158 | /*print ("writeStream found %d count %d\n", !!si, count);*/ |
159 | if (si) { |
160 | if (si->reason > NPERR_NO_ERROR) { |
161 | sz = count; /* stream closed, skip remainings */ |
162 | } else { |
163 | if (!si->called_plugin) { |
164 | NPError err; |
165 | uint16 stype = NP_NORMAL; |
166 | err = np_funcs.newstream (npp, |
167 | si->mimetype ? si->mimetype : (char *)"text/plain", |
168 | &si->np_stream, 0, &stype); |
169 | if (err != NPERR_NO_ERROR) { |
170 | g_printerr ("newstream error %d\n", err); |
171 | destroyStream ((void *)stream); |
172 | return count; |
173 | } |
174 | print ("newStream %d type:%d %s mime:%s\n", (long) stream, stype, si->url, si->mimetype ? si->mimetype : "text/plain"); |
175 | si->called_plugin = true; |
176 | } |
177 | if (count) /* urls with a target returns zero bytes */ |
178 | sz = np_funcs.writeready (npp, &si->np_stream); |
179 | if (sz > 0) { |
180 | sz = np_funcs.write (npp, &si->np_stream, si->stream_pos, |
181 | (int32_t) count > sz ? sz : (int32_t) count, (char *)buf); |
182 | if (sz < 0) { /*FIXME plugin destroys stream here*/ |
183 | destroyStream ((gpointer)stream); |
184 | return 0; |
185 | } |
186 | } else { |
187 | sz = 0; |
188 | } |
189 | si->stream_pos += sz; |
190 | } |
191 | } |
192 | return sz; |
193 | } |
194 | |
195 | static StreamInfo *addStream (const char *url, const char *mime, |
196 | const char *target, int len, const char *post, void *notify_data, |
197 | bool notify) { |
198 | StreamInfo *si = (StreamInfo *) nsAlloc (sizeof (StreamInfo)); |
199 | |
200 | memset (si, 0, sizeof (StreamInfo)); |
201 | si->url = g_strdup (url); |
202 | si->np_stream.url = si->url; |
203 | if (mime) |
204 | si->mimetype = g_strdup (mime); |
205 | if (target) |
206 | si->target = g_strdup (target); |
207 | if (len && post) { |
208 | si->post_len = len; |
209 | si->post = (char *) nsAlloc (len); |
210 | memcpy (si->post, post, len); |
211 | } |
212 | si->np_stream.notifyData = notify_data; |
213 | si->notify = notify; |
214 | si->np_stream.ndata = (void *) (long) (stream_id_counter++); |
215 | print ("add stream %d\n", (long) si->np_stream.ndata); |
216 | g_tree_insert (stream_list, si->np_stream.ndata, si); |
217 | |
218 | g_timeout_add (0, requestStream, si->np_stream.ndata); |
219 | |
220 | return si; |
221 | } |
222 | |
223 | /*----------------%<---------------------------------------------------------*/ |
224 | |
225 | static NPObject * nsCreateObject (NPP instance, NPClass *aClass) { |
226 | NPObject *obj; |
227 | if (aClass && aClass->allocate) |
228 | obj = aClass->allocate (instance, aClass); |
229 | else |
230 | obj = js_class.allocate (instance, &js_class);/*add null class*/ |
231 | /*print ("NPN_CreateObject\n");*/ |
232 | obj->referenceCount = 1; |
233 | return obj; |
234 | } |
235 | |
236 | static NPObject *nsRetainObject (NPObject *npobj) { |
237 | /*print( "nsRetainObject %p\n", npobj);*/ |
238 | npobj->referenceCount++; |
239 | return npobj; |
240 | } |
241 | |
242 | static void nsReleaseObject (NPObject *npobj) { |
243 | NPObject *obj = npobj; |
244 | /*print ("NPN_ReleaseObject\n");*/ |
245 | if (!obj) |
246 | obj = scriptable_peer; |
247 | if (! (--obj->referenceCount)) { |
248 | if (obj->_class->deallocate) |
249 | obj->_class->deallocate (obj); |
250 | else |
251 | nsMemFree (obj); |
252 | if (obj == scriptable_peer) { |
253 | print ("NPN_ReleaseObject default\n"); |
254 | scriptable_peer = NULL; |
255 | } |
256 | } |
257 | } |
258 | |
259 | static NPError nsGetURL (NPP instance, const char* url, const char* target) { |
260 | (void)instance; |
261 | print ("nsGetURL %s %s\n", url, target ? target : ""); |
262 | addStream (url, 0L, target, 0, NULL, 0L, false); |
263 | return NPERR_NO_ERROR; |
264 | } |
265 | |
266 | static NPError nsPostURL (NPP instance, const char *url, |
267 | const char *target, uint32 len, const char *buf, NPBool file) { |
268 | (void)instance; (void)file; |
269 | print ("nsPostURL %s %s\n", url, target ? target : ""); |
270 | addStream (url, 0L, target, len, buf, 0L, false); |
271 | return NPERR_NO_ERROR; |
272 | } |
273 | |
274 | static NPError nsRequestRead (NPStream *stream, NPByteRange *rangeList) { |
275 | (void)stream; (void)rangeList; |
276 | print ("nsRequestRead\n"); |
277 | return NPERR_NO_ERROR; |
278 | } |
279 | |
280 | static NPError nsNewStream (NPP instance, NPMIMEType type, |
281 | const char *target, NPStream **stream) { |
282 | (void)instance; (void)type; (void)stream; (void)target; |
283 | print ("nsNewStream\n"); |
284 | return NPERR_NO_ERROR; |
285 | } |
286 | |
287 | static int32 nsWrite (NPP instance, NPStream* stream, int32 len, void *buf) { |
288 | (void)instance; (void)len; (void)buf; (void)stream; |
289 | print ("nsWrite\n"); |
290 | return 0; |
291 | } |
292 | |
293 | static NPError nsDestroyStream (NPP instance, NPStream *stream, NPError reason) { |
294 | StreamInfo *si = (StreamInfo *) g_tree_lookup (stream_list, stream->ndata); |
295 | (void)instance; |
296 | print ("nsDestroyStream\n"); |
297 | if (si) { |
298 | si->reason = reason; |
299 | si->destroyed = true; |
300 | g_timeout_add (0, destroyStream, stream->ndata); |
301 | return NPERR_NO_ERROR; |
302 | } |
303 | return NPERR_NO_DATA; |
304 | } |
305 | |
306 | static void nsStatus (NPP instance, const char* message) { |
307 | (void)instance; |
308 | print ("NPN_Status %s\n", message); |
309 | } |
310 | |
311 | static const char* nsUserAgent (NPP instance) { |
312 | (void)instance; |
313 | print ("NPN_UserAgent\n"); |
314 | return "Mozilla/5.0 (X11; U; Linux armv7l; en-US; rv:1.9.2a1pre) Gecko/20090907 Firefox/3.5 Maemo Browser 1.4.1.8 RX-51 N900"; |
315 | } |
316 | |
317 | static uint32 nsMemFlush (uint32 size) { |
318 | (void)size; |
319 | print ("NPN_MemFlush\n"); |
320 | return 0; |
321 | } |
322 | |
323 | static void nsReloadPlugins (NPBool reloadPages) { |
324 | (void)reloadPages; |
325 | print ("NPN_ReloadPlugins\n"); |
326 | } |
327 | |
328 | static JRIEnv* nsGetJavaEnv () { |
329 | print ("NPN_GetJavaEnv\n"); |
330 | return NULL; |
331 | } |
332 | |
333 | static jref nsGetJavaPeer (NPP instance) { |
334 | (void)instance; |
335 | print ("NPN_GetJavaPeer\n"); |
336 | return NULL; |
337 | } |
338 | |
339 | static NPError nsGetURLNotify (NPP instance, const char* url, const char* target, void *notify) { |
340 | (void)instance; |
341 | addStream (url, 0L, target, 0, NULL, notify, true); |
342 | return NPERR_NO_ERROR; |
343 | } |
344 | |
345 | static NPError nsPostURLNotify (NPP instance, const char* url, const char* target, uint32 len, const char* buf, NPBool file, void *notify) { |
346 | (void)instance; (void)file; |
347 | print ("NPN_PostURLNotify\n"); |
348 | addStream (url, 0L, target, len, buf, notify, true); |
349 | return NPERR_NO_ERROR; |
350 | } |
351 | |
352 | static NPError nsGetValue (NPP instance, NPNVariable variable, void *value) { |
353 | print ("NPN_GetValue %d\n", variable & ~NP_ABI_MASK); |
354 | switch (variable) { |
355 | case NPNVxDisplay: |
356 | *(void**)value = (void*)(long) gdk_x11_get_default_xdisplay (); |
357 | break; |
358 | case NPNVxtAppContext: |
359 | *(void**)value = NULL; |
360 | break; |
361 | case NPNVnetscapeWindow: |
362 | print ("NPNVnetscapeWindow\n"); |
363 | *(int*)value = 0; |
364 | break; |
365 | case NPNVjavascriptEnabledBool: |
366 | *(NPBool*)value = 1; |
367 | break; |
368 | case NPNVasdEnabledBool: |
369 | *(NPBool*)value = 0; |
370 | break; |
371 | case NPNVisOfflineBool: |
372 | *(NPBool*)value = 0; |
373 | break; |
374 | case NPNVserviceManager: |
375 | *(int*)value = 0; |
376 | break; |
377 | case NPNVToolkit: |
378 | *(int*)value = NPNVGtk2; |
379 | break; |
380 | case NPNVSupportsXEmbedBool: |
381 | *(NPBool*)value = 1; |
382 | break; |
383 | case NPNVWindowNPObject: |
384 | if (!js_window) { |
385 | JsObject *jo = (JsObject*) nsCreateObject (instance, &window_class); |
386 | jo->name = g_strdup ("window"); |
387 | js_window = (NPObject *) jo; |
388 | } |
389 | *(NPObject**)value = nsRetainObject (js_window); |
390 | break; |
391 | /*case NPNVPluginElementNPObject: { |
392 | JsObject * obj = (JsObject *) nsCreateObject (instance, &js_class); |
393 | obj->name = g_strdup ("this"); |
394 | *(NPObject**)value = (NPObject *) obj; |
395 | break; |
396 | }*/ |
397 | default: |
398 | print ("unknown value\n"); |
399 | return NPERR_GENERIC_ERROR; |
400 | } |
401 | return NPERR_NO_ERROR; |
402 | } |
403 | |
404 | static NPError nsSetValue (NPP instance, NPPVariable variable, void *value) { |
405 | /* NPPVpluginWindowBool */ |
406 | (void)instance; (void)value; |
407 | print ("NPN_SetValue %d\n", variable & ~NP_ABI_MASK); |
408 | return NPERR_NO_ERROR; |
409 | } |
410 | |
411 | static void nsInvalidateRect (NPP instance, NPRect *invalidRect) { |
412 | (void)instance; (void)invalidRect; |
413 | print ("NPN_InvalidateRect\n"); |
414 | } |
415 | |
416 | static void nsInvalidateRegion (NPP instance, NPRegion invalidRegion) { |
417 | (void)instance; (void)invalidRegion; |
418 | print ("NPN_InvalidateRegion\n"); |
419 | } |
420 | |
421 | static void nsForceRedraw (NPP instance) { |
422 | (void)instance; |
423 | print ("NPN_ForceRedraw\n"); |
424 | } |
425 | |
426 | static NPIdentifier nsGetStringIdentifier (const NPUTF8* name) { |
427 | /*print ("NPN_GetStringIdentifier %s\n", name);*/ |
428 | gpointer id = g_tree_lookup (identifiers, name); |
429 | if (!id) { |
430 | id = g_strdup (name); |
431 | g_tree_insert (identifiers, id, id); |
432 | } |
433 | return id; |
434 | } |
435 | |
436 | static void nsGetStringIdentifiers (const NPUTF8** names, int32_t nameCount, |
437 | NPIdentifier* ids) { |
438 | (void)names; (void)nameCount; (void)ids; |
439 | print ("NPN_GetStringIdentifiers\n"); |
440 | } |
441 | |
442 | static NPIdentifier nsGetIntIdentifier (int32_t intid) { |
443 | print ("NPN_GetIntIdentifier %d\n", intid); |
444 | return (NPIdentifier) (long) intid; |
445 | } |
446 | |
447 | static bool nsIdentifierIsString (NPIdentifier name) { |
448 | print ("NPN_IdentifierIsString\n"); |
449 | return !!g_tree_lookup (identifiers, name); |
450 | } |
451 | |
452 | static NPUTF8 * nsUTF8FromIdentifier (NPIdentifier name) { |
453 | char *str = (char *) g_tree_lookup (identifiers, name); |
454 | print ("NPN_UTF8FromIdentifier\n"); |
455 | if (str) |
456 | return (NPUTF8 *)g_strdup (str); |
457 | return NULL; |
458 | } |
459 | |
460 | static int32_t nsIntFromIdentifier (NPIdentifier identifier) { |
461 | print ("NPN_IntFromIdentifier\n"); |
462 | return (int32_t) (long) identifier; |
463 | } |
464 | |
465 | static bool nsInvoke (NPP instance, NPObject * npobj, NPIdentifier method, |
466 | const NPVariant *args, uint32_t arg_count, NPVariant *result) { |
467 | NPObject *obj = npobj; |
468 | (void)instance; |
469 | if (!obj) { |
470 | if (!scriptable_peer && |
471 | NPERR_NO_ERROR != np_funcs.getvalue (npp, |
472 | NPPVpluginScriptableNPObject, (void*)&scriptable_peer)) |
473 | return false; |
474 | obj = scriptable_peer; |
475 | } |
476 | /*print ("NPN_Invoke %s\n", id);*/ |
477 | if (obj->_class->invoke) |
478 | return obj->_class->invoke (obj, method, args, arg_count, result); |
479 | return false; |
480 | } |
481 | |
482 | static bool nsInvokeDefault (NPP instance, NPObject * npobj, |
483 | const NPVariant * args, uint32_t arg_count, NPVariant * result) { |
484 | (void)instance; |
485 | if (npobj->_class->invokeDefault) |
486 | return npobj->_class->invokeDefault (npobj,args, arg_count, result); |
487 | return false; |
488 | } |
489 | |
490 | static bool createUndefined (NPVariant *result) { |
491 | result->type = NPVariantType_String; |
492 | result->value.stringValue.utf8characters = g_strdup ("undefined"); |
493 | result->value.stringValue.utf8length = 9; |
494 | return true; |
495 | } |
496 | |
497 | static bool nsEvaluate (NPP instance, NPObject * npobj, NPString * script, |
498 | NPVariant * result) { |
499 | (void) instance; |
500 | (void) script; |
501 | return createUndefined (result); |
502 | } |
503 | |
504 | static bool nsGetProperty (NPP instance, NPObject * npobj, |
505 | NPIdentifier property, NPVariant * result) { |
506 | (void)instance; |
507 | if (npobj->_class->getProperty) |
508 | return npobj->_class->getProperty (npobj, property, result); |
509 | return false; |
510 | } |
511 | |
512 | static bool nsSetProperty (NPP instance, NPObject * npobj, |
513 | NPIdentifier property, const NPVariant *value) { |
514 | (void)instance; |
515 | if (npobj->_class->setProperty) |
516 | return npobj->_class->setProperty (npobj, property, value); |
517 | return false; |
518 | } |
519 | |
520 | static bool nsRemoveProperty (NPP inst, NPObject * npobj, NPIdentifier prop) { |
521 | (void)inst; |
522 | if (npobj->_class->removeProperty) |
523 | return npobj->_class->removeProperty (npobj, prop); |
524 | return false; |
525 | } |
526 | |
527 | static bool nsHasProperty (NPP instance, NPObject * npobj, NPIdentifier prop) { |
528 | (void)instance; |
529 | if (npobj->_class->hasProperty) |
530 | return npobj->_class->hasProperty (npobj, prop); |
531 | return false; |
532 | } |
533 | |
534 | static bool nsHasMethod (NPP instance, NPObject * npobj, NPIdentifier method) { |
535 | (void)instance; |
536 | if (npobj->_class->hasMethod) |
537 | return npobj->_class->hasMethod (npobj, method); |
538 | return false; |
539 | } |
540 | |
541 | static void nsReleaseVariantValue (NPVariant * variant) { |
542 | /*print ("NPN_ReleaseVariantValue\n");*/ |
543 | switch (variant->type) { |
544 | case NPVariantType_String: |
545 | if (variant->value.stringValue.utf8characters) |
546 | g_free ((char *) variant->value.stringValue.utf8characters); |
547 | break; |
548 | case NPVariantType_Object: |
549 | if (variant->value.objectValue) |
550 | nsReleaseObject (variant->value.objectValue); |
551 | break; |
552 | default: |
553 | break; |
554 | } |
555 | variant->type = NPVariantType_Null; |
556 | } |
557 | |
558 | static void nsSetException (NPObject *npobj, const NPUTF8 *message) { |
559 | (void)npobj; |
560 | print ("NPN_SetException %s\n", message ? message : ""); |
561 | } |
562 | |
563 | static bool nsPushPopupsEnabledState (NPP instance, NPBool enabled) { |
564 | (void)instance; |
565 | print ("NPN_PushPopupsEnabledState %d\n", enabled); |
566 | return false; |
567 | } |
568 | |
569 | static bool nsPopPopupsEnabledState (NPP instance) { |
570 | (void)instance; |
571 | print ("NPN_PopPopupsEnabledState\n"); |
572 | return false; |
573 | } |
574 | |
575 | /*----------------%<---------------------------------------------------------*/ |
576 | |
577 | static NPObject * jsClassAllocate (NPP instance, NPClass *aClass) { |
578 | /*print ("jsClassAllocate\n");*/ |
579 | JsObject * jo = (JsObject *) nsAlloc (sizeof (JsObject)); |
580 | (void)instance; |
581 | memset (jo, 0, sizeof (JsObject)); |
582 | jo->npobject._class = aClass; |
583 | return (NPObject *) jo; |
584 | } |
585 | |
586 | static void jsClassDeallocate (NPObject *npobj) { |
587 | JsObject *jo = (JsObject *) npobj; |
588 | /*print ("jsClassDeallocate\n");*/ |
589 | if (jo->name) |
590 | g_free (jo->name); |
591 | if (npobj == js_window) { |
592 | print ("WARNING deleting window object\n"); |
593 | js_window = NULL; |
594 | } |
595 | nsMemFree (npobj); |
596 | } |
597 | |
598 | static void jsClassInvalidate (NPObject *npobj) { |
599 | (void)npobj; |
600 | print ("jsClassInvalidate\n"); |
601 | } |
602 | |
603 | static bool jsClassHasMethod (NPObject *npobj, NPIdentifier name) { |
604 | (void)npobj; (void)name; |
605 | print ("windowClassHasMehtod\n"); |
606 | return false; |
607 | } |
608 | |
609 | static bool jsClassInvoke (NPObject *npobj, NPIdentifier method, |
610 | const NPVariant *args, uint32_t arg_count, NPVariant *result) { |
611 | (void) npobj; |
612 | (void) method; |
613 | (void) args; |
614 | (void) arg_count; |
615 | return createUndefined (result); |
616 | } |
617 | |
618 | static bool jsClassInvokeDefault (NPObject *npobj, |
619 | const NPVariant *args, uint32_t arg_count, NPVariant *result) { |
620 | (void)npobj; (void)args; (void)arg_count; (void)result; |
621 | print ("jsClassInvokeDefault\n"); |
622 | return false; |
623 | } |
624 | |
625 | static bool jsClassHasProperty (NPObject *npobj, NPIdentifier name) { |
626 | (void)npobj; (void)name; |
627 | print ("jsClassHasProperty\n"); |
628 | return false; |
629 | } |
630 | |
631 | static bool jsClassGetProperty (NPObject *npobj, NPIdentifier property, |
632 | NPVariant *result) { |
633 | (void) npobj; |
634 | (void) property; |
635 | return createUndefined (result); |
636 | } |
637 | |
638 | static bool jsClassSetProperty (NPObject *npobj, NPIdentifier property, |
639 | const NPVariant *value) { |
640 | (void) npobj; |
641 | (void) property; |
642 | (void) value; |
643 | |
644 | return true; |
645 | } |
646 | |
647 | static bool jsClassRemoveProperty (NPObject *npobj, NPIdentifier name) { |
648 | (void)npobj; (void)name; |
649 | print ("jsClassRemoveProperty\n"); |
650 | return false; |
651 | } |
652 | |
653 | static bool windowClassGetProperty (NPObject *npobj, NPIdentifier property, |
654 | NPVariant *result) { |
655 | char * id = (char *) g_tree_lookup (identifiers, property); |
656 | print ("windowClassGetProperty.GetProperty %s\n", id); |
657 | if (!strcmp (id, "location")) { |
658 | JsObject *jo = (JsObject*) nsCreateObject (NULL, &location_class); |
659 | jo->name = g_strdup ("location"); |
660 | result->value.objectValue = (NPObject *) jo; |
661 | result->type = NPVariantType_Object; |
662 | return true; |
663 | } else if (!strcmp (id, "top")) { |
664 | result->value.objectValue = nsRetainObject (npobj); |
665 | result->type = NPVariantType_Object; |
666 | return true; |
667 | } |
668 | return jsClassGetProperty (npobj, property, result); |
669 | } |
670 | |
671 | static bool createStartLink (NPVariant *result) { |
672 | result->type = NPVariantType_String; |
673 | result->value.stringValue.utf8length = strlen (start_url); |
674 | result->value.stringValue.utf8characters = (char *) nsAlloc (strlen (start_url) + 1); |
675 | strcpy ((char *) result->value.stringValue.utf8characters, start_url); |
676 | return true; |
677 | } |
678 | |
679 | static bool locationClassGetProperty (NPObject *npobj, NPIdentifier property, |
680 | NPVariant *result) { |
681 | char * id = (char *) g_tree_lookup (identifiers, property); |
682 | print ("locationClass.GetProperty %s\n", id); |
683 | if (!strcmp (id, "href")) |
684 | return createStartLink (result); |
685 | return jsClassGetProperty (npobj, property, result); |
686 | } |
687 | |
688 | static bool locationClassInvoke (NPObject *npobj, NPIdentifier method, |
689 | const NPVariant *args, uint32_t arg_count, NPVariant *result) { |
690 | char *id = (char *) g_tree_lookup (identifiers, method); |
691 | print ("locationClass.Invoke %s\n", id); |
692 | if (!strcmp (id, "toString")) |
693 | return createStartLink (result); |
694 | return jsClassInvoke (npobj, method, args, arg_count, result); |
695 | } |
696 | |
697 | |
698 | /*----------------%<---------------------------------------------------------*/ |
699 | |
700 | void nppPluginShutdown (NPPluginLib *lib) { |
701 | print ("nppPluginShutdown\n"); |
702 | if (lib) { |
703 | if (lib->npShutdown) |
704 | lib->npShutdown(); |
705 | g_module_close (lib->module); |
706 | nsMemFree (lib); |
707 | } |
708 | } |
709 | |
710 | NPPluginLib *nppPluginInit (const char *lib) { |
711 | NPError np_err; |
712 | NPPluginLib *plugin_lib; |
713 | GModule *library; |
714 | |
715 | print ("starting %s\n", lib); |
716 | library = g_module_open (lib, G_MODULE_BIND_LAZY); |
717 | if (!library) { |
718 | print ("failed to load %s %s\n", lib, g_module_error ()); |
719 | return NULL; |
720 | } |
721 | |
722 | plugin_lib = (NPPluginLib *)nsAlloc (sizeof (NPPluginLib)); |
723 | plugin_lib->module = library; |
724 | |
725 | if (!g_module_symbol (library, |
726 | "NP_GetMIMEDescription", |
727 | (gpointer *)&plugin_lib->npGetMIMEDescription)) { |
728 | print ("undefined reference to load NP_GetMIMEDescription\n"); |
729 | goto bail_out; |
730 | } |
731 | if (!g_module_symbol (library, |
732 | "NP_Initialize", (gpointer *)&plugin_lib->npInitialize)) { |
733 | print ("undefined reference to load NP_Initialize\n"); |
734 | goto bail_out; |
735 | } |
736 | if (!g_module_symbol (library, |
737 | "NP_Shutdown", (gpointer *)&plugin_lib->npShutdown)) { |
738 | print ("undefined reference to load NP_Shutdown\n"); |
739 | goto bail_out; |
740 | } |
741 | print ("startup succeeded %s\n", plugin_lib->npGetMIMEDescription ()); |
742 | |
743 | memset (&ns_funcs, 0, sizeof (NPNetscapeFuncs)); |
744 | ns_funcs.size = sizeof (NPNetscapeFuncs); |
745 | ns_funcs.version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; |
746 | ns_funcs.geturl = nsGetURL; |
747 | ns_funcs.posturl = nsPostURL; |
748 | ns_funcs.requestread = nsRequestRead; |
749 | ns_funcs.newstream = nsNewStream; |
750 | ns_funcs.write = nsWrite; |
751 | ns_funcs.destroystream = nsDestroyStream; |
752 | ns_funcs.status = nsStatus; |
753 | ns_funcs.uagent = nsUserAgent; |
754 | ns_funcs.memalloc = nsAlloc; |
755 | ns_funcs.memfree = nsMemFree; |
756 | ns_funcs.memflush = nsMemFlush; |
757 | ns_funcs.reloadplugins = nsReloadPlugins; |
758 | ns_funcs.getJavaEnv = nsGetJavaEnv; |
759 | ns_funcs.getJavaPeer = nsGetJavaPeer; |
760 | ns_funcs.geturlnotify = nsGetURLNotify; |
761 | ns_funcs.posturlnotify = nsPostURLNotify; |
762 | ns_funcs.getvalue = nsGetValue; |
763 | ns_funcs.setvalue = nsSetValue; |
764 | ns_funcs.invalidaterect = nsInvalidateRect; |
765 | ns_funcs.invalidateregion = nsInvalidateRegion; |
766 | ns_funcs.forceredraw = nsForceRedraw; |
767 | ns_funcs.getstringidentifier = nsGetStringIdentifier; |
768 | ns_funcs.getstringidentifiers = nsGetStringIdentifiers; |
769 | ns_funcs.getintidentifier = nsGetIntIdentifier; |
770 | ns_funcs.identifierisstring = nsIdentifierIsString; |
771 | ns_funcs.utf8fromidentifier = nsUTF8FromIdentifier; |
772 | ns_funcs.intfromidentifier = nsIntFromIdentifier; |
773 | ns_funcs.createobject = nsCreateObject; |
774 | ns_funcs.retainobject = nsRetainObject; |
775 | ns_funcs.releaseobject = nsReleaseObject; |
776 | ns_funcs.invoke = nsInvoke; |
777 | ns_funcs.invokeDefault = nsInvokeDefault; |
778 | ns_funcs.evaluate = nsEvaluate; |
779 | ns_funcs.getproperty = nsGetProperty; |
780 | ns_funcs.setproperty = nsSetProperty; |
781 | ns_funcs.removeproperty = nsRemoveProperty; |
782 | ns_funcs.hasproperty = nsHasProperty; |
783 | ns_funcs.hasmethod = nsHasMethod; |
784 | ns_funcs.releasevariantvalue = nsReleaseVariantValue; |
785 | ns_funcs.setexception = nsSetException; |
786 | ns_funcs.pushpopupsenabledstate = nsPushPopupsEnabledState; |
787 | ns_funcs.poppopupsenabledstate = nsPopPopupsEnabledState; |
788 | |
789 | js_class.structVersion = NP_CLASS_STRUCT_VERSION; |
790 | js_class.allocate = jsClassAllocate; |
791 | js_class.deallocate = jsClassDeallocate; |
792 | js_class.invalidate = jsClassInvalidate; |
793 | js_class.hasMethod = jsClassHasMethod; |
794 | js_class.invoke = jsClassInvoke; |
795 | js_class.invokeDefault = jsClassInvokeDefault; |
796 | js_class.hasProperty = jsClassHasProperty; |
797 | js_class.getProperty = jsClassGetProperty; |
798 | js_class.setProperty = jsClassSetProperty; |
799 | js_class.removeProperty = jsClassRemoveProperty; |
800 | |
801 | window_class = js_class; |
802 | window_class.getProperty = windowClassGetProperty; |
803 | |
804 | location_class = js_class; |
805 | location_class.getProperty = locationClassGetProperty; |
806 | location_class.invoke = locationClassInvoke; |
807 | |
808 | np_funcs.size = sizeof (NPPluginFuncs); |
809 | |
810 | np_err = plugin_lib->npInitialize (&ns_funcs, &np_funcs); |
811 | if (np_err != NPERR_NO_ERROR) { |
812 | print ("NP_Initialize failure %d\n", np_err); |
813 | goto bail_out; |
814 | } |
815 | |
816 | identifiers = g_tree_new ((GCompareFunc) strcmp); |
817 | stream_list = g_tree_new (streamCompare); |
818 | |
819 | return plugin_lib; |
820 | |
821 | bail_out: |
822 | nsMemFree (plugin_lib); |
823 | return NULL; |
824 | } |
825 | |
826 | void *nppInstanceOpen (const char *mime, uint16_t argc, char *argn[], |
827 | char *argv[], void *ndata, NSNotify *notify) { |
828 | NPError np_err; |
829 | Display *display; |
830 | int screen; |
831 | int i; |
832 | int needs_xembed; |
833 | /*unsigned int width = 0, height = 0;*/ |
834 | |
835 | browser_data = ndata; |
836 | browser_notify = notify; |
837 | |
838 | npp = (NPP_t*)nsAlloc (sizeof (NPP_t)); |
839 | memset (npp, 0, sizeof (NPP_t)); |
840 | /*for (i = 0; i < argc; i++) { |
841 | print ("arg %s %s\n", argn[i], argv[i]); |
842 | if (!strcasecmp (argn[i], "width")) |
843 | width = strtol (argv[i], 0L, 10); |
844 | else if (!strcasecmp (argn[i], "height")) |
845 | height = strtol (argv[i], 0L, 10); |
846 | } |
847 | if (width > 0 && height > 0) |
848 | notify->setDimension (ndata, width, height);*/ |
849 | |
850 | np_err = np_funcs.newp ((char *)mime, npp, NP_EMBED, argc, argn, argv, saved_data); |
851 | if (np_err != NPERR_NO_ERROR) { |
852 | print ("NPP_New failure %d %p %p\n", np_err, np_funcs, np_funcs.newp); |
853 | nsMemFree (npp); |
854 | return NULL; |
855 | } |
856 | if (np_funcs.getvalue) { |
857 | np_err = np_funcs.getvalue (npp, |
858 | NPPVpluginNeedsXEmbed, (void*)&needs_xembed); |
859 | if (np_err != NPERR_NO_ERROR || !needs_xembed) { |
860 | print ("NPP_GetValue NPPVpluginNeedsXEmbed failure %d\n", np_err); |
861 | /*shutdownPlugin();*/ |
862 | nsMemFree (npp); |
863 | return NULL; |
864 | } |
865 | } |
866 | memset (&np_window, 0, sizeof (NPWindow)); |
867 | display = gdk_x11_get_default_xdisplay (); |
868 | np_window.x = 0; |
869 | np_window.y = 0; |
870 | np_window.width = top_w; /*width ? width : top_w;*/ |
871 | np_window.height = top_h; /*height ? height : top_h;*/ |
872 | np_window.window = (void*)socket_id; |
873 | np_window.type = NPWindowTypeWindow; |
874 | ws_info.type = NP_SETWINDOW; |
875 | screen = DefaultScreen (display); |
876 | ws_info.display = display; |
877 | ws_info.visual = DefaultVisual (display, screen); |
878 | ws_info.colormap = DefaultColormap (display, screen); |
879 | ws_info.depth = DefaultDepth (display, screen); |
880 | print ("display %u %dx%d\n", socket_id, np_window.width, np_window.height); |
881 | np_window.ws_info = (void*)&ws_info; |
882 | |
883 | np_err = np_funcs.setwindow (npp, &np_window); |
884 | |
885 | return npp; |
886 | } |
887 | |
888 | void nppInstanceTopUrl (const char *url) { |
889 | g_free (start_url); |
890 | start_url = g_strdup (url); |
891 | } |
892 | |
893 | void nppInstanceStart (const char *url, const char *mime, void *pdata) { |
894 | (void) pdata; |
895 | addStream (url, mime, 0L, 0, NULL, 0L, false); |
896 | } |
897 | |
898 | void nppStreamData (uint32_t stream, const char *buf, uint32_t sz, void *p) { |
899 | int written = writeStream (stream, buf, sz); |
900 | (void)p; |
901 | if (written < sz) |
902 | print ("FIXME: plugin didn't accept data %d written %d\n", sz, written); |
903 | } |
904 | |
905 | void nppStreamFinished (uint32_t stream, uint32_t reason, void *pdata) { |
906 | StreamInfo *si = (StreamInfo *) g_tree_lookup (stream_list, (void *)stream); |
907 | print ("nppStreamFinished\n"); |
908 | if (si) { |
909 | si->reason = reason; |
910 | removeStream (stream); |
911 | } |
912 | } |
913 | |
914 | void nppStreamRedirected (uint32_t stream, const char *url) { |
915 | StreamInfo *si = (StreamInfo *) g_tree_lookup (stream_list, (void *) stream); |
916 | if (si) { |
917 | g_free (si->url); |
918 | si->url = g_strdup (url); |
919 | si->np_stream.url = si->url; |
920 | } |
921 | } |
922 | |
923 | void nppStreamInfo (uint32_t sid, const char *mime, unsigned long length) { |
924 | StreamInfo *si = (StreamInfo *) g_tree_lookup (stream_list, (void *) sid); |
925 | if (si) { |
926 | print ("nppStreamInfo %s %s\n", si->url, mime ? mime : ""); |
927 | if (si->mimetype) |
928 | g_free (si->mimetype); |
929 | si->mimetype = mime ? g_strdup (mime) : NULL; |
930 | si->np_stream.end = length; |
931 | } |
932 | } |
933 | |
934 | void nppInstanceClose (void *pdata) { |
935 | if (scriptable_peer) { |
936 | nsReleaseObject (scriptable_peer); |
937 | scriptable_peer = NULL; |
938 | } |
939 | if (npp) { |
940 | np_funcs.destroy (npp, &saved_data); |
941 | nsMemFree (npp); |
942 | npp = 0L; |
943 | } |
944 | g_free (start_url); |
945 | start_url = NULL; |
946 | top_w = 0; |
947 | top_h = 0; |
948 | np_window.window = NULL; |
949 | } |
950 | |
951 | void nppInstanceWindowClose (void *priv) { |
952 | (void)priv; |
953 | |
954 | np_window.window = NULL; |
955 | } |
956 | |
957 | /*----------------%<---------------------------------------------------------*/ |
958 | |
959 | static gboolean updateDimension (void * p) { |
960 | (void)p; |
961 | if (np_window.window && |
962 | (np_window.width != top_w || np_window.height != top_h)) { |
963 | np_window.width = top_w; |
964 | np_window.height = top_h; |
965 | np_funcs.setwindow (npp, &np_window); |
966 | } |
967 | update_dimension_timer = 0; |
968 | return 0; /* single shot */ |
969 | } |
970 | |
971 | void nppInstanceWindowDimension (void *p, int x, int y, int w, int h) { |
972 | (void)p; (void) x; (void) y; |
973 | print ("nppInstanceWindowDimension %dx%d\n", w, h); |
974 | if (!update_dimension_timer) |
975 | update_dimension_timer = g_timeout_add (100, updateDimension, NULL); |
976 | top_w = w; |
977 | top_h = h; |
978 | } |
979 | |
980 | void nppInstanceWindowParent (void *p, void * wid) { |
981 | (void)p; |
982 | socket_id = (Window) wid; |
983 | } |
984 |