/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ /* * nullplugin.c * * Implementation of the null plugins for Unix. * * dp * updated 5/1998 * */ #include #include #include #include #include "npapi.h" #include "nullplugin.h" /* Global data */ MimeTypeElement *head = NULL; static void UnmanageChild_safe (Widget w) { if (w) XtUnmanageChild (w); } static void nullPlugin_cb(Widget widget, XtPointer closure, XtPointer call_data) { XmAnyCallbackStruct *cb = (XmAnyCallbackStruct *) call_data; PluginInstance* This = (PluginInstance*) closure; char *url; switch (cb->reason) { case XmCR_OK: XtDestroyWidget(This->dialog); This->dialog = NULL; /* Don't reuse deleted dialog */ if (This->pluginsFileUrl != NULL) { /* Get the JavaScript command string */ char* buf = "javascript:netscape.softupdate.Trigger.StartSoftwareUpdate(\"%s\")"; url = NPN_MemAlloc(strlen(This->pluginsFileUrl) + 1 + strlen(buf) + 1); if (url != NULL) { /* Insert the file URL into the JavaScript command */ sprintf(url, buf, This->pluginsFileUrl); NPN_GetURL(This->instance, url, TARGET); NPN_MemFree(url); } } else { /* If necessary, get the default plug-ins page resource */ char* address = This->pluginsPageUrl; if (address == NULL) { address = PLUGINSPAGE_URL; } url = NPN_MemAlloc(strlen(address) + 1 + strlen(This->type) + 1); if (url != NULL) { /* Append the MIME type to the URL */ sprintf(url, "%s?%s", address, This->type); NPN_GetURL(This->instance, url, TARGET); NPN_MemFree(url); } /* Update the button label and callbacks */ setAction(This, REFRESH); } break; case XmCR_CANCEL: XtDestroyWidget(This->dialog); This->dialog = NULL; /* Don't reuse deleted dialog */ break; } } void refreshPluginList(Widget widget, XtPointer closure, XtPointer call_data) { PluginInstance* This = (PluginInstance*) closure; if (!This) return; This->refreshing = TRUE; NPN_ReloadPlugins(TRUE); /* * NPN_GetURL(This->instance, REFRESH_PLUGIN_LIST, "_self"); */ } void showPluginDialog(Widget widget, XtPointer closure, XtPointer call_data) { PluginInstance* This = (PluginInstance*) closure; Widget dialog; Arg av[20]; int ac; XmString xmstr; char message[1024]; if (!This) return; dialog = This->dialog; if (dialog) { /* The dialog is already available */ XtManageChild(dialog); XMapRaised(XtDisplay(dialog), XtWindow(dialog)); return; } /* Create the dialog */ sprintf(message, MESSAGE, This->type); xmstr = XmStringCreateLtoR(message, XmSTRING_DEFAULT_CHARSET); ac = 0; /* Copy button attributes unless hidden (no attributes) */ if (This->visual) { XtSetArg (av[ac], XmNvisual, This->visual); ac++; XtSetArg (av[ac], XmNdepth, This->depth); ac++; XtSetArg (av[ac], XmNcolormap, This->colormap); ac++; } XtSetArg (av[ac], XmNallowShellResize, TRUE); ac++; XtSetArg (av[ac], XmNdialogStyle, XmDIALOG_MODELESS); ac++; XtSetArg (av[ac], XmNdialogType, XmDIALOG_QUESTION); ac++; XtSetArg (av[ac], XmNdeleteResponse, XmUNMAP); ac++; XtSetArg (av[ac], XmNautoUnmanage, False); ac++; XtSetArg (av[ac], XmNmessageString, xmstr); ac++; if (!widget) { widget = FE_GetToplevelWidget(); } if (!widget) return; /* This should never happen! */ dialog = XmCreateMessageDialog(widget, "nullpluginDialog", av, ac); UnmanageChild_safe (XmMessageBoxGetChild (dialog, XmDIALOG_HELP_BUTTON)); XtAddCallback(dialog, XmNokCallback, nullPlugin_cb, This); XtAddCallback(dialog, XmNcancelCallback, nullPlugin_cb, This); XmStringFree(xmstr); This->dialog = dialog; XtManageChild(dialog); } /* Create the X-Motif button widget */ void makeWidget(PluginInstance *This) { Widget netscape_widget; Widget form; Arg av[20]; int ac; if (!This) return; netscape_widget = XtWindowToWidget(This->display, This->window); ac = 0; XtSetArg(av[ac], XmNx, 0); ac++; XtSetArg(av[ac], XmNy, 0); ac++; XtSetArg(av[ac], XmNwidth, This->width); ac++; XtSetArg(av[ac], XmNheight, This->height); ac++; XtSetArg(av[ac], XmNborderWidth, 0); ac++; XtSetArg(av[ac], XmNnoResize, True); ac++; form = XmCreateForm(netscape_widget, "pluginForm", av, ac); ac = 0; XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++; XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++; XtSetArg (av[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++; /* XtSetArg (av[ac], XmNlabelString, xmstr); ac++; */ This->button = XmCreatePushButton (form, "pluginButton", av, ac); if (!This->action) This->action = GET; setAction(This, This->action); XtManageChild(This->button); XtManageChild(form); /* Popup the pluginDialog if this is the first time * * we encounter this MimeType */ if (addToList(&head, This->type)) showPluginDialog(This->button, (XtPointer) This, NULL); } /* Update the button label and callbacks (unless hidden) */ void setAction(PluginInstance *This, int action) { int ac; Arg av[20]; XmString xmstr; if (!This) return; This->action = action; if (action == GET) This->message = CLICK_TO_GET; else if (action == REFRESH) This->message = CLICK_WHEN_DONE; if (!This->button) return; xmstr = XmStringCreateLtoR(This->message, XmSTRING_DEFAULT_CHARSET); /* Update the message on the button */ ac = 0; XtSetArg (av[ac], XmNlabelString, xmstr); ac++; XtSetValues(This->button, av, ac); /* Restore the original size of the button * * NOTE: This MUST be done in a separate call * * after the message change or else it will * * not work. Also, note that width/height is * * is used only because XmNXXXAtachment * * parameters do not work */ ac = 0; XtSetArg(av[ac], XmNheight, This->height); ac++; XtSetArg(av[ac], XmNwidth, This->width); ac++; XtSetValues(This->button, av, ac); if (action == GET) { if (This->exists) XtRemoveCallback (This->button, XmNactivateCallback, refreshPluginList, (XtPointer)This); XtAddCallback (This->button, XmNactivateCallback, showPluginDialog, (XtPointer)This); } else if (action == REFRESH) { if (This->exists) XtRemoveCallback (This->button, XmNactivateCallback, showPluginDialog, (XtPointer)This); XtAddCallback (This->button, XmNactivateCallback, refreshPluginList, (XtPointer)This); } if (!This->exists) { XtAddEventHandler (This->button, EnterWindowMask, False, (XtEventHandler)showStatus, (XtPointer)This); XtAddEventHandler (This->button, LeaveWindowMask, False, (XtEventHandler)clearStatus, (XtPointer)This); This->exists = TRUE; } XmStringFree(xmstr); } void showStatus(Widget widget, XtPointer closure, XtPointer call_data) { PluginInstance *This = (PluginInstance *) closure; if (!This) return; if (!This->instance) return; NPN_Status(This->instance, This->message); } void clearStatus(Widget widget, XtPointer closure, XtPointer call_data) { PluginInstance *This = (PluginInstance *) closure; if (!This) return; if (!This->instance) return; NPN_Status(This->instance, ""); } /* MIMETypeList maintenance routines */ static Boolean isEqual(NPMIMEType t1, NPMIMEType t2) { return(strcmp(t1, t2) == 0); } static Boolean isExist(MimeTypeElement **typelist, NPMIMEType type) { MimeTypeElement *ele; if (typelist == NULL) return False; ele = *typelist; while (ele != NULL) { if (isEqual(ele->value, type)) return True; ele = ele->next; } return False; } NPMIMEType dupMimeType(NPMIMEType type) { NPMIMEType mimetype = NPN_MemAlloc(strlen(type)+1); if (mimetype) strcpy(mimetype, type); return(mimetype); } int addToList(MimeTypeElement **typelist, NPMIMEType type) { MimeTypeElement *ele; if (!typelist) return(0); if (isExist(typelist, type)) return(0); ele = (MimeTypeElement *) NPN_MemAlloc(sizeof(MimeTypeElement)); ele->value = dupMimeType(type); ele->next = *typelist; *typelist = ele; return(1); }