home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / libfont / src / wffpPeer.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  19.9 KB  |  1,000 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.  * wffppeer.cpp (FontDisplayerPeerObject.cpp)
  20.  *
  21.  * This object is local to the FontDisplayer. One of these objects
  22.  * exist for every FontDisplayer that exists. All calls to the FontDisplayer
  23.  * are routed through this peer object. This takes care of loading and
  24.  * unloading the FontDisplayers as neccessary.
  25.  *
  26.  * dp Suresh <dp@netscape.com>
  27.  */
  28.  
  29.  
  30. #include "wffpPeer.h"
  31.  
  32. #include "fe_proto.h"
  33. #define WF_ONE_MILLESEC 1
  34. #define WF_ONE_MINUTE (60 * 1000 * WF_ONE_MILLESEC)
  35.  
  36. /* Getting intl string ids */
  37. #define WANT_ENUM_STRING_IDS
  38. #include "allxpstr.h"
  39. #undef WANT_ENUM_STRING_IDS
  40.  
  41. FontDisplayerPeerObject::
  42. FontDisplayerPeerObject(struct nffp *fp)
  43.     : dlm(NULL), deleted(0), disabled(0), native(-1),
  44.       streamCount(0), fhList(NULL), unloadTimerId(NULL)
  45. {
  46.     XP_ASSERT(fp);
  47.     fpType = FontDisplayerPeerObject::WF_FP_STATIC;
  48.  
  49.     fontDisplayer = fp;
  50.  
  51.     // Although there we aren't expected to free the returned
  52.     // Name and Description, we could unload this dynamic modules
  53.     // and the name and decription could be in their data space.
  54.     // So to prevent losing these, we take a copy.
  55.     displayerName = CopyString(nffp_Name(fontDisplayer, NULL));
  56.     displayerDescription = CopyString(nffp_Description(fontDisplayer, NULL));
  57.     
  58. #if defined(XP_WIN) && !defined(WIN32)
  59.     // Win16 It seems the const char * assignment doesn't work.
  60.     char mimeString[256];
  61.     *mimeString = '\0';
  62.     strcpy(mimeString, nffp_EnumerateMimeTypes(fontDisplayer, NULL));
  63. #else
  64.     const char *mimeString = nffp_EnumerateMimeTypes(fontDisplayer, NULL);
  65. #endif
  66.     if (mimeString && *mimeString )
  67.     {
  68.         mimeList.reconstruct(mimeString);
  69.         registerConverters();
  70.     }
  71. }
  72.  
  73.  
  74. FontDisplayerPeerObject::
  75. FontDisplayerPeerObject(const char *dlmName)
  76.     : dlm(dlmName), mimeList(NULL), deleted(0), disabled(0), native(-1),
  77.       streamCount(0), fhList(NULL), unloadTimerId(NULL)
  78. {
  79.     fpType = FontDisplayerPeerObject::WF_FP_DYNAMIC;
  80.  
  81.     fontDisplayer = NULL;
  82.     displayerName = NULL;
  83.     displayerDescription = NULL;
  84.  
  85.     if (dlm.status() < 0)
  86.     {
  87.         deleted = 1;
  88.         return;
  89.     }
  90.  
  91. #ifdef DEBUG
  92.     // Don't load in purified versions of libraries.
  93.     if(XP_STRSTR(dlmName, "_pure_")) {
  94.         XP_ASSERT(0);
  95.         deleted = 1;
  96.         return;
  97.     }
  98. #endif
  99.  
  100.     if (load() < 0)
  101.     {
  102.         deleted = 1;
  103.         return;
  104.     }
  105.     displayerName = CopyString(nffp_Name(fontDisplayer, NULL));
  106.     displayerDescription = CopyString(nffp_Description(fontDisplayer,NULL));
  107.     
  108. #if defined(XP_WIN) && !defined(WIN32)
  109.     // Win16 It seems the const char * assignment doesn't work.
  110.     char mimeString[256];
  111.     *mimeString = '\0';
  112.     strcpy(mimeString, nffp_EnumerateMimeTypes(fontDisplayer, NULL));
  113. #else
  114.     const char *mimeString = nffp_EnumerateMimeTypes(fontDisplayer, NULL);
  115. #endif
  116.     if (mimeString && *mimeString )
  117.     {
  118.         mimeList.reconstruct(mimeString);
  119.         registerConverters();
  120.     }
  121. }
  122.  
  123. FontDisplayerPeerObject::
  124. FontDisplayerPeerObject(FontCatalogFile &fc)
  125.     : dlm(NULL), deleted(0), disabled(0), native(-1),
  126.       streamCount(0), fhList(NULL), unloadTimerId(NULL)
  127. {
  128.     fpType = FontDisplayerPeerObject::WF_FP_DYNAMIC;
  129.     fontDisplayer = NULL;
  130.     displayerName = NULL;
  131.     displayerDescription = NULL;
  132.  
  133.     reconstruct(fc);
  134. }
  135.  
  136.  
  137. FontDisplayerPeerObject::
  138. ~FontDisplayerPeerObject()
  139. {
  140.     finalize();
  141. }
  142.  
  143. jint FontDisplayerPeerObject::
  144. describe(FontCatalogFile &fc)
  145. {
  146.     char *s;
  147.     
  148.     // Print out the displayer information
  149.     
  150.     if (fpType != WF_FP_DYNAMIC)
  151.     {
  152.         return (0);
  153.     }
  154.     fc.output("displayer = {");
  155.     fc.indentIn();
  156.  
  157.     s = "dynamic";
  158.     fc.output("type", s);
  159.  
  160.     s = dlm.describe();
  161.     fc.output("dlm", s);
  162.     if (s)
  163.     {
  164.         XP_FREE(s);
  165.     }
  166.  
  167.     fc.output("name", displayerName);
  168.     fc.output("description", displayerDescription);
  169.  
  170.     s = mimeList.describe();
  171.     fc.output("mimeString", s);
  172.     if (s)
  173.     {
  174.         XP_FREE(s);
  175.     }
  176.  
  177.     fc.output("deleted", deleted);
  178.     fc.output("disabled", disabled);
  179.  
  180.     fc.output("catalog = {");
  181.     fc.indentIn();
  182.     catalog.describe(fc);
  183.     fc.indentOut();
  184.     fc.output("} // End of catalog");
  185.  
  186.     fc.indentOut();
  187.     fc.output("} // End of displayer");
  188.  
  189.     return (0);
  190. }
  191.  
  192. jint FontDisplayerPeerObject::
  193. reconstruct(FontCatalogFile &fc)
  194. {
  195.     char buf[1024];
  196.     int buflen;
  197.  
  198.     int over = 0;
  199.     char *variable = NULL;
  200.     char *value = NULL;
  201.     char *ret;
  202.  
  203.     finalize();
  204.     
  205.     while (!over)
  206.     {
  207.         ret = fc.readline(buf, sizeof(buf));
  208.         if (!ret)
  209.         {
  210.             over = 1;
  211.             continue;
  212.         }
  213.         buflen = strlen((const char *)buf);
  214.         if (buf[buflen-1] == '\n')
  215.         {
  216.             buf[buflen-1] = '\0';
  217.             buflen--;
  218.         }
  219.         if (!strncmp(buf, "#", 1))
  220.         {
  221.             // Ignore comments
  222.             continue;
  223.         }
  224.         wf_scanVariableAndValue(buf, buflen, variable, value);
  225.         if (!wf_strcasecmp(variable, "displayer"))
  226.         {
  227.             continue;
  228.         }
  229.         else if (!wf_strcasecmp(variable, "type"))
  230.         {
  231.             if (!wf_strcasecmp(value, "dynamic"))
  232.             {
  233.                 fpType = WF_FP_DYNAMIC;
  234.             }
  235.             else
  236.             {
  237.                 deleted = 1;
  238.                 over = 1;
  239.                 continue;
  240.             }
  241.         }
  242.         else if (!wf_strcasecmp(variable, "dlm"))
  243.         {
  244.             fontDisplayer = NULL;
  245.             dlm.reconstruct(value);
  246.             if (dlm.status() < 0)
  247.             {
  248.                 deleted = 1;
  249.                 over = 1;
  250.                 continue;
  251.             }
  252.         }
  253.         else if (!wf_strcasecmp(variable, "disabled"))
  254.         {
  255.             disabled = atoi(value);
  256.         }
  257.         else if (!wf_strcasecmp(variable, "name"))
  258.         {
  259.             if (displayerName) delete displayerName;
  260.             displayerName = CopyString(value);
  261.         }
  262.  
  263.         else if (!wf_strcasecmp(variable, "description"))
  264.         {
  265.             if (displayerDescription) delete displayerDescription;
  266.             displayerDescription = CopyString(value);
  267.         }
  268.         else if (!wf_strcasecmp(variable, "mimeString"))
  269.         {
  270.             mimeList.reconstruct(value);
  271.             registerConverters();
  272.         }
  273.         else if (!wf_strcasecmp(variable, "deleted"))
  274.         {
  275.             deleted = atoi(value);
  276.         }
  277.         else if (!wf_strcasecmp(variable, "catalog"))
  278.         {
  279.             catalog.reconstruct(fc);
  280.         }
  281.         else if (!strncmp(variable, "}", 1))
  282.         {
  283.             over = 1;
  284.             continue;
  285.         }
  286.     }
  287.  
  288.     // sanity check the fpp
  289.     if (dlm.filename() == NULL || dlm.status() <= 0 || fpType != WF_FP_DYNAMIC)
  290.         deleted = 1;
  291.     return (0);
  292. }
  293.  
  294.  
  295. jdouble *
  296. FontDisplayerPeerObject::EnumerateSizes(struct nfrc *rc, void *fh)
  297. {
  298.     // Check for generic preconditions
  299.     if (deleted || disabled)
  300.     {
  301.         return NULL;
  302.     }
  303.  
  304.     // Check for call specific preconditions
  305.     if (load() < 0)
  306.     {
  307.         deleted = 1;
  308.         return (NULL);
  309.     }
  310.     return((jdouble *)nffp_EnumerateSizes(fontDisplayer, rc, fh, NULL));
  311. }
  312.  
  313. struct nffmi * 
  314. FontDisplayerPeerObject::GetMatchInfo(void *fh)
  315. {
  316.     // Check for generic preconditions
  317.     if (deleted || disabled)
  318.     {
  319.         return (NULL);
  320.     }
  321.  
  322.     // Check for call specific preconditions
  323.     if (load() < 0)
  324.     {
  325.         deleted = 1;
  326.         return (NULL);
  327.     }
  328.     return(nffp_GetMatchInfo(fontDisplayer, fh, NULL));
  329. }
  330.  
  331. struct nfrf *
  332. FontDisplayerPeerObject::
  333. CreateRenderableFont(struct nfrc *rc, void *fh, jdouble pointsize)
  334. {
  335.     // Check for generic preconditions
  336.     if (deleted || disabled)
  337.     {
  338.         return (NULL);
  339.     }
  340.  
  341.     // Check for call specific preconditions
  342.     if (load() < 0)
  343.     {
  344.         deleted = 1;
  345.         return (NULL);
  346.     }
  347.     return(nffp_GetRenderableFont(fontDisplayer, rc, fh, pointsize, NULL));
  348. }
  349.  
  350. void *
  351. FontDisplayerPeerObject::LookupFont(struct nfrc *rc, struct nffmi *fmi, const char *accessor)
  352. {
  353.     // Check for generic preconditions
  354.     if (deleted || disabled)
  355.     {
  356.         return (NULL);
  357.     }
  358.  
  359.     // Check for call specific preconditions
  360.     if (load() < 0)
  361.     {
  362.         deleted = 1;
  363.         return (NULL);
  364.     }
  365.     return(nffp_LookupFont(fontDisplayer, rc, fmi, accessor, NULL));
  366. }
  367.  
  368. void *
  369. FontDisplayerPeerObject::CreateFontFromFile(struct nfrc *rc, const char *mimetype,
  370.                                            const char *filename, const char *urlOfPage)
  371. {
  372.     // Check for generic preconditions
  373.     if (deleted || disabled)
  374.     {
  375.         return (NULL);
  376.     }
  377.  
  378.     // Check for call specific preconditions
  379.     if (load() < 0)
  380.     {
  381.         deleted = 1;
  382.         return (NULL);
  383.     }
  384.     return(nffp_CreateFontFromFile(fontDisplayer, rc, mimetype, filename, urlOfPage,
  385.                                    NULL));
  386. }
  387.  
  388. struct nfstrm *
  389. FontDisplayerPeerObject::CreateFontStreamHandler(struct nfrc *rc, const char *urlOfPage)
  390. {
  391.     // Check for generic preconditions
  392.     if (deleted || disabled)
  393.     {
  394.         return (NULL);
  395.     }
  396.  
  397.     // Check for call specific preconditions
  398.     if (load() < 0)
  399.     {
  400.         deleted = 1;
  401.         return (NULL);
  402.     }
  403.     return((struct nfstrm *)
  404.             nffp_CreateFontStreamHandler(fontDisplayer, rc, urlOfPage, NULL));
  405. }
  406.  
  407.  
  408. jint
  409. FontDisplayerPeerObject::ReleaseFontHandle(void *fh)
  410. {
  411.     // Check for generic preconditions
  412.     if (deleted || disabled)
  413.     {
  414.         return (-1);
  415.     }
  416.  
  417.     // Check for call specific preconditions
  418.     if (load() < 0)
  419.     {
  420.         deleted = 1;
  421.         return (-1);
  422.     }
  423.     return(nffp_ReleaseFontHandle(fontDisplayer, fh, NULL));
  424. }
  425.  
  426. //
  427. // Catalogue routines
  428. //
  429.  
  430. struct nffmi **
  431. FontDisplayerPeerObject::ListFonts(struct nfrc *rc, struct nffmi *fmi)
  432. {
  433.     // Check for generic preconditions
  434.     if (deleted || disabled)
  435.     {
  436.         return (NULL);
  437.     }
  438.  
  439.     // Check for call specific preconditions
  440.     if (load() < 0)
  441.     {
  442.         deleted = 1;
  443.         return (NULL);
  444.     }
  445.     return((struct nffmi **)
  446.              nffp_ListFonts(fontDisplayer, rc, fmi, NULL));
  447. }
  448.  
  449. jdouble *
  450. FontDisplayerPeerObject::ListSizes(struct nfrc *rc, struct nffmi *fmi)
  451. {
  452.     // Check for generic preconditions
  453.     if (deleted || disabled)
  454.     {
  455.         return (NULL);
  456.     }
  457.  
  458.     // Check for call specific preconditions
  459.     if (load() < 0)
  460.     {
  461.         deleted = 1;
  462.         return (NULL);
  463.     }
  464.     return((jdouble *)
  465.              nffp_ListSizes(fontDisplayer, rc, fmi, NULL));
  466. }
  467.  
  468. int
  469. FontDisplayerPeerObject::queryCatalog(struct nfrc *rc, struct nffmi *fmi)
  470. {
  471.     int ret = catalog.supportsFmi(rc, fmi);
  472.  
  473.     if (ret < 0)
  474.     {
  475.         // Catalog may not have been initialized.
  476.         if (!catalog.isInitialized(rc))
  477.         {
  478.             // Now we need to load the dll to initialize the catalog.
  479.             struct nffmi **fmis = ListFonts(rc, NULL);
  480.             catalog.update(rc, fmis);
  481.             
  482.             if (fmis)
  483.             {
  484.                 // XXX We need to free the fmis. We may get away
  485.                 // XXX doing that if we make catalog.update() not
  486.                 // XXX take a copy of the fmi.
  487.                 wf_releaseFmis(fmis);
  488.                 WF_FREE(fmis);
  489.             }
  490.             ret = catalog.supportsFmi(rc, fmi);
  491.         }
  492.     }
  493.     return (ret);
  494. }
  495.  
  496.  
  497. //
  498. // Displayer loading/unloading management routines
  499. //
  500. int
  501. FontDisplayerPeerObject::dlmChanged(const char *dlm_name)
  502. {
  503.     int ret = -1;
  504.     // if this is the dlm that we are associcated with
  505.     if (!strcmp(dlm.filename(), dlm_name))
  506.     {
  507.         if (dlm.isChanged() == 0)
  508.         {
  509.             // Unchanged
  510.             ret = 0;
  511.         }
  512.         else
  513.         {
  514.             // This mean the dlm has either changed or may have been deleted.
  515.             ret = 1;
  516.         }
  517.     }
  518.  
  519.     return (ret);
  520. }
  521.  
  522. void
  523. FontDisplayerPeerObject::resync(void)
  524. {
  525.     native = -1;
  526.  
  527.     finalizeExceptDlmAndDisabled();
  528.  
  529.     // This might cause a core dump as usually a resync() is done only
  530.     // when we know that the dlm has changed. And if it was loaded in
  531.     // memory and the disk copy was changed whew!
  532.     // Some platforms wont let the copy on disk to change. So we are kind of
  533.     // safe.
  534.     //
  535.     // XXX A better solution would be to not unload it at all but just clear our
  536.     // internal state. Let us see.
  537.     dlm.unload(/*force*/ 1);
  538.  
  539.     dlm.sync();
  540.  
  541.     if (dlm.status() < 0)
  542.     {
  543.         deleted = 1;
  544.         return;
  545.     }
  546.     if (load() < 0)
  547.     {
  548.         deleted = 1;
  549.         return;
  550.     }
  551.     displayerName = CopyString(nffp_Name(fontDisplayer, NULL));
  552.     displayerDescription = CopyString(nffp_Description(fontDisplayer,NULL));
  553.     
  554. #if defined(XP_WIN) && !defined(WIN32)
  555.     // Win16 It seems the const char * assignment doesn't work.
  556.     char mimeString[256];
  557.     *mimeString = '\0';
  558.     strcpy(mimeString, nffp_EnumerateMimeTypes(fontDisplayer, NULL));
  559. #else
  560.     const char *mimeString = nffp_EnumerateMimeTypes(fontDisplayer, NULL);
  561. #endif
  562.     if (mimeString && *mimeString )
  563.     {
  564.         mimeList.reconstruct(mimeString);
  565.         registerConverters();
  566.     }
  567. }
  568.  
  569. //
  570. // mime handling routines
  571. //
  572.  
  573. int
  574. FontDisplayerPeerObject::countMimetypes()
  575. {
  576.     // Check for generic preconditions
  577.     if (deleted || disabled)
  578.     {
  579.         return (-1);
  580.     }
  581.     return (mimeList.count());
  582. }
  583.  
  584. int
  585. FontDisplayerPeerObject::isMimetypeEnabled(const char *mimetype)
  586. {
  587.     // Check for generic preconditions
  588.     if (deleted || disabled)
  589.     {
  590.         return (0);
  591.     }
  592.  
  593.     return (mimeList.isEnabled(mimetype));
  594. }
  595.  
  596. const char *
  597. FontDisplayerPeerObject::getMimetypeFromExtension(const char *ext)
  598. {
  599.     // Check for generic preconditions
  600.     if (deleted || disabled)
  601.     {
  602.         return (0);
  603.     }
  604.  
  605.     return (mimeList.getMimetypeFromExtension(ext));
  606. }
  607.  
  608.  
  609. int
  610. FontDisplayerPeerObject::disableMimetype(const char *mimetype)
  611. {
  612.     // Check for generic preconditions
  613.     if (deleted)
  614.     {
  615.         return (-1);
  616.     }
  617.  
  618.     return (mimeList.setEnabledStatus(mimetype, 0));
  619. }
  620.  
  621. int
  622. FontDisplayerPeerObject::enableMimetype(const char *mimetype)
  623. {
  624.     // Check for generic preconditions
  625.     if (deleted)
  626.     {
  627.         return (-1);
  628.     }
  629.  
  630.     return (mimeList.setEnabledStatus(mimetype, 1));
  631. }
  632.  
  633. //
  634. // Additional routines
  635. //
  636.  
  637. const char *
  638. FontDisplayerPeerObject::name(void)
  639. {
  640.     // Check for generic preconditions
  641.     if (deleted || disabled)
  642.     {
  643.         return (NULL);
  644.     }
  645.  
  646.     return (displayerName);
  647. }
  648.  
  649. int
  650. FontDisplayerPeerObject::isNative(void)
  651. {
  652.     if (native < 0)
  653.     {
  654.         native = 0;    // not native
  655.         if (displayerName)
  656.         {
  657.             native = (strcmp(displayerName, NF_NATIVE_FONT_DISPLAYER) == 0);
  658.         }
  659.     }
  660.     // Check if this is the native font displayer
  661.     return (native);
  662. }
  663.  
  664. int
  665. FontDisplayerPeerObject::isDeleted(void)
  666. {
  667.     return (deleted);
  668. }
  669.  
  670. int
  671. FontDisplayerPeerObject::isLoaded(void)
  672. {
  673.     int ret = 0;
  674.  
  675.     // Check for generic preconditions
  676.     if (deleted || disabled)
  677.     {
  678.         return (ret);
  679.     }
  680.  
  681.     if (fontDisplayer || fpType == FontDisplayerPeerObject::WF_FP_STATIC)
  682.     {
  683.         ret = 1;
  684.     }
  685.     return (ret);
  686. }
  687.  
  688.  
  689. void
  690. FontDisplayerPeerObject::StreamCreated(struct nfstrm *strm)
  691. {
  692.     streamCount++;
  693. }
  694.  
  695. void
  696. FontDisplayerPeerObject::StreamDone(struct nfstrm *strm)
  697. {
  698.     streamCount--;
  699.  
  700.     decideToUnload();
  701. }
  702.  
  703. void
  704. FontDisplayerPeerObject::FontHandleCreated(void *fh)
  705. {
  706.     fhList.add(fh);
  707. }
  708.  
  709. void
  710. FontDisplayerPeerObject::FontHandleDone(void *fh)
  711. {
  712.     if (fhList.remove(fh) == wfList::SUCCESS)
  713.     {
  714.         // If there was no other copy of the fh in our fhlist
  715.         // then this was the last fh and can be released.
  716.         if (fhList.isExist(fh) != wfList::SUCCESS)
  717.         {
  718.             ReleaseFontHandle(fh);
  719.             
  720.             if (fpType == FontDisplayerPeerObject::WF_FP_DYNAMIC)
  721.             {
  722.                 // Static displayers need not be unloaded.
  723.                 decideToUnload();
  724.             }
  725.         }
  726.     }
  727. }
  728.  
  729.  
  730. int
  731. FontDisplayerPeerObject::disableDisplayer(void)
  732. {
  733.     if (deleted)
  734.     {
  735.         return (-1);
  736.     }
  737.  
  738.     disabled = 1;
  739.     return (0);
  740. }
  741.  
  742. int
  743. FontDisplayerPeerObject::enableDisplayer(void)
  744. {
  745.     if (deleted)
  746.     {
  747.         return (-1);
  748.     }
  749.  
  750.     disabled = 0;
  751.     return (0);
  752. }
  753.  
  754. int
  755. FontDisplayerPeerObject::isDisplayerEnabled(void)
  756. {
  757.     if (deleted)
  758.     {
  759.         return (0);
  760.     }
  761.     return ((disabled ? 0 : 1));
  762. }
  763.  
  764.  
  765. int
  766. FontDisplayerPeerObject::registerConverters(void)
  767. {
  768.     if (deleted)
  769.     {
  770.         return (-1);
  771.     }
  772.  
  773.     if (!mimeList.isEmpty())
  774.     {
  775.         // Foreach mime
  776.         struct wfListElement *tmp = mimeList.head;
  777.         for (; tmp; tmp = tmp->next)
  778.         {
  779.             struct mime_store *ele = (struct mime_store *) tmp->item;
  780.             NET_cdataCommit(ele->mimetype, ele->extensions);
  781.         }
  782.     }
  783.     
  784.     return (0);
  785. }
  786.  
  787.  
  788. char *
  789. FontDisplayerPeerObject::aboutData(void)
  790. {
  791.     char *aboutData = NULL;
  792.     int aboutDataLen = 0;
  793.     int aboutDataMaxLen = 0;
  794. #ifndef NO_HTML_DIALOGS_CHANGE
  795. #define WF_ABOUT_DATA_ALLOCATION_STEP 64
  796. #define WF_ACCUMULATE(str) wf_addToString(&aboutData, &aboutDataLen, &aboutDataMaxLen, str);
  797.  
  798.     // Dont show deleted font displayers.
  799.     if (isDeleted())
  800.     {
  801.         return (NULL);
  802.     }
  803.  
  804.  
  805.     // Displayer data
  806.     char *fmtstring = NULL;
  807.     char *buf;
  808.     if (fpType == FontDisplayerPeerObject::WF_FP_STATIC)
  809.     {
  810.         fmtstring = XP_GetString(WF_MSG_ABOUT_DISPLAYER_STATIC);
  811.         buf = PR_smprintf(fmtstring,
  812.             (displayerName ? displayerName : ""),
  813.             (displayerDescription ? displayerDescription : ""));
  814.     }
  815.     else
  816.     {
  817.         fmtstring = XP_GetString(WF_MSG_ABOUT_DISPLAYER_DYNAMIC);
  818.         buf = PR_smprintf(fmtstring,
  819.             (displayerName ? displayerName : ""),
  820.             (displayerDescription ? displayerDescription : ""),
  821.             dlm.filename());
  822.     }
  823.     if (buf)
  824.     {
  825.         WF_ACCUMULATE(buf);
  826.         XP_FREE(buf);
  827.         buf = NULL;
  828.     }
  829.     if (!mimeList.isEmpty())
  830.     {
  831.         // Foreach mime
  832.         struct wfListElement *tmp = mimeList.head;
  833.         for (; tmp; tmp = tmp->next)
  834.         {
  835.             struct mime_store *ele = (struct mime_store *) tmp->item;
  836.             buf = PR_smprintf(XP_GetString(WF_MSG_ABOUT_DISPLAYER_MIME),
  837.                 ele->mimetype,
  838.                 (displayerName ? displayerName : ""),
  839.                 (ele->isEnabled ? "checked" : ""), /* NO I18N */
  840.                 ele->mimetype, ele->description,
  841.                 ele->extensions);
  842.             if (buf)
  843.             {
  844.                 WF_ACCUMULATE(buf);
  845.                 XP_FREE(buf);
  846.                 buf = NULL;
  847.             }
  848.         }
  849.     }
  850.     WF_ACCUMULATE(XP_GetString(WF_MSG_ABOUT_DISPLAYER_END));
  851. #endif /* NO_HTML_DIALOGS_CHANGE */
  852.     return (aboutData);
  853. }
  854.     
  855. //
  856. // Private method implementations
  857. //
  858.  
  859. int
  860. FontDisplayerPeerObject::load(void)
  861. {
  862.     // Check for generic preconditions
  863.     if (deleted || disabled)
  864.     {
  865.         return (0);
  866.     }
  867.  
  868.     if (fontDisplayer || fpType == FontDisplayerPeerObject::WF_FP_STATIC)
  869.     {
  870.         return (0);
  871.     }
  872.  
  873.     dlm.load();
  874.     if (dlm.status() < 0)
  875.     {
  876.         return (-1);
  877.     }
  878.  
  879.     fontDisplayer = dlm.createDisplayerObject(WF_fbp);
  880.     if (!fontDisplayer)
  881.     {
  882.         WF_TRACEMSG(("NF: dlm (%s) Couldn't create fontdisplayer object. Skipping dlm.",
  883.                   dlm.filename()));
  884.         dlm.unload();
  885.         return (-1);
  886.     }
  887.     return (0);
  888. }
  889.  
  890. extern "C" void wf_unloadTimer(void *closure)
  891. {
  892.     FontDisplayerPeerObject *fpp = (FontDisplayerPeerObject *)closure;
  893.     if (fpp->unloadTimerId)
  894.     {
  895.         // One last sanity check
  896.         if (fpp->streamCount == 0 && fpp->fhList.isEmpty())
  897.         {
  898.             fpp->unload();
  899.         }
  900.         fpp->unloadTimerId = 0;
  901.     }
  902. }
  903.  
  904. void
  905. FontDisplayerPeerObject::decideToUnload(void)
  906. {
  907.     if (streamCount == 0 && fhList.isEmpty())
  908.     {
  909.         // This displayer can be unloaded.
  910.         // I really want to do something like unloading the displayer
  911.         // after say 1 min. because say the navigator moves from one page
  912.         // to another and both had use for this displayer, then this displayer
  913.         // will get loaded twice and unloaded once causing thrashing.
  914.         //
  915.         // The problem in implementing this is how to we ensure we get
  916.         // back control after this many seconds. We should use the
  917.         // FE Timer callback.
  918.         
  919.         // Clear any previous timers
  920.         if (unloadTimerId)
  921.         {
  922.             FE_ClearTimeout(unloadTimerId);
  923.         }
  924.  
  925.         // Set the new timer
  926.         unloadTimerId = FE_SetTimeout(wf_unloadTimer, this, WF_ONE_MINUTE);
  927.     }
  928.     else
  929.     {
  930.         // Unload should not happen
  931.         if (unloadTimerId)
  932.         {
  933.             FE_ClearTimeout(unloadTimerId);
  934.         }
  935.     }
  936. }
  937.  
  938. int
  939. FontDisplayerPeerObject::unload(void)
  940. {
  941.     if (fpType == FontDisplayerPeerObject::WF_FP_STATIC)
  942.     {
  943.         // Static displayer need not be unloaded.
  944.         return (0);
  945.     }
  946.     if (!fontDisplayer)
  947.     {
  948.         // We were never loaded.
  949.         return (-1);
  950.     }
  951.     nffp_release(fontDisplayer, NULL);
  952.     fontDisplayer = NULL;
  953.     return (dlm.unload());
  954. }
  955.  
  956. int FontDisplayerPeerObject::
  957. finalizeExceptDlmAndDisabled()
  958. {
  959.     // Release memory
  960.     if (displayerName)
  961.     {
  962.         delete displayerName;
  963.         displayerName = NULL;
  964.     }
  965.     if (displayerDescription)
  966.     {
  967.         delete displayerDescription;
  968.         displayerDescription = NULL;
  969.     }
  970.  
  971.     // Clear native flag
  972.     native = -1;
  973.     // Clear deleted flag
  974.     deleted = 0;
  975.     
  976.     // Clean mimelist
  977.     mimeList.finalize();
  978.  
  979.     // Clean catalog
  980.     catalog.finalize();
  981.  
  982.     return (0);
  983. }
  984.  
  985. int FontDisplayerPeerObject::
  986. finalize()
  987. {
  988.     finalizeExceptDlmAndDisabled();
  989.  
  990.     // Clean dlm
  991.     unload();
  992.     dlm.finalize();
  993.     
  994.     // Clear disabled flag
  995.     disabled = 0;
  996.  
  997.     return (0);
  998. }
  999.  
  1000.