#include <ctype.h>
#include <stdlib.h>
#include "RxPlugin.h"
#include "X11/StringDefs.h"
static void
FreeArgs(char* argn[], char* argv[], int argc)
{
int i;
if (argc != 0) {
for (i = 0; i < argc; i++) {
NPN_MemFree(argn[i]);
NPN_MemFree(argv[i]);
}
NPN_MemFree(argn);
NPN_MemFree(argv);
}
}
static NPError
CopyArgs(char** argn1[], char** argv1[], int16* argc1,
char* argn2[], char* argv2[], int16 argc2)
{
char **argn, **argv;
int i;
argn = (char **)NPN_MemAlloc(sizeof(char *) * argc2);
if (!argn)
return NPERR_OUT_OF_MEMORY_ERROR;
argv = (char **)NPN_MemAlloc(sizeof(char *) * argc2);
if (!argv) {
NPN_MemFree(argn);
return NPERR_OUT_OF_MEMORY_ERROR;
}
memset(argn, 0, sizeof(char *) * argc2);
memset(argv, 0, sizeof(char *) * argc2);
for (i = 0; i < argc2; i++) {
char *name, *value;
name = (char *)NPN_MemAlloc(strlen(argn2[i]) + 1);
if (!name) {
FreeArgs(argn, argv, i - 1);
return NPERR_OUT_OF_MEMORY_ERROR;
}
strcpy(name, argn2[i]);
value = (char *)NPN_MemAlloc(strlen(argv2[i]) + 1);
if (!value) {
NPN_MemFree(name);
FreeArgs(argn, argv, i - 1);
return NPERR_OUT_OF_MEMORY_ERROR;
}
strcpy(value, argv2[i]);
argn[i] = name;
argv[i] = value;
}
*argc1 = argc2;
*argn1 = argn;
*argv1 = argv;
return NPERR_NO_ERROR;
}
char*
NPP_GetMIMEDescription(void)
{
return(PLUGIN_MIME_DESCRIPTION);
}
NPError
NPP_GetValue(void *future, NPPVariable variable, void *value)
{
NPError err = NPERR_NO_ERROR;
switch (variable) {
case NPPVpluginNameString:
*((char **)value) = PLUGIN_NAME;
break;
case NPPVpluginDescriptionString:
*((char **)value) = PLUGIN_DESCRIPTION;
break;
default:
err = NPERR_GENERIC_ERROR;
}
return err;
}
jref
NPP_GetJavaClass()
{
return NULL;
}
NPError
NPP_New(NPMIMEType pluginType,
NPP instance,
uint16 mode,
int16 argc,
char* argn[],
char* argv[],
NPSavedData* saved)
{
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
This = (PluginInstance*) instance->pdata;
if (This == NULL)
return NPERR_OUT_OF_MEMORY_ERROR;
This->instance = instance;
if (argc != 0) {
if (CopyArgs(&This->argn, &This->argv, &This->argc,
argn, argv, argc) == NPERR_OUT_OF_MEMORY_ERROR) {
NPN_MemFree(This);
return NPERR_OUT_OF_MEMORY_ERROR;
}
} else {
This->argc = 0;
This->argn = This->argv = NULL;
}
This->parse_reply = 0;
This->status = 0;
This->dont_reparent = RxUndef;
This->state = LOADING;
This->status_widget = NULL;
This->plugin_widget = NULL;
RxpNew(This);
return NPERR_NO_ERROR;
}
NPError
NPP_Destroy(NPP instance, NPSavedData** save)
{
PluginInstance* This;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
if (This != NULL) {
RxpDestroy(This);
if (This->argc != 0)
FreeArgs(This->argn, This->argv, This->argc);
if (This->query != NULL)
NPN_MemFree(This->query);
NPN_MemFree(instance->pdata);
instance->pdata = NULL;
}
return NPERR_NO_ERROR;
}
typedef struct {
char *buf;
uint32 size;
} RxStreamBuf;
NPError
NPP_NewStream(NPP instance,
NPMIMEType type,
NPStream *stream,
NPBool seekable,
uint16 *stype)
{
PluginInstance* This;
RxStreamBuf *streambuf;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
if (This->parse_reply != 0)
return NPERR_NO_ERROR;
streambuf = (RxStreamBuf *) NPN_MemAlloc(sizeof(RxStreamBuf));
if (streambuf == NULL)
return NPERR_OUT_OF_MEMORY_ERROR;
streambuf->buf = NULL;
streambuf->size = 0;
stream->pdata = (void *) streambuf;
return NPERR_NO_ERROR;
}
int32 STREAMBUFSIZE = 0X0FFFFFFF;
int32
NPP_WriteReady(NPP instance, NPStream *stream)
{
PluginInstance* This;
if (instance != NULL)
This = (PluginInstance*) instance->pdata;
return STREAMBUFSIZE;
}
int32
NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buf)
{
PluginInstance* This;
if (instance == NULL)
return len;
This = (PluginInstance*) instance->pdata;
if (This->parse_reply == 0) {
RxStreamBuf *streambuf = (RxStreamBuf *) stream->pdata;
uint32 size = streambuf->size;
char *cbuf;
if (size == 0)
size++;
size += len;
cbuf = (char *) NPN_MemAlloc(size);
if (cbuf == NULL)
return -1;
if (streambuf->size != 0) {
memcpy(cbuf, streambuf->buf, streambuf->size - 1);
memcpy(cbuf + streambuf->size - 1, ((char *)buf), len);
NPN_MemFree((void *) streambuf->buf);
} else
memcpy(cbuf, ((char *)buf), len);
cbuf[size - 1] = '\0';
streambuf->buf = cbuf;
streambuf->size = size;
#ifdef PLUGIN_TRACE
fprintf(stderr, "write %s:\n", PLUGIN_NAME);
fwrite(buf, len, 1, stderr);
fprintf(stderr, "\n");
#endif
} else {
int l = len;
if (This->parse_reply == 1) {
char *ptr = strchr(buf, '\n');
if (ptr != NULL && isdigit(((char *)buf)[0])) {
This->status = (short) atoi((char *)buf);
l -= ptr - (char *)buf + 1;
buf = ptr + 1;
if (This->status != 0) {
fprintf(stderr,
"%s: Application failed to start properly\n",
PLUGIN_NAME);
}
}
This->parse_reply = 2;
}
fwrite(buf, l, 1, stderr);
}
return len;
}
void
StartApplication(PluginInstance* This)
{
NPError err;
#ifndef NO_STARTING_STATE
RxpSetStatusWidget(This, STARTING);
#else
RxpSetStatusWidget(This, RUNNING);
#endif
err = NPN_GetURL(This->instance, This->query, NULL);
This->parse_reply = 1;
}
void
StartCB(Widget widget, XtPointer client_data, XtPointer call_data)
{
PluginInstance* This = (PluginInstance*) client_data;
#if 0
XtUnmapWidget(widget);
#endif
XtDestroyWidget(widget);
StartApplication(This);
}
#if defined(linux) || (defined(sun) && !defined(SVR4))
static WidgetClass xmLabelGadgetClass;
static WidgetClass xmPushButtonGadgetClass;
#else
extern WidgetClass xmLabelGadgetClass;
extern WidgetClass xmPushButtonGadgetClass;
#endif
void
RxpSetStatusWidget(PluginInstance* This, PluginState state)
{
Arg args[5];
int n;
XrmDatabase db;
char* return_type;
XrmValue return_value;
if (This->status_widget) {
XtDestroyWidget(This->status_widget);
This->status_widget = NULL;
}
if (This->plugin_widget == NULL)
return;
db = XtDatabase (XtDisplay (This->plugin_widget));
if (!XrmGetResource (db, "RxPlugin_BeenHere", "RxPlugin_BeenHere",
&return_type, &return_value)) {
XrmPutStringResource (&db, "*Rx_Loading.labelString", "Loading...");
XrmPutStringResource (&db, "*Rx_Starting.labelString", "Starting...");
XrmPutStringResource (&db, "*Rx_Start.labelString", "Start");
XrmPutStringResource (&db, "RxPlugin_BeenHere", "YES");
}
#if defined(linux) || (defined(sun) && !defined(SVR4))
if (xmLabelGadgetClass == NULL) {
Widget w;
w = XtNameToWidget (This->toplevel_widget, "*topLeftArea.urlLabel");
if (w == NULL)
w = XtNameToWidget (This->toplevel_widget, "*urlBar.urlLocationLabel");
xmLabelGadgetClass = XtClass (w);
w = XtNameToWidget (This->toplevel_widget, "*toolBar.abort");
if (w == NULL)
w = XtNameToWidget (This->toplevel_widget, "*PopupMenu.openCustomUrl");
xmPushButtonGadgetClass = XtClass (w);
}
#endif
n = 0;
XtSetArg(args[n], "shadowThickness", 1); n++;
XtSetArg(args[n], XtNwidth, This->width); n++;
XtSetArg(args[n], XtNheight, This->height); n++;
if (state == LOADING) {
This->status_widget =
XtCreateManagedWidget("Rx_Loading", xmLabelGadgetClass,
This->plugin_widget, args, n);
#ifndef NO_STARTING_STATE
} else if (state == STARTING) {
This->status_widget =
XtCreateManagedWidget("Rx_Starting", xmLabelGadgetClass,
This->plugin_widget, args, n);
#endif
} else if (state == WAITING) {
This->status_widget =
XtCreateManagedWidget("Rx_Start", xmPushButtonGadgetClass,
This->plugin_widget, args, n);
XtAddCallback(This->status_widget, "activateCallback", StartCB, This);
} else if (state == RUNNING) {
}
This->state = state;
}
NPError
NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
{
PluginInstance* This;
RxStreamBuf *streambuf = (RxStreamBuf *) stream->pdata;
char **rx_argn, **rx_argv;
int rx_argc;
RxParams params;
RxReturnParams return_params;
NPError status = NPERR_NO_ERROR;
if (instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
This = (PluginInstance*) instance->pdata;
if (This->parse_reply != 0) {
fflush(stderr);
if (This->status != 0)
RxpSetStatusWidget(This, WAITING);
return NPRES_DONE;
}
memset(¶ms, 0, sizeof(RxParams));
memset(&return_params, 0, sizeof(RxReturnParams));
rx_argc = 0;
if (reason != NPRES_DONE) {
status = NPERR_GENERIC_ERROR;
goto exit;
}
if (RxReadParams(streambuf->buf, &rx_argn, &rx_argv, &rx_argc) != 0) {
fprintf(stderr, "%s: invalid file %s\n", PLUGIN_NAME, stream->url);
status = NPERR_GENERIC_ERROR;
goto exit;
}
RxInitializeParams(¶ms);
if (RxParseParams(rx_argn, rx_argv, rx_argc, ¶ms, 0) != 0) {
fprintf(stderr, "%s: invalid RX params\n", PLUGIN_NAME);
status = NPERR_GENERIC_ERROR;
goto exit;
}
if (RxParseParams(This->argn, This->argv, This->argc, ¶ms, 0) != 0) {
fprintf(stderr, "%s: invalid HTML params\n", PLUGIN_NAME);
status = NPERR_GENERIC_ERROR;
goto exit;
}
if (RxpProcessParams(This, ¶ms, &return_params) != 0) {
fprintf(stderr, "%s: failed to process params\n", PLUGIN_NAME);
status = NPERR_GENERIC_ERROR;
goto exit;
}
This->query = RxBuildRequest(&return_params);
if (This->query == NULL) {
fprintf(stderr, "%s: failed to make query\n", PLUGIN_NAME);
status = NPERR_GENERIC_ERROR;
goto exit;
}
if (params.auto_start != RxFalse)
StartApplication(This);
else
RxpSetStatusWidget(This, WAITING);
exit:
FreeArgs(rx_argn, rx_argv, rx_argc);
FreeArgs(This->argn, This->argv, This->argc);
This->argc = 0;
RxFreeParams(¶ms);
RxFreeReturnParams(&return_params);
if (streambuf->buf != NULL)
NPN_MemFree(streambuf->buf);
NPN_MemFree(stream->pdata);
return status;
}
void
NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
{
}
void
NPP_Print(NPP instance, NPPrint* printInfo)
{
if(printInfo == NULL)
return;
if (instance != NULL) {
#if 0
PluginInstance* This = (PluginInstance*) instance->pdata;
#endif
if (printInfo->mode == NP_FULL) {
printInfo->print.fullPrint.pluginPrinted = FALSE;
}
#if 0
else {
NPWindow* printWindow =
&(printInfo->print.embedPrint.window);
void* platformPrint =
printInfo->print.embedPrint.platformPrint;
}
#endif
}
}