home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / plugins / textplugin / npshell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  13.9 KB  |  511 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /*
  19.  * npshell.c
  20.  *
  21.  * Netscape Client Plugin API
  22.  * - Function that need to be implemented by plugin developers
  23.  *
  24.  * This file defines a "shell" plugin that plugin developers can use
  25.  * as the basis for a real plugin.  This shell just provides empty
  26.  * implementations of all functions that the plugin can implement
  27.  * that will be called by Netscape (the NPP_xxx methods defined in 
  28.  * npapi.h). 
  29.  *
  30.  * Example usage of this plugin is:
  31.  * <EMBED SRC="a.txt" WIDTH=100 HEIGHT=100>
  32.  *    Other attributes specific to the TEXT_PLUGIN are
  33.  * MODE=AsFile
  34.  * MODE=AsFileOnly
  35.  *    This will work in StreamAsFile mode and print the name of the file.
  36.  * MODE=Seek
  37.  *    This will work in seek mode on seekable streames and display
  38.  *    20 bytes from the 10th byte.
  39.  * NODATA
  40.  *    This will make the plugin take no data. WriteReady will always return
  41.  *    0.
  42.  * The above modes are provided for test purposes.
  43.  *
  44.  * dp Suresh <dp@netscape.com>
  45.  *
  46.  *----------------------------------------------------------------------
  47.  * PLUGIN DEVELOPERS:
  48.  *    Implement your plugins here.
  49.  *    A sample text plugin is implemented here.
  50.  *    All the sample plugin does is displays any file with a
  51.  *    ".txt" extension in a scrolled text window. It uses Motif.
  52.  *----------------------------------------------------------------------
  53.  */
  54.  
  55. #include <stdio.h>
  56. #include "npapi.h"
  57.  
  58. #ifdef TEXT_PLUGIN
  59. #include <Xm/Xm.h>
  60. #include <Xm/Form.h>
  61. #include <Xm/Text.h>
  62. #endif /* TEXT_PLUGIN */
  63.  
  64. /***********************************************************************
  65.  * Instance state information about the plugin.
  66.  *
  67.  * PLUGIN DEVELOPERS:
  68.  *    Use this struct to hold per-instance information that you'll
  69.  *    need in the various functions in this file.
  70.  ***********************************************************************/
  71.  
  72. typedef struct _PluginInstance
  73. {
  74.     uint16 mode;
  75.     Window window;
  76.     Display *display;
  77.     uint32 x, y;
  78.     uint32 width, height;
  79.  
  80.     uint16 opmode;        /* Reflects the MODE attribute in the embed */
  81.     NPBool nodata;        /* Does not accept data */
  82. #ifdef TEXT_PLUGIN
  83.     Widget form;        /* Form container widget */
  84.     Widget text;        /* Text widget */
  85. #endif /* TEXT_PLUGIN */
  86. } PluginInstance;
  87.  
  88.  
  89. /***********************************************************************
  90.  *
  91.  * Empty implementations of plugin API functions
  92.  *
  93.  * PLUGIN DEVELOPERS:
  94.  *    You will need to implement these functions as required by your
  95.  *    plugin.
  96.  *
  97.  ***********************************************************************/
  98.  
  99. char*
  100. NPP_GetMIMEDescription(void)
  101. {
  102. #ifdef TEXT_PLUGIN
  103.     /* The registering of this plugin for text/postscript also is
  104.      * more intended towards showing how to register a plugin for
  105.      * multiple mime/types.
  106.      */
  107.     return("text/plain:txt,text:Plain text;text/postscript:ps:Postscript");
  108. #else
  109.     return("text/plain:txt,text:Plain text;text/postscript:ps:Postscript");
  110. #endif
  111. }
  112.  
  113. NPError
  114. NPP_GetValue(void *future, NPPVariable variable, void *value)
  115. {
  116.     NPError err = NPERR_NO_ERROR;
  117.  
  118.     switch (variable) {
  119.         case NPPVpluginNameString:
  120.             *((char **)value) = "Sample Text plugin";
  121.             break;
  122.         case NPPVpluginDescriptionString:
  123.             *((char **)value) =
  124.                 "This plugins handles text files and displays "
  125.                 "them in a scrolled window.";
  126.             break;
  127.         default:
  128.             err = NPERR_GENERIC_ERROR;
  129.     }
  130.     return err;
  131. }
  132.  
  133. NPError
  134. NPP_Initialize(void)
  135. {
  136.     return NPERR_NO_ERROR;
  137. }
  138.  
  139.  
  140. jref
  141. NPP_GetJavaClass()
  142. {
  143.     return NULL;
  144. }
  145.  
  146. void
  147. NPP_Shutdown(void)
  148. {
  149. }
  150.  
  151.  
  152. NPError 
  153. NPP_New(NPMIMEType pluginType,
  154.     NPP instance,
  155.     uint16 mode,
  156.     int16 argc,
  157.     char* argn[],
  158.     char* argv[],
  159.     NPSavedData* saved)
  160. {
  161.         PluginInstance* This;
  162.  
  163.     if (instance == NULL)
  164.         return NPERR_INVALID_INSTANCE_ERROR;
  165.         
  166.     instance->pdata = NPN_MemAlloc(sizeof(PluginInstance));
  167.     
  168.     This = (PluginInstance*) instance->pdata;
  169.  
  170.     if (This != NULL)
  171.     {
  172.         /* mode is NP_EMBED, NP_FULL, or NP_BACKGROUND (see npapi.h) */
  173.         This->mode = mode;
  174.         This->window = (Window) 0;
  175.         This->opmode = NP_NORMAL;
  176.         This->nodata = FALSE;
  177. #ifdef TEXT_PLUGIN
  178.         This->form = 0;
  179.         This->text = 0;
  180. #endif /* TEXT_PLUGIN */
  181.         while (argc > 0) {
  182.             if (!strcasecmp(argn[argc-1], "MODE") && argv[argc-1]) {
  183.                  if (!strcasecmp(argv[argc-1], "seek"))
  184.                     This->opmode = NP_SEEK;
  185.                  if (!strcasecmp(argv[argc-1], "asfile"))
  186.                     This->opmode = NP_ASFILE;
  187.                  if (!strcasecmp(argv[argc-1], "asfileonly"))
  188.                     This->opmode = NP_ASFILEONLY;
  189.             }
  190.             else if (!strcasecmp(argn[argc-1], "NODATA"))
  191.                 This->nodata = TRUE;
  192.             argc --;
  193.         }
  194.  
  195.         /* PLUGIN DEVELOPERS:
  196.          *    Initialize fields of your plugin
  197.          *    instance data here.  If the NPSavedData is non-
  198.          *    NULL, you can use that data (returned by you from
  199.          *    NPP_Destroy to set up the new plugin instance).
  200.          */
  201.         
  202.         return NPERR_NO_ERROR;
  203.     }
  204.     else
  205.         return NPERR_OUT_OF_MEMORY_ERROR;
  206. }
  207.  
  208.  
  209. NPError 
  210. NPP_Destroy(NPP instance, NPSavedData** save)
  211. {
  212.     PluginInstance* This;
  213.  
  214.     if (instance == NULL)
  215.         return NPERR_INVALID_INSTANCE_ERROR;
  216.  
  217.     This = (PluginInstance*) instance->pdata;
  218.  
  219.     /* PLUGIN DEVELOPERS:
  220.      *    If desired, call NP_MemAlloc to create a
  221.      *    NPSavedDate structure containing any state information
  222.      *    that you want restored if this plugin instance is later
  223.      *    recreated.
  224.      */
  225.  
  226.     if (This != NULL) {
  227.         NPN_MemFree(instance->pdata);
  228.         instance->pdata = NULL;
  229.     }
  230.  
  231.     return NPERR_NO_ERROR;
  232. }
  233.  
  234.  
  235.  
  236. NPError 
  237. NPP_SetWindow(NPP instance, NPWindow* window)
  238. {
  239.     PluginInstance* This;
  240.  
  241.     if (instance == NULL)
  242.         return NPERR_INVALID_INSTANCE_ERROR;
  243.  
  244.     if (window == NULL)
  245.         return NPERR_NO_ERROR;
  246.  
  247.     This = (PluginInstance*) instance->pdata;
  248.  
  249.     /*
  250.      * PLUGIN DEVELOPERS:
  251.      *    Before setting window to point to the
  252.      *    new window, you may wish to compare the new window
  253.      *    info to the previous window (if any) to note window
  254.      *    size changes, etc.
  255.      */
  256.  
  257.     if (This->window == (Window) window->window) {
  258.         /* This could be the plugin changing size (or) just an
  259.          * extra SetWindow().
  260.          */
  261. #ifdef TEXT_PLUGIN
  262.         if (This->x != window->x || This->width != window->width ||
  263.             This->y != window->y || This->height != window->height) {
  264.             This->x = window->x;
  265.             This->y = window->y;
  266.             This->width = window->width;
  267.             This->height = window->height;
  268.             XtVaSetValues(This->form, XmNx, This->x, XmNy, This->y,
  269.                         XmNheight, This->height, XmNwidth, This->width, 0);
  270.         }
  271. #endif /* TEXT_PLUGIN */
  272.     }
  273.     else {
  274.         This->x = window->x;
  275.         This->y = window->y;
  276.         This->width = window->width;
  277.         This->height = window->height;
  278.         This->window = (Window) window->window;
  279.         This->display = ((NPSetWindowCallbackStruct *)window->ws_info)->display;
  280. #ifdef TEXT_PLUGIN
  281.         {
  282.             Widget netscape_widget;
  283.             Widget form;
  284.             Arg av[20];
  285.             int ac;
  286.  
  287.             netscape_widget = XtWindowToWidget(This->display, This->window);
  288.  
  289.             ac = 0;
  290.             XtSetArg(av[ac], XmNx, 0); ac++;
  291.             XtSetArg(av[ac], XmNy, 0); ac++;
  292.             XtSetArg(av[ac], XmNwidth, This->width); ac++;
  293.             XtSetArg(av[ac], XmNheight, This->height); ac++;
  294.             XtSetArg(av[ac], XmNborderWidth, 0); ac++;
  295.  
  296.             This->form = XmCreateForm(netscape_widget, "pluginForm",
  297.                     av, ac);
  298.  
  299.             ac = 0;
  300.             XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  301.             XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  302.             XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  303.             XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  304.             XtSetArg (av[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
  305.             This->text = XmCreateScrolledText (This->form, "pluginText",
  306.                                                av, ac);
  307.  
  308.             XtManageChild(This->text);
  309.             XtManageChild(This->form);
  310.         }
  311. #endif /* TEXT_PLUGIN */
  312.     }
  313.  
  314.     return NPERR_NO_ERROR;
  315. }
  316.  
  317.  
  318. NPError 
  319. NPP_NewStream(NPP instance,
  320.               NPMIMEType type,
  321.               NPStream *stream, 
  322.               NPBool seekable,
  323.               uint16 *stype)
  324. {
  325.     NPByteRange range;
  326.     PluginInstance* This;
  327.  
  328.     if (instance == NULL)
  329.         return NPERR_INVALID_INSTANCE_ERROR;
  330.  
  331.     This = (PluginInstance*) instance->pdata;
  332.  
  333.     if (seekable && This->opmode == NP_SEEK) {
  334.         *stype = NP_SEEK;
  335.         range.offset = 10;
  336.         range.length = 20;
  337.         range.next = NULL;
  338.         NPN_RequestRead(stream, &range);
  339.     }
  340.     else if (This->opmode == NP_ASFILE || This->opmode == NP_ASFILEONLY)
  341.         *stype = This->opmode;
  342.  
  343.     return NPERR_NO_ERROR;
  344. }
  345.  
  346.  
  347. /* PLUGIN DEVELOPERS:
  348.  *    These next 2 functions are directly relevant in a plug-in which
  349.  *    handles the data in a streaming manner. If you want zero bytes
  350.  *    because no buffer space is YET available, return 0. As long as
  351.  *    the stream has not been written to the plugin, Navigator will
  352.  *    continue trying to send bytes.  If the plugin doesn't want them,
  353.  *    just return some large number from NPP_WriteReady(), and
  354.  *    ignore them in NPP_Write().  For a NP_ASFILE stream, they are
  355.  *    still called but can safely be ignored using this strategy.
  356.  */
  357.  
  358. int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile
  359.                    * mode so we can take any size stream in our
  360.                    * write call (since we ignore it) */
  361.  
  362. int32 
  363. NPP_WriteReady(NPP instance, NPStream *stream)
  364. {
  365.     PluginInstance* This;
  366.     if (instance != NULL)
  367.         This = (PluginInstance*) instance->pdata;
  368.  
  369.     /* Number of bytes ready to accept in NPP_Write() */
  370.     /* If in nodata mode, return 0 */
  371.     if (This->nodata)
  372.         return 0;
  373.  
  374.     return STREAMBUFSIZE;
  375. }
  376.  
  377.  
  378. int32 
  379. NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer)
  380. {
  381.     if (instance != NULL)
  382.     {
  383.         PluginInstance* This = (PluginInstance*) instance->pdata;
  384.         char *cbuf;
  385. #ifdef TEXT_PLUGIN
  386.         XmTextPosition pos = 0;
  387. #endif /* TEXT_PLUGIN */
  388.  
  389.         /* If this was a NODATA plugin, then we should not be getting
  390.          * this write call.
  391.          */
  392.         if (This->nodata)
  393.             fprintf(stderr, "TextPlugin ERROR: Although NODATA attribute was used (NPP_WriteReady returned 0),\nwe got a NPP_Write call. Tell Netscape about this.\n");
  394.  
  395.         cbuf = (char *) NPN_MemAlloc(len + 1);
  396.         if (!cbuf) return 0;
  397.         memcpy(cbuf, (char *)buffer, len);
  398.         cbuf[len] = '\0';
  399. #ifdef TEXT_PLUGIN
  400.         if (This->text) {
  401.             XtVaGetValues(This->text, XmNcursorPosition, &pos, 0);
  402.             XmTextInsert(This->text, pos, cbuf);
  403.         }
  404.         else {
  405.             /* This must be a hidden plugin */
  406.             fprintf(stderr, "%s", cbuf);
  407.         }
  408. #else /* TEXT_PLUGIN */
  409.         fprintf(stderr, "%s", cbuf);
  410. #endif /* TEXT_PLUGIN */
  411.         NPN_MemFree(cbuf);
  412.     }
  413.  
  414.     return len;        /* The number of bytes accepted */
  415. }
  416.  
  417.  
  418. NPError 
  419. NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason)
  420. {
  421.     PluginInstance* This;
  422.  
  423.     if (instance == NULL)
  424.         return NPERR_INVALID_INSTANCE_ERROR;
  425.     This = (PluginInstance*) instance->pdata;
  426.  
  427.     return NPERR_NO_ERROR;
  428. }
  429.  
  430.  
  431. void 
  432. NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname)
  433. {
  434.     PluginInstance* This;
  435.     if (instance != NULL)
  436.         This = (PluginInstance*) instance->pdata;
  437. #ifdef TEXT_PLUGIN
  438.     fprintf(stderr, "Got NPP_StreamAsFile: %s.\n",
  439.             (fname == NULL)?"null":fname);
  440. #endif /* TEXT_PLUGIN */
  441. }
  442.  
  443.  
  444. void 
  445. NPP_Print(NPP instance, NPPrint* printInfo)
  446. {
  447.     if(printInfo == NULL)
  448.         return;
  449.  
  450.     if (instance != NULL) {
  451.         PluginInstance* This = (PluginInstance*) instance->pdata;
  452.     
  453.         if (printInfo->mode == NP_FULL) {
  454.             /*
  455.              * PLUGIN DEVELOPERS:
  456.              *    If your plugin would like to take over
  457.              *    printing completely when it is in full-screen mode,
  458.              *    set printInfo->pluginPrinted to TRUE and print your
  459.              *    plugin as you see fit.  If your plugin wants Netscape
  460.              *    to handle printing in this case, set
  461.              *    printInfo->pluginPrinted to FALSE (the default) and
  462.              *    do nothing.  If you do want to handle printing
  463.              *    yourself, printOne is true if the print button
  464.              *    (as opposed to the print menu) was clicked.
  465.              *    On the Macintosh, platformPrint is a THPrint; on
  466.              *    Windows, platformPrint is a structure
  467.              *    (defined in npapi.h) containing the printer name, port,
  468.              *    etc.
  469.              */
  470.  
  471.             void* platformPrint =
  472.                 printInfo->print.fullPrint.platformPrint;
  473.             NPBool printOne =
  474.                 printInfo->print.fullPrint.printOne;
  475.  
  476. #ifdef TEXT_PLUGIN
  477.             fprintf(stderr, "NPP_Print: FullPage print. platformPrint=%x, printOne=%s\n",
  478.                   platformPrint, printOne ? "True":"False");
  479. #endif /* TEXT_PLUGIN */
  480.             
  481.             /* Do the default*/
  482.             printInfo->print.fullPrint.pluginPrinted = FALSE;
  483.         }
  484.         else {    /* If not fullscreen, we must be embedded */
  485.             /*
  486.              * PLUGIN DEVELOPERS:
  487.              *    If your plugin is embedded, or is full-screen
  488.              *    but you returned false in pluginPrinted above, NPP_Print
  489.              *    will be called with mode == NP_EMBED.  The NPWindow
  490.              *    in the printInfo gives the location and dimensions of
  491.              *    the embedded plugin on the printed page.  On the
  492.              *    Macintosh, platformPrint is the printer port; on
  493.              *    Windows, platformPrint is the handle to the printing
  494.              *    device context.
  495.              */
  496.  
  497.             NPWindow* printWindow =
  498.                 &(printInfo->print.embedPrint.window);
  499.             void* platformPrint =
  500.                 printInfo->print.embedPrint.platformPrint;
  501. #ifdef TEXT_PLUGIN
  502.             fprintf(stderr, "NPP_Print: EmbedPage print. platformPrint=%x,\n",
  503.                   platformPrint);
  504.             fprintf(stderr, "         : window(%d) : (%d, %d) [%d x %d]\n",
  505.                     printWindow->window, printWindow->x, printWindow->y,
  506.                     printWindow->width, printWindow->height);
  507. #endif /* TEXT_PLUGIN */
  508.         }
  509.     }
  510. }
  511.