Contents of /trunk/src/npplayer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1009 - (show annotations)
Sun Dec 11 14:33:15 2011 UTC (12 years, 4 months ago) by koos
File MIME type: text/plain
File size: 31232 byte(s)
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