home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libnet / cvcolor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  16.3 KB  |  593 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. /* Please leave outside of ifdef for windows precompiled headers */
  19. #include "mkutils.h"
  20.  
  21. #ifdef MOZILLA_CLIENT
  22.  
  23. /* take an HTML stream.  Escape all the HTML and
  24.  * use <FONT color=> to color the different syntactical parts
  25.  * of the HTML stream
  26.  */
  27. #include "mkstream.h"
  28. #include "mkgeturl.h"
  29. #include "pa_parse.h"
  30. #include "xp.h"
  31. #include "xpgetstr.h"
  32. #include "intl_csi.h"
  33. #define VIEW_SOURCE_TARGET_WINDOW_NAME "%ViewSourceWindow"
  34.  
  35. typedef enum StatesEnum {
  36.     IN_CONTENT,
  37.     IN_SCRIPT,
  38.     ABOUT_TO_BEGIN_TAG,
  39.     IN_BEGIN_TAG,
  40.     IN_TAG,
  41.     BEGIN_ATTRIBUTE_VALUE,
  42.     IN_QUOTED_ATTRIBUTE_VALUE,
  43.     IN_BROKEN_QUOTED_ATTRIBUTE_VALUE,
  44.     IN_UNQUOTED_ATTRIBUTE_VALUE,
  45.     IN_COMMENT,
  46.     IN_AMPERSAND_THINGY
  47. } StatesEnum;
  48.  
  49. #define MAXTAGLEN 15
  50.  
  51. typedef struct _DataObject {
  52.     NET_StreamClass * next_stream;
  53.     StatesEnum state;
  54.     char tag[MAXTAGLEN+1];
  55.     uint tag_index;
  56.     int  tag_type;
  57.     XP_Bool in_broken_html;
  58. } DataObject;
  59.  
  60. #define BEGIN_TAG_MARKUP "<B>"
  61. #define END_TAG_MARKUP "</B>"
  62. #define BEGIN_TAG_NAME_MARKUP "<FONT SIZE=+0 COLOR=\"#551A8B\">"
  63. #define END_TAG_NAME_MARKUP "</FONT>"
  64. #define BEGIN_ATTRIBUTE_VALUE_MARKUP "</B><FONT SIZE=+0 COLOR=\"003E98\">"
  65. #define END_ATTRIBUTE_VALUE_MARKUP "</FONT><B>"
  66. #define BEGIN_BROKEN_ATTRIBUTE_MARKUP "<FONT COLOR=#0000FF><BLINK>"
  67. #define END_BROKEN_ATTRIBUTE_MARKUP "</BLINK></FONT>"
  68. #define BEGIN_COMMENT_MARKUP "<I>"
  69. #define END_COMMENT_MARKUP "</I>"
  70. #define BEGIN_AMPERSAND_THINGY_MARKUP "<FONT SIZE=+0 COLOR=\"#2F4F2F\">"
  71. #define END_AMPERSAND_THINGY_MARKUP "</FONT>"
  72.  
  73. extern int MK_CVCOLOR_SOURCE_OF; 
  74.  
  75. PRIVATE char *net_BeginColorHTMLTag (DataObject *obj)
  76. {
  77.     char *new_markup = 0;
  78.  
  79.     if (obj->tag_type == P_SCRIPT)
  80.       {
  81.         StrAllocCopy(new_markup, "</XMP><PRE>");
  82.         obj->tag_type = P_UNKNOWN;
  83.       }
  84.     StrAllocCat(new_markup, BEGIN_TAG_MARKUP);
  85.     StrAllocCat(new_markup, "<");
  86.     StrAllocCat(new_markup, BEGIN_TAG_NAME_MARKUP);
  87.     obj->state = ABOUT_TO_BEGIN_TAG;
  88.     return new_markup;
  89. }
  90.  
  91. PRIVATE char *net_EndColorHTMLTag (DataObject *obj)
  92. {
  93.     char *new_markup = 0;
  94.  
  95.     if(obj->in_broken_html)
  96.       {
  97.            StrAllocCopy(new_markup, END_BROKEN_ATTRIBUTE_MARKUP);
  98.         obj->in_broken_html = FALSE;
  99.       }
  100.     StrAllocCat(new_markup, ">");
  101.     StrAllocCat(new_markup, END_TAG_MARKUP);
  102.     if (obj->tag_type == P_SCRIPT)
  103.       {
  104.         StrAllocCat(new_markup, "</PRE><XMP>");
  105.         obj->state = IN_SCRIPT;
  106.       }
  107.     else
  108.       {
  109.         obj->state = IN_CONTENT;
  110.       }
  111.     return new_markup;
  112. }
  113.  
  114. PRIVATE int net_ColorHTMLWrite (NET_StreamClass *stream, CONST char *s, int32 l)
  115. {
  116.     int32 i;
  117.     int32 last_output_point;
  118.     char *new_markup=0;
  119.     char *tmp_markup=0;
  120.     char  tiny_buf[4];
  121.     CONST char *cp;
  122.     int   status;
  123.     DataObject *obj=stream->data_object;    
  124.  
  125.     last_output_point = 0;
  126.  
  127.     for(i = 0, cp = s; i < l; i++, cp++)
  128.       {
  129.         switch(obj->state)
  130.           {
  131.             case IN_CONTENT:
  132.                 /* do nothing until you find a '<' "<!--" or '&' */
  133.                 if(*cp == '<')
  134.                   {
  135.                     /* XXX we can miss a comment spanning a block boundary */
  136.                     if(i+4 <= l && !XP_STRNCMP(cp, "<!--", 4))
  137.                       {
  138.                         StrAllocCopy(new_markup, BEGIN_COMMENT_MARKUP);
  139.                         StrAllocCat(new_markup, "<");
  140.                         obj->state = IN_COMMENT;
  141.                       }
  142.                     else
  143.                       {
  144.                         new_markup = net_BeginColorHTMLTag(obj);
  145.                       }
  146.                   }
  147.                 else if(*cp == '&')
  148.                   {
  149.                     StrAllocCopy(new_markup, BEGIN_AMPERSAND_THINGY_MARKUP);
  150.                     StrAllocCat(new_markup, "&");
  151.                     obj->state = IN_AMPERSAND_THINGY;
  152.                   }
  153.                 break;
  154.             case IN_SCRIPT:
  155.                 /* do nothing until you find '</SCRIPT>' */
  156.                 if(*cp == '<')
  157.                   {
  158.                     /* XXX we can miss a </SCRIPT> spanning a block boundary */
  159.                     if(i+8 <= l && !XP_STRNCASECMP(cp, "</SCRIPT", 8))
  160.                       {
  161.                         new_markup = net_BeginColorHTMLTag(obj);
  162.                       }
  163.                   }
  164.                 break;
  165.             case ABOUT_TO_BEGIN_TAG:
  166.                 /* we have seen the first '<'
  167.                  * once we see a non-whitespace character
  168.                  * we will be in the tag identifier
  169.                  */
  170.                 if(*cp == '>')
  171.                   {
  172.                     StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
  173.                     tmp_markup = net_EndColorHTMLTag(obj);
  174.                     StrAllocCat(new_markup, tmp_markup);
  175.                     FREE_AND_CLEAR(tmp_markup);
  176.                   }
  177.                 else if(!XP_IS_SPACE(*cp))
  178.                   {
  179.                     obj->state = IN_BEGIN_TAG;
  180.                     obj->tag_index = 0;
  181.                     obj->tag[obj->tag_index++] = *cp;
  182.                     if(*cp == '<')
  183.                         StrAllocCopy(new_markup, "<");
  184.  
  185.                   }
  186.                 break;
  187.             case IN_BEGIN_TAG:
  188.                 /* go to the IN_TAG state when we see
  189.                  * the first whitespace
  190.                  */
  191.                 if(XP_IS_SPACE(*cp))
  192.                   {
  193.                     StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
  194.                     XP_SPRINTF(tiny_buf, "%c", *cp);
  195.                     StrAllocCat(new_markup, tiny_buf);
  196.                     obj->state = IN_TAG;
  197.                     obj->tag[obj->tag_index] = '\0';
  198.                     obj->tag_type = pa_tokenize_tag(obj->tag);
  199.                   }
  200.                 else if(*cp == '>')
  201.                   {
  202.                     StrAllocCopy(new_markup, END_TAG_NAME_MARKUP);
  203.                     tmp_markup = net_EndColorHTMLTag(obj);
  204.                     StrAllocCat(new_markup, tmp_markup);
  205.                     FREE_AND_CLEAR(tmp_markup);
  206.                   }
  207.                 else if(*cp == '<')
  208.                   {
  209.                     /* protect ourselves from markup */
  210.                     if(!obj->in_broken_html)
  211.                       {
  212.                         obj->in_broken_html = TRUE;
  213.                         StrAllocCopy(new_markup, BEGIN_BROKEN_ATTRIBUTE_MARKUP);
  214.                         StrAllocCat(new_markup, "<");
  215.                       }
  216.                     else
  217.                       {
  218.                         StrAllocCopy(new_markup, "<");
  219.                       }
  220.                   }
  221.                 else
  222.                   {
  223.                     if (obj->tag_index < MAXTAGLEN)
  224.                         obj->tag[obj->tag_index++] = *cp;
  225.                   }
  226.                 break;
  227.             case IN_TAG:
  228.                 /* do nothing until you find a opening '=' or end '>' */
  229.                 if(*cp == '=')
  230.                   {
  231.                     StrAllocCopy(new_markup, "=");
  232.                     StrAllocCat(new_markup, BEGIN_ATTRIBUTE_VALUE_MARKUP);
  233.                     obj->state = BEGIN_ATTRIBUTE_VALUE;
  234.                   }
  235.                 else if(*cp == '>')
  236.                   {
  237.                     new_markup = net_EndColorHTMLTag(obj);
  238.                   }
  239.                 else if(*cp == '<')
  240.                   {
  241.                     /* protect ourselves from markup */
  242.                     StrAllocCopy(new_markup, "<");
  243.                   }
  244.                 break;
  245.             case BEGIN_ATTRIBUTE_VALUE:
  246.                 /* when we reach the first non-whitespace
  247.                  * we will enter the UNQUOTED or the QUOTED
  248.                  * ATTRIBUTE state
  249.                  */
  250.                 if(!XP_IS_SPACE(*cp))
  251.                   {
  252.                     if(*cp == '"')
  253.                     {
  254.                         obj->state = IN_QUOTED_ATTRIBUTE_VALUE;
  255.                         /* no need to jump to the quoted attr handler
  256.                          * since this char can't be a dangerous char
  257.                          */
  258.                     }
  259.                     else
  260.                     {
  261.                         obj->state = IN_UNQUOTED_ATTRIBUTE_VALUE;
  262.                         /* need to jump to the unquoted attr handler
  263.                          * since this char can be a dangerous character
  264.                          */
  265.                         goto unquoted_attribute_jump_point;
  266.                     }
  267.                   }
  268.                 else if(*cp == '>')
  269.                   {
  270.                     StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
  271.                     tmp_markup = net_EndColorHTMLTag(obj);
  272.                     StrAllocCat(new_markup, tmp_markup);
  273.                     FREE_AND_CLEAR(tmp_markup);
  274.                   }
  275.                 else if(*cp == '<')
  276.                   {
  277.                     /* protect ourselves from markup */
  278.                     StrAllocCopy(new_markup, "<");
  279.                   }
  280.                 break;
  281.             case IN_UNQUOTED_ATTRIBUTE_VALUE:
  282. unquoted_attribute_jump_point:
  283.                 /* do nothing until you find a whitespace */
  284.                 if(XP_IS_SPACE(*cp))
  285.                   {
  286.                     StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
  287.                     XP_SPRINTF(tiny_buf, "%c", *cp);
  288.                     StrAllocCat(new_markup, tiny_buf);
  289.                     obj->state = IN_TAG;
  290.                   }
  291.                 else if(*cp == '>')
  292.                   {
  293.                     StrAllocCopy(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
  294.                     tmp_markup = net_EndColorHTMLTag(obj);
  295.                     StrAllocCat(new_markup, tmp_markup);
  296.                     FREE_AND_CLEAR(tmp_markup);
  297.                   }
  298.                 else if(*cp == '<')
  299.                   {
  300.                     /* protect ourselves from markup */
  301.                     StrAllocCopy(new_markup, "<");
  302.                   }
  303.                 else if(*cp == '&')
  304.                   {
  305.                     /* protect ourselves from markup */
  306.                     StrAllocCopy(new_markup, "&");
  307.                   }
  308.                 break;
  309.             case IN_QUOTED_ATTRIBUTE_VALUE:
  310.                 /* do nothing until you find a closing '"' */
  311.                 if(*cp == '\"')
  312.                   {
  313.                     if(obj->in_broken_html)
  314.                       {
  315.                         StrAllocCopy(new_markup, END_BROKEN_ATTRIBUTE_MARKUP);
  316.                         obj->in_broken_html = FALSE;
  317.                       }
  318.                     StrAllocCat(new_markup, "\"");
  319.                     StrAllocCat(new_markup, END_ATTRIBUTE_VALUE_MARKUP);
  320.                     obj->state = IN_TAG;
  321.                   }
  322.                 else if(*cp == '<')
  323.                   {
  324.                     /* protect ourselves from markup */
  325.                     StrAllocCopy(new_markup, "<");
  326.                   }
  327.                 else if(*cp == '&')
  328.                   {
  329.                     /* protect ourselves from markup */
  330.                     StrAllocCopy(new_markup, "&");
  331.                   }
  332.                 else if(*cp == '>')
  333.                   {
  334.                     /* probably a broken attribute value */
  335.                     if(!obj->in_broken_html)
  336.                       {
  337.                         obj->in_broken_html = TRUE;
  338.                         StrAllocCopy(new_markup, BEGIN_BROKEN_ATTRIBUTE_MARKUP);
  339.                         StrAllocCat(new_markup, ">");
  340.                       }
  341.                   }
  342.                 break;
  343.             case IN_COMMENT:
  344.                 /* do nothing until you find a closing '-->' */
  345.                 if(!XP_STRNCMP(cp, "-->", 3))
  346.                   {
  347.                     StrAllocCopy(new_markup, ">");
  348.                     cp += 2;
  349.                     i += 2;
  350.                     StrAllocCat(new_markup, END_COMMENT_MARKUP);
  351.                     obj->state = IN_CONTENT;
  352.                   }
  353.                 else if(*cp == '<')
  354.                   {
  355.                     /* protect ourselves from markup */
  356.                     StrAllocCopy(new_markup, "<");
  357.                   }
  358.                 break;
  359.             case IN_AMPERSAND_THINGY:
  360.                 /* do nothing until you find a ';' or space */
  361.                 if(*cp == ';' || XP_IS_SPACE(*cp))
  362.                   {
  363.                     XP_SPRINTF(tiny_buf, "%c", *cp);
  364.                     StrAllocCopy(new_markup, tiny_buf);
  365.                     StrAllocCat(new_markup, END_AMPERSAND_THINGY_MARKUP);
  366.                     obj->state = IN_CONTENT;
  367.                   }
  368.                 else if(*cp == '<')
  369.                   {
  370.                     /* protect ourselves from markup */
  371.                     StrAllocCopy(new_markup, "<");
  372.                   }
  373.                 break;
  374.             default:
  375.                 XP_ASSERT(0);
  376.                 break;
  377.           }
  378.  
  379.         if(new_markup)
  380.           {
  381.             /* push all the way up to but not including *cp */
  382.             status = (*obj->next_stream->put_block)
  383.                                             (obj->next_stream,
  384.                                             &s[last_output_point],
  385.                                             i-last_output_point);
  386.             last_output_point = i+1;
  387.  
  388.             if(status < 0)
  389.               {
  390.                 FREE(new_markup);
  391.                 return(status);
  392.               }
  393.  
  394.             /* add new markup */
  395.             status = (*obj->next_stream->put_block)
  396.                                             (obj->next_stream,
  397.                                             new_markup, XP_STRLEN(new_markup));
  398.             if(status < 0)
  399.               {
  400.                 FREE(new_markup);
  401.                 return(status);
  402.               }
  403.  
  404.             FREE_AND_CLEAR(new_markup);
  405.           }
  406.       }
  407.  
  408.     if(last_output_point < l)
  409.         return((*obj->next_stream->put_block)(obj->next_stream,
  410.                                           &s[last_output_point],
  411.                                           (l-last_output_point)));
  412.     else
  413.         return(0);
  414. }
  415.  
  416. /* is the stream ready for writeing?
  417.  */
  418. PRIVATE unsigned int net_ColorHTMLWriteReady (NET_StreamClass * stream)
  419. {
  420.     DataObject *obj=stream->data_object;
  421.     return((*obj->next_stream->is_write_ready)(obj->next_stream));
  422. }
  423.  
  424.  
  425. PRIVATE void net_ColorHTMLComplete (NET_StreamClass *stream)
  426. {
  427.     DataObject *obj=stream->data_object;    
  428.     (*obj->next_stream->complete)(obj->next_stream);
  429. }
  430.  
  431. PRIVATE void net_ColorHTMLAbort (NET_StreamClass *stream, int status)
  432. {
  433.     DataObject *obj=stream->data_object;    
  434.     (*obj->next_stream->abort)(obj->next_stream, status);
  435. }
  436.  
  437. PUBLIC NET_StreamClass *
  438. net_ColorHTMLStream (int         format_out,
  439.                      void       *data_obj,
  440.                      URL_Struct *URL_s,
  441.                      MWContext  *window_id)
  442. {
  443.     DataObject* obj;
  444.     char *new_markup=0;
  445.     char *new_url=0;
  446.     char *old_url;
  447.     int status, type;
  448.     NET_StreamClass *next_stream, *new_stream;
  449.     Bool is_html_stream = FALSE;
  450.     INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(window_id);
  451.     INTL_CharSetInfo next_csi;
  452.  
  453.     TRACEMSG(("Setting up ColorHTML stream. Have URL: %s\n", URL_s->address));
  454.  
  455.     /* treat the stream as html if the closure data says
  456.      * it's HTML and it is also not a mail or news message
  457.      */
  458.     type = NET_URL_Type(URL_s->address);
  459.     if(data_obj 
  460.         && !XP_STRCMP((char *)data_obj, TEXT_HTML)
  461.         && type != MAILBOX_TYPE_URL
  462.         && type != IMAP_TYPE_URL
  463.         && type != NEWS_TYPE_URL)
  464.         is_html_stream = TRUE;
  465.  
  466.     /* use a new named window */
  467.     StrAllocCopy(URL_s->window_target, VIEW_SOURCE_TARGET_WINDOW_NAME);
  468.  
  469.     /* add the url address to the name so that there can be
  470.      * one view source window per url
  471.      */
  472.     StrAllocCat(URL_s->window_target, URL_s->address);
  473.  
  474.     /* zero position_tag to prevent hash lossage */
  475.     URL_s->position_tag = 0;
  476.  
  477.     /* alloc a new chrome struct and stick it in the URL
  478.        * so that we can turn off the relavent stuff
  479.      */
  480.     URL_s->window_chrome = XP_NEW(Chrome);
  481.     if(URL_s->window_chrome)
  482.       {
  483.         /* zero everything to turn off all chrome */
  484.         XP_MEMSET(URL_s->window_chrome, 0, sizeof(Chrome));
  485.         URL_s->window_chrome->type = MWContextDialog;
  486.         URL_s->window_chrome->show_scrollbar = TRUE;
  487.         URL_s->window_chrome->allow_resize = TRUE;
  488.         URL_s->window_chrome->allow_close = TRUE;
  489.       }
  490.  
  491.     /* call the HTML parser */
  492.     StrAllocCopy(URL_s->content_type, INTERNAL_PARSER);
  493.  
  494.     /* use the view-source: url instead */
  495.     StrAllocCopy(new_url, VIEW_SOURCE_URL_PREFIX);
  496.     StrAllocCat(new_url, URL_s->address);
  497.     old_url = URL_s->address;
  498.     URL_s->address = new_url;
  499.  
  500.     format_out = FO_PRESENT;
  501.  
  502.     /* open next stream */
  503.     next_stream = NET_StreamBuilder(format_out, URL_s, window_id);
  504.  
  505.     if(!next_stream)
  506.       {
  507.         FREE(old_url);
  508.         return(NULL);
  509.       }
  510.     next_csi = LO_GetDocumentCharacterSetInfo(next_stream->window_id);
  511.  
  512.     /* jliu: for international's reason,
  513.         set the value ASAP, so the following stream can share it */
  514.     INTL_SetCSIWinCSID(next_csi, INTL_GetCSIWinCSID(csi));
  515.     INTL_SetCSIDocCSID(next_csi, INTL_GetCSIDocCSID(csi));
  516.  
  517.  
  518. #define DEF_PICS_LABEL "<META http-equiv=PICS-Label content='(PICS-1.0 \"http://home.netscape.com/default_rating\" l gen true r (s 0))'>"
  519.  
  520.     /* add a PICS label */
  521.     StrAllocCopy(new_markup, DEF_PICS_LABEL);
  522.     StrAllocCat(new_markup, "<TITLE>");
  523.     StrAllocCat(new_markup, XP_GetString(MK_CVCOLOR_SOURCE_OF));
  524.     StrAllocCat(new_markup, old_url);
  525.     StrAllocCat(new_markup, "</TITLE><BODY BGCOLOR=#C0C0C0>");
  526.  
  527.  
  528.     if(!is_html_stream)
  529.         StrAllocCat(new_markup, "<PLAINTEXT>");
  530.     else
  531.         StrAllocCat(new_markup, "<PRE>");
  532.  
  533.     FREE(old_url);
  534.  
  535.       status = (*next_stream->put_block)(next_stream,
  536.                                             new_markup,
  537.                                             XP_STRLEN(new_markup));
  538.     FREE(new_markup);
  539.  
  540.     if(status < 0)
  541.       {
  542.           (*next_stream->abort)(next_stream, status);
  543.         FREE(next_stream);
  544.         return(NULL);
  545.       }
  546.  
  547.     if(!is_html_stream)
  548.         return(next_stream);
  549.  
  550.     /* else; continue on and build up this stream module
  551.      * and attach the next stream to it
  552.      */
  553.  
  554.     new_stream = XP_NEW(NET_StreamClass);
  555.     if(new_stream == NULL)
  556.       {
  557.           (*next_stream->abort)(next_stream, status);
  558.         FREE(next_stream);
  559.         return(NULL);
  560.       }
  561.  
  562.     obj = XP_NEW(DataObject);
  563.  
  564.     if (obj == NULL)
  565.       {
  566.           (*next_stream->abort)(next_stream, status);
  567.         FREE(next_stream);
  568.         FREE(new_stream);
  569.         return(NULL);
  570.       }
  571.  
  572.     XP_MEMSET(obj, 0, sizeof(DataObject));
  573.  
  574.     obj->state = IN_CONTENT;
  575.  
  576.     obj->next_stream = next_stream;
  577.     obj->tag_type = P_UNKNOWN;
  578.  
  579.     new_stream->name           = "HTML Colorer";
  580.     new_stream->complete       = (MKStreamCompleteFunc) net_ColorHTMLComplete;
  581.     new_stream->abort          = (MKStreamAbortFunc) net_ColorHTMLAbort;
  582.     new_stream->put_block      = (MKStreamWriteFunc) net_ColorHTMLWrite;
  583.     new_stream->is_write_ready = (MKStreamWriteReadyFunc)
  584.                                                     net_ColorHTMLWriteReady;
  585.     new_stream->data_object    = (void *) obj;  /* document info object */
  586.     new_stream->window_id      = window_id;
  587.  
  588.     TRACEMSG(("Returning stream from HTMLColorConverter\n"));
  589.  
  590.     return new_stream;
  591. }
  592. #endif /* MOZILLA_CLIENT */
  593.