45 |
#include "pluginDebug.h" |
#include "pluginDebug.h" |
46 |
#include "pluginMeta.h" |
#include "pluginMeta.h" |
47 |
|
|
48 |
|
// Support hack to get documentbase. |
49 |
|
#include <nsIPluginInstance.h> |
50 |
|
#include <nsIPluginInstancePeer.h> |
51 |
|
#include <nsIPluginTagInfo2.h> |
52 |
|
|
53 |
|
static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID); |
54 |
|
|
55 |
static NPNetscapeFuncs browserFunctions; |
static NPNetscapeFuncs browserFunctions; |
56 |
|
|
57 |
static gint send_message_to_appletviewer (NPP instance, gchar *name, gchar *value); |
static gint send_message_to_appletviewer (gchar const* name, gchar *value); |
58 |
static gint receive_message_from_appletviewer (NPP instance, gchar *string); |
static gint receive_message_from_appletviewer (gchar* string); |
59 |
|
|
60 |
struct GCJPluginData |
struct GCJPluginData |
61 |
{ |
{ |
62 |
char *code; |
char *code; |
63 |
char *codebase; |
char *codebase; |
64 |
char *archive; |
char *archive; |
65 |
char *documentbase; |
char const* documentbase; |
66 |
char *parameters; |
char *parameters; |
67 |
char *width; |
char *width; |
68 |
char *height; |
char *height; |
72 |
GIOChannel *input_from_appletviewer; |
GIOChannel *input_from_appletviewer; |
73 |
}; |
}; |
74 |
|
|
75 |
|
static GIOChannel *output_to_appletviewer = NULL; |
76 |
|
static GIOChannel *input_from_appletviewer = NULL; |
77 |
|
|
78 |
NPError |
NPError |
79 |
GCJ_GetValue (NPP instance, NPPVariable variable, void* value) |
GCJ_GetValue (NPP instance, NPPVariable variable, void* value) |
80 |
{ |
{ |
112 |
if (!data) |
if (!data) |
113 |
return NPERR_OUT_OF_MEMORY_ERROR; |
return NPERR_OUT_OF_MEMORY_ERROR; |
114 |
|
|
115 |
// FIXME: size this dynamically. |
// This little hack gets the current document's documentbase. It |
116 |
gchar *command_line[50]; |
// will only work when the plugin is loaded in Mozilla, because it |
117 |
|
// relys on browser-private data. |
118 |
// Allocate memory for the gcjappletviewer name, --plugin option, each |
nsIPluginInstance* xpcom_instance = (nsIPluginInstance *) (instance->ndata); |
119 |
// applet tag attribute and a terminating NULL. |
nsIPluginInstancePeer* peer = NULL; |
120 |
|
xpcom_instance->GetPeer (&peer); |
121 |
|
|
122 |
|
nsresult result; |
123 |
|
nsIPluginTagInfo2* pluginTagInfo2; |
124 |
|
result = peer->QueryInterface (kIPluginTagInfo2IID, (void**) &pluginTagInfo2); |
125 |
|
|
126 |
command_line[0] = g_strdup ("gcjappletviewer"); |
pluginTagInfo2->GetDocumentBase (&data->documentbase); |
|
command_line[1] = g_strdup ("--plugin"); |
|
127 |
|
|
128 |
int arg_count = 2; |
gchar *applet_tag = g_strdup ("<EMBED "); |
129 |
|
|
130 |
for (int i = 0; i < argc; i++) |
for (int i = 0; i < argc; i++) |
131 |
{ |
{ |
|
// FIXME: Use glib functions here. |
|
132 |
if (!g_ascii_strcasecmp (argn[i], "code")) |
if (!g_ascii_strcasecmp (argn[i], "code")) |
133 |
{ |
{ |
134 |
data->code = g_strdup (argv[i]); |
data->code = g_strdup (argv[i]); |
135 |
continue; |
applet_tag = g_strconcat (applet_tag, |
136 |
|
g_strdup_printf ("CODE=\"%s\" ", argv[i]), NULL); |
137 |
} |
} |
138 |
else if (!g_ascii_strcasecmp (argn[i], "codebase")) |
else if (!g_ascii_strcasecmp (argn[i], "codebase")) |
139 |
data->codebase = g_strdup (argv[i]); |
{ |
140 |
|
data->codebase = g_strdup (argv[i]); |
141 |
|
applet_tag = g_strconcat (applet_tag, |
142 |
|
g_strdup_printf ("CODEBASE=\"%s\" ", argv[i]), NULL); |
143 |
|
} |
144 |
else if (!g_ascii_strcasecmp (argn[i], "archive")) |
else if (!g_ascii_strcasecmp (argn[i], "archive")) |
145 |
data->archive = g_strdup (argv[i]); |
{ |
146 |
else if (!g_ascii_strcasecmp (argn[i], "documentbase")) |
data->archive = g_strdup (argv[i]); |
147 |
data->documentbase = g_strdup (argv[i]); |
applet_tag = g_strconcat (applet_tag, |
148 |
else if (!g_ascii_strcasecmp (argn[i], "parameters")) |
g_strdup_printf ("ARCHIVE=\"%s\" ", argv[i]), NULL); |
149 |
{ |
} |
|
// FIXME: need to handle multiple params |
|
|
data->documentbase = g_strdup (argv[i]); |
|
|
g_printerr ("THESE ARE THE PARAMETERS: %s\n", argv[i]); |
|
|
} |
|
150 |
else if (!g_ascii_strcasecmp (argn[i], "width")) |
else if (!g_ascii_strcasecmp (argn[i], "width")) |
151 |
data->width = g_strdup (argv[i]); |
{ |
152 |
|
data->width = g_strdup (argv[i]); |
153 |
|
applet_tag = g_strconcat (applet_tag, |
154 |
|
g_strdup_printf ("WIDTH=\"%s\" ", argv[i]), NULL); |
155 |
|
} |
156 |
else if (!g_ascii_strcasecmp (argn[i], "height")) |
else if (!g_ascii_strcasecmp (argn[i], "height")) |
157 |
data->height = g_strdup (argv[i]); |
{ |
158 |
|
data->height = g_strdup (argv[i]); |
159 |
|
applet_tag = g_strconcat (applet_tag, |
160 |
|
g_strdup_printf ("HEIGHT=\"%s\" ", argv[i]), NULL); |
161 |
|
} |
162 |
else |
else |
163 |
{ |
{ |
164 |
g_printerr ("GCJWebPlugin: unrecognized attribute\n"); |
applet_tag = g_strconcat (applet_tag, |
165 |
continue; |
g_strdup_printf ("%s=\"%s\" ", argn[i], argv[i]), NULL); |
166 |
} |
} |
|
command_line[arg_count++] = g_strdup_printf ("--%s=%s", argn[i], argv[i]); |
|
167 |
} |
} |
168 |
command_line[arg_count] = NULL; |
applet_tag = g_strconcat (applet_tag, |
169 |
|
g_strdup_printf ("></EMBED>"), NULL); |
|
GError *err = NULL; |
|
|
gint output_to_appletviewer = 0; |
|
|
gint input_from_appletviewer = 0; |
|
|
if (!g_spawn_async_with_pipes (NULL, |
|
|
command_line, |
|
|
NULL, |
|
|
G_SPAWN_SEARCH_PATH, |
|
|
NULL, |
|
|
NULL, |
|
|
NULL, |
|
|
&output_to_appletviewer, |
|
|
&input_from_appletviewer, |
|
|
NULL, |
|
|
&err)) |
|
|
{ |
|
|
g_printerr ("GCJ_New: Error: %s\n", err->message); |
|
|
return NPERR_GENERIC_ERROR; |
|
|
} |
|
|
|
|
|
// FIXME: Free command_line. |
|
|
|
|
|
data->output_to_appletviewer = g_io_channel_unix_new (output_to_appletviewer); |
|
|
data->input_from_appletviewer = g_io_channel_unix_new (input_from_appletviewer); |
|
170 |
|
|
171 |
instance->pdata = data; |
instance->pdata = data; |
172 |
|
|
173 |
NPError np_error; |
// FIXME: this multi-instance messaging scheme won't work. we need |
174 |
if ((np_error = receive_message_from_appletviewer (instance, "running")) != NPERR_NO_ERROR) |
// a one that includes the instance name in each message, eg: |
175 |
return np_error; |
// Applet0: tag |
176 |
|
// Applet0: <EMBED ...></EMBED> |
177 |
|
// Also, we need a global counter so we can name each instance |
178 |
|
// uniquely. |
179 |
|
|
180 |
|
send_message_to_appletviewer ("instance", NULL); |
181 |
|
send_message_to_appletviewer ("Applet 0", NULL); |
182 |
|
send_message_to_appletviewer ("tag", NULL); |
183 |
|
send_message_to_appletviewer (data->documentbase, NULL); |
184 |
|
send_message_to_appletviewer (applet_tag, NULL); |
185 |
|
|
186 |
return NPERR_NO_ERROR; |
return NPERR_NO_ERROR; |
187 |
} |
} |
192 |
PLUGIN_DEBUG ("GCJ_Destroy\n"); |
PLUGIN_DEBUG ("GCJ_Destroy\n"); |
193 |
|
|
194 |
// FIXME: Free NPP->pdata structures. |
// FIXME: Free NPP->pdata structures. |
195 |
return send_message_to_appletviewer (instance, "shutdown", NULL); |
return send_message_to_appletviewer ("shutdown", NULL); |
196 |
} |
} |
197 |
|
|
198 |
NPError |
NPError |
207 |
|
|
208 |
data->width = g_strdup_printf ("%d", window->width); |
data->width = g_strdup_printf ("%d", window->width); |
209 |
data->height = g_strdup_printf ("%d", window->height); |
data->height = g_strdup_printf ("%d", window->height); |
210 |
data->xid = g_strdup_printf ("0x%x", (int)(window->window)); |
data->xid = g_strdup_printf ("%d", (int)(window->window)); |
211 |
|
|
212 |
|
// FIXME: check the return values here. |
213 |
|
send_message_to_appletviewer ("xid", NULL); |
214 |
|
send_message_to_appletviewer (data->xid, NULL); |
215 |
|
|
216 |
return send_message_to_appletviewer (instance, "xid", data->xid); |
return NPERR_NO_ERROR; |
217 |
} |
} |
218 |
|
|
219 |
NPError |
NPError |
221 |
{ |
{ |
222 |
PLUGIN_DEBUG ("GCJ_NewStream\n"); |
PLUGIN_DEBUG ("GCJ_NewStream\n"); |
223 |
|
|
|
// Tell the web browser to download the file and notify the plugin when ready. |
|
|
*stype = NP_ASFILEONLY; |
|
|
|
|
224 |
return NPERR_NO_ERROR; |
return NPERR_NO_ERROR; |
225 |
} |
} |
226 |
|
|
228 |
GCJ_StreamAsFile (NPP instance, NPStream* stream, const char* filename) |
GCJ_StreamAsFile (NPP instance, NPStream* stream, const char* filename) |
229 |
{ |
{ |
230 |
PLUGIN_DEBUG ("GCJ_StreamAsFile\n"); |
PLUGIN_DEBUG ("GCJ_StreamAsFile\n"); |
|
|
|
|
if (filename != NULL) |
|
|
{ |
|
|
// FIXME: load Applet from filename |
|
|
} |
|
231 |
} |
} |
232 |
|
|
233 |
NPError |
NPError |
283 |
} |
} |
284 |
|
|
285 |
static gint |
static gint |
286 |
send_message_to_appletviewer (NPP instance, gchar *name, gchar *value) |
send_message_to_appletviewer (gchar const* name, gchar *value) |
287 |
{ |
{ |
288 |
GError *err = NULL; |
GError *err = NULL; |
289 |
gsize bytes_written; |
gsize bytes_written; |
|
GCJPluginData* data = (GCJPluginData *)instance->pdata; |
|
290 |
NPError np_error; |
NPError np_error; |
291 |
|
|
292 |
// Send name of attribute to gcjappletviewer. |
// Send name of attribute to gcjappletviewer. |
293 |
gchar *name_buf = g_strdup_printf ("%s\n", name); |
gchar *name_buf = g_strdup_printf ("%s\n", name); |
294 |
|
|
295 |
if (g_io_channel_write_chars (data->output_to_appletviewer, |
if (g_io_channel_write_chars (output_to_appletviewer, |
296 |
name_buf, -1, &bytes_written, &err) |
name_buf, -1, &bytes_written, &err) |
297 |
!= G_IO_STATUS_NORMAL) |
!= G_IO_STATUS_NORMAL) |
298 |
{ |
{ |
303 |
g_error_free (err); |
g_error_free (err); |
304 |
err = NULL; |
err = NULL; |
305 |
|
|
306 |
g_io_channel_flush (data->output_to_appletviewer, &err); |
g_io_channel_flush (output_to_appletviewer, &err); |
307 |
if (err) |
if (err) |
308 |
g_error_free (err); |
g_error_free (err); |
309 |
err = NULL; |
err = NULL; |
310 |
PIPE_OUTPUT_DEBUG (name); |
PIPE_OUTPUT_DEBUG (name); |
311 |
|
|
312 |
if ((np_error = receive_message_from_appletviewer (instance, name)) != NPERR_NO_ERROR) |
gchar *recv_name = g_strdup (name); |
313 |
|
|
314 |
|
if ((np_error = receive_message_from_appletviewer (recv_name)) != NPERR_NO_ERROR) |
315 |
return np_error; |
return np_error; |
316 |
|
|
317 |
if (value) |
if (value) |
318 |
{ |
{ |
319 |
// Send value of attribute to gcjappletviewer. |
// Send value of attribute to gcjappletviewer. |
320 |
gchar *value_buf = g_strdup_printf ("%s\n", value); |
gchar *value_buf = g_strdup_printf ("%s\n", value); |
321 |
if (g_io_channel_write_chars (data->output_to_appletviewer, |
if (g_io_channel_write_chars (output_to_appletviewer, |
322 |
value_buf, -1, &bytes_written, &err) |
value_buf, -1, &bytes_written, &err) |
323 |
!= G_IO_STATUS_NORMAL) |
!= G_IO_STATUS_NORMAL) |
324 |
{ |
{ |
330 |
err = NULL; |
err = NULL; |
331 |
PIPE_OUTPUT_DEBUG (value); |
PIPE_OUTPUT_DEBUG (value); |
332 |
|
|
333 |
g_io_channel_flush (data->output_to_appletviewer, &err); |
g_io_channel_flush (output_to_appletviewer, &err); |
334 |
if (err) |
if (err) |
335 |
g_error_free (err); |
g_error_free (err); |
336 |
err = NULL; |
err = NULL; |
337 |
|
|
338 |
if ((np_error = receive_message_from_appletviewer (instance, value)) != NPERR_NO_ERROR) |
if ((np_error = receive_message_from_appletviewer (value)) != NPERR_NO_ERROR) |
339 |
return np_error; |
return np_error; |
340 |
} |
} |
341 |
|
|
342 |
g_printerr ("send_message_to_appletviewer: Success: %s, %s\n", name, value); |
g_printerr ("send_message_to_appletviewer: Success: %s, %s\n", recv_name, value); |
343 |
|
|
344 |
return NPERR_NO_ERROR; |
return NPERR_NO_ERROR; |
345 |
} |
} |
346 |
|
|
347 |
static gint |
static gint |
348 |
receive_message_from_appletviewer (NPP instance, gchar *str) |
receive_message_from_appletviewer (gchar *str) |
349 |
{ |
{ |
350 |
GError *err = NULL; |
GError *err = NULL; |
|
GCJPluginData* data = (GCJPluginData *)instance->pdata; |
|
351 |
|
|
352 |
// Receive message from gcjappletviewer. |
// Receive message from gcjappletviewer. |
353 |
gchar *read_buf; |
gchar *read_buf; |
354 |
if (g_io_channel_read_line (data->input_from_appletviewer, |
if (g_io_channel_read_line (input_from_appletviewer, |
355 |
&read_buf, NULL, NULL, &err) |
&read_buf, NULL, NULL, &err) |
356 |
!= G_IO_STATUS_NORMAL) |
!= G_IO_STATUS_NORMAL) |
357 |
{ |
{ |
440 |
pluginTable->urlnotify = NewNPP_URLNotifyProc(GCJ_URLNotify); |
pluginTable->urlnotify = NewNPP_URLNotifyProc(GCJ_URLNotify); |
441 |
pluginTable->getvalue = NewNPP_GetValueProc(GCJ_GetValue); |
pluginTable->getvalue = NewNPP_GetValueProc(GCJ_GetValue); |
442 |
|
|
443 |
|
GError *err = NULL; |
444 |
|
gint output_to_gcjappletviewer; |
445 |
|
gint input_from_gcjappletviewer; |
446 |
|
gchar *command_line [3] = { "gcjappletviewer", "--plugin", NULL }; |
447 |
|
|
448 |
|
if (!g_spawn_async_with_pipes (NULL, |
449 |
|
command_line, |
450 |
|
NULL, |
451 |
|
G_SPAWN_SEARCH_PATH, |
452 |
|
NULL, |
453 |
|
NULL, |
454 |
|
NULL, |
455 |
|
&output_to_gcjappletviewer, |
456 |
|
&input_from_gcjappletviewer, |
457 |
|
NULL, |
458 |
|
&err)) |
459 |
|
{ |
460 |
|
g_printerr ("GCJ_New: Error: %s\n", err->message); |
461 |
|
return NPERR_GENERIC_ERROR; |
462 |
|
} |
463 |
|
|
464 |
|
output_to_appletviewer = g_io_channel_unix_new (output_to_gcjappletviewer); |
465 |
|
input_from_appletviewer = g_io_channel_unix_new (input_from_gcjappletviewer); |
466 |
|
|
467 |
|
g_printerr ("Spawned gcjappletviewer successfully.\n"); |
468 |
|
|
469 |
|
NPError np_error; |
470 |
|
if ((np_error = receive_message_from_appletviewer ("running")) != NPERR_NO_ERROR) |
471 |
|
return np_error; |
472 |
|
|
473 |
|
g_printerr ("Got confirmation that gcjappletviewer is running.\n"); |
474 |
|
|
475 |
return NPERR_NO_ERROR; |
return NPERR_NO_ERROR; |
476 |
} |
} |
477 |
|
|