html.c
上传用户:zlh9724
上传日期:2007-01-04
资源大小:1991k
文件大小:78k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /* html.c - display code for html
  2. This file contains the code for displaying HTML documents, scrolling them
  3. and dealing with hypertext jumps by recognising which buttons are clicked.
  4. */
  5. /*
  6. Janne Saarela
  7. janne.saarela@hut.fi
  8. 28.7.1995
  9. The SEQTEXT element in the PaintStream has the additional
  10. attribute, emph, of width of two bytes.
  11. The handling of different emph attributes is not finalized.
  12. I tried using < and > symbols from the adobe symbol font
  13. but they do not seem to work properly. OVERHAT, OVERDOT,
  14. OVERDDOT and OVERTILDE are to be implemented.
  15. */
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <ctype.h>
  19. #include "www.h"
  20. #include "tools.h"
  21. #include "forms.h"
  22. #include "style.h"
  23. extern Display *display;
  24. extern int screen;
  25. extern Window win;
  26. extern GC disp_gc, gc_fill;
  27. extern Cursor hourglass;
  28. extern int UsePaper;
  29. extern Context *context;
  30. extern int ExposeCount; 
  31. extern int debug;  /* controls display of errors */
  32. /*extern int document; */ /* HTML_DOCUMENT or TEXT_DOCUMENT */
  33. extern int busy;
  34. extern int OpenURL;
  35. extern int IsIndex;
  36. extern int FindStr;
  37. extern char *FindNextStr;
  38. extern int SaveFile;
  39. extern int sbar_width;
  40. extern int statusHeight;
  41. extern int ToolBarHeight;
  42. extern unsigned long windowColor;
  43. extern unsigned int win_width, win_height, tileWidth, tileHeight;
  44. extern unsigned long textColor, labelColor, windowTopShadow,
  45.                      strikeColor, windowBottomShadow, windowShadow, windowColor;
  46. extern unsigned long stdcmap[128];  /* 2/3/2 color maps for gifs etc */
  47. extern unsigned long greymap[16];  /* for mixing with unsaturated colors */
  48. extern int depth;
  49. extern Form *forms;
  50. Byte color_text_ix, color_background_ix;
  51. /*
  52.     The current top line is displayed at the top of the window,the pixel
  53.     offset is the number of pixels from the start of the document.
  54. */
  55. extern char *buffer;            /* the start of the document buffer */
  56. extern long PixelOffset;        /* the pixel offset to top of window */
  57. extern int hdrlen;              /* MIME header length at start of buffer */
  58. extern long buf_height;
  59. extern long lineHeight;
  60. extern long chDescent;
  61. extern int buf_width;
  62. extern int PixelIndent;
  63. extern int chStrike;
  64. extern int spWidth;             /* width of space char */
  65. extern int chWidth;             /* width of average char */
  66. extern Doc *CurrentDoc;
  67. extern XFontStruct *pFontInfo;
  68. extern XFontStruct *Fonts[FONTS];
  69. extern int LineSpacing[FONTS], BaseLine[FONTS], StrikeLine[FONTS];
  70. extern int LineThickness[FONTS];
  71. extern int ListIndent1, ListIndent2;
  72. extern char *LastBufPtr, *StartOfLine, *StartOfWord; /* in HTML document */
  73. extern char *bufptr;  /* parse position in the HTML buffer */
  74. extern Byte *TopObject;  /* first visible object in window */
  75. extern Byte *paint; /* holds the sequence of paint commands */
  76. extern int paintbufsize;     /* size of buffer, not its contents */
  77. extern int paintlen;         /* where to add next entry */
  78. extern Field *focus;
  79. extern int font;  /* index into Fonts[] array */
  80. int preformatted;
  81. XRectangle displayRect; /* clipping limits for painting html */
  82. long IdOffset;      /* offset for targetId */
  83. char *targetptr;    /* for toggling view between HTML/TEXT views */
  84. char *targetId;     /* for locating named Id during ParseHTML() */
  85. /* globals associated with detecting which object is under the mouse */
  86. char *anchor_start, *anchor_end;
  87. Byte *clicked_element;
  88. int img_dx, img_dy;
  89. /* the background frame structure specifies:
  90.     a) where to start painting in this frame
  91.     b) where this frame ends in paint buffer
  92.     c) tree of nested frames which all
  93.        intersect the top of the window
  94. */
  95. Frame background;
  96. /* copy line from str to LineBuf, skipping initial spaces and SGML <tags> */
  97. char *CopyLine(char *str, unsigned int len)
  98. {
  99.     int c, n, k;
  100.     char *p;
  101.     static char buf[1024];
  102.     
  103.     if (len == 0)
  104. return "";
  105.     
  106.     p = buf;
  107.     
  108.     while (len-- > 0)
  109.     {
  110.         c = *str;
  111.         if (c == '')
  112.             break;
  113.         while (c == '<' && ((n = str[1]) == '!' || n == '?' || n == '/' || isalpha(n)))
  114. {                
  115.     
  116.     /* howcome 28/8/95: added code from Michael Van Biesbrouck
  117.        <mlvanbie@valeyard.csclub.uwaterloo.ca> to handle comments */
  118.     
  119.     if (strncmp(str+1, "!--", 3) == 0){
  120. str = FindEndComment( str + 2 );
  121. if (*str) str++;
  122.     } else {
  123. while (*str++ != '>');
  124.     }
  125.             c = *str;
  126.         }
  127.         if (c == '&' && (isalnum(str[1]) || str[1] == '#')) /* howcome 25/11/94: isalpha -> isalnum */
  128.         {
  129.             n = entity(str + 1, &k);
  130.             if (n)
  131.             {
  132.                 /* TokenValue = n; */
  133.                 str += k;
  134.                 *p++  = n;
  135.                 continue;
  136.             }
  137.         }
  138.         if (preformatted)
  139.         {
  140.             if (c == 't')
  141.             {
  142.                 n = 8 - (p - buf)%8;
  143.                 if (n > 0)
  144.                     ++len;
  145.                 while (n-- > 0)
  146.                 {
  147.                     *p++ = ' ';
  148.                      --len;
  149.                 }
  150.             }
  151.             else
  152.                 *p++ = c;
  153.             ++str;
  154.             continue;
  155.         }
  156.         if (IsWhite(c))
  157.         {
  158.             do
  159.                 c = *++str;
  160.             while (IsWhite(c));
  161.             *p++ = c = ' ';
  162.             continue;
  163.         }
  164.         *p++ = c;
  165.         ++str;
  166.     }
  167.     *p = '';
  168.     return buf;
  169. }
  170. void PrintFrameData(int depth, Frame *frame)
  171. {
  172.     int i;
  173.     while (frame)
  174.     {
  175.         for (i = 0; i < depth; ++i)
  176.             printf("  ");
  177.         printf("x = %d, y = %ld; w = %d, h = %ld  size = %d, info at %dn",
  178.             frame->indent, frame->offset, frame->width, frame->height, frame->length, frame->info);
  179.         PrintFrameData(depth+1, frame->child);
  180.         frame = frame->next;
  181.     }
  182. }
  183. void PrintFrame(Frame *frame)
  184. {
  185.     PrintFrameData(1, frame);
  186. }
  187. void PrintObject(unsigned char *p)
  188. {
  189.     int tag, emph, fnt, x1, yi, len, width;
  190.     unsigned int c1, c2;
  191.     long offset, str;
  192.     char *s;
  193.     BG_Style *bg_style;
  194.     tag = *p++;
  195.     if ((tag & 0xF) == STRING)
  196.     {
  197. c1 = *p++; c2 = *p++; emph = c1 | c2<<8;
  198.         fnt = *p++;
  199. #ifdef STYLE_COLOR
  200. color_text_ix = *p++;
  201. #endif
  202. #ifdef STYLE_BACKGROUND
  203. bg_style=(BG_Style *)GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  204. if(bg_style)
  205.     color_background_ix = (bg_style->flag & S_BACKGROUND_COLOR) ? rgb2ix(0, bg_style->r, bg_style->g, bg_style->b,0) : 255; /* GRR */ 
  206. else
  207.     color_background_ix = 255;  
  208. #endif
  209.         yi = *p++ - 128;
  210.         c1 = *p++; c2 = *p++; x1 = (c1 | c2<<8);  /* here */
  211.         c1 = *p++; c2 = *p++; len = c1 | c2<<8;
  212.         c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  213. str = (long) GetPointer(&p);
  214. p += POINTERSIZE;
  215.         preformatted = (tag & PRE_TEXT);
  216.         s = CopyLine((char *)str, len);
  217.         printf("string: "%s"n", s);
  218.     }
  219.     else
  220.     {
  221.         c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  222.         c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  223.         printf("tag = %d, offset = %ldn", tag, offset);
  224.     }
  225. }
  226. void OpenDoc(char *name)
  227. {
  228.   /* janet 21/07/95: not used:    char *p, *q; */
  229.   /* janet 21/07/95: not used:    long wh, target; */
  230.     OpenURL = 0;
  231.     FindNextStr = 0;
  232. /*    XDefineCursor(display, win, hourglass);*/
  233. /*    XFlush(display);*/
  234.     if (name)  /* attempt to get new document */
  235.     {
  236.         /* note current status string */
  237.         SaveStatusString();
  238.         /* quit Open, SaveAs or Find if active */
  239.         OpenURL = SaveFile = FindStr = 0;
  240. libGetDocument(name, strlen(name), NULL, TRUE, FALSE, TRUE, FALSE, FALSE);
  241.     }
  242. }
  243. void PostDoc(char *name, char *post)
  244. {
  245.     OpenURL = 0;
  246.     FindNextStr = 0;
  247. /*    XDefineCursor(display, win, hourglass);*/
  248. /*    XFlush(display);*/
  249.     if (name && post)  /* attempt to get new document */
  250.     {
  251.         /* note current status string */
  252.         SaveStatusString();
  253.         /* quit Open, SaveAs or Find if active */
  254.         OpenURL = SaveFile = FindStr = 0;
  255. libPostDocument(name, strlen(name), post, strlen(post));
  256.     }
  257. }
  258. void ReloadDoc(char *name)
  259. {
  260.   /* janet 21/07/95: not used:    char *p, *q; */
  261.   /* janet 21/07/95; not used:    long wh, target; */
  262.     OpenURL = 0;
  263.     FindNextStr = 0;
  264. /*    XDefineCursor(display, win, hourglass);*/
  265. /*    XFlush(display);*/
  266.     if (name)  /* attempt to get new document */
  267.     {
  268.         /* note current status string */
  269.         SaveStatusString();
  270.         /* quit Open, SaveAs or Find if active */
  271.         OpenURL = SaveFile = FindStr = 0;
  272. /* free style sheets */
  273. if (CurrentDoc->style != context->style) {
  274.     FreeStyleSheet(CurrentDoc->style);
  275.     CurrentDoc->style = NULL;
  276. } else {
  277.     FreeStyleSheet(CurrentDoc->style);
  278.     CurrentDoc->style = NULL;
  279.     context->style = StyleGetInit();
  280. }
  281.       
  282. Free(CurrentDoc->head_style);
  283. Free(CurrentDoc->link_style);
  284. libGetDocument(name, strlen(name), NULL, TRUE, FALSE, FALSE, TRUE, FALSE);
  285.     }
  286. }
  287. /* find title text as defined by <TITLE>title text</TITLE> */
  288. #define MAXTITLE 128
  289. char *TitleText(char *buf)
  290. {
  291.     return "Dummy Title";
  292. }
  293. /*
  294.     The global unsigned (char *)TopObject points to
  295.     the paint stream and is adjusted to the first object
  296.     that appears at the top of the window for an offset
  297.     of h pixels from the start of the document.
  298.     This involves a search thru the paint stream, and
  299.     relies on the objects being ordered wrt increasing
  300.     pixel offset from the start of the document.
  301.     The paint stream is organised as a sequence of nested
  302.     frames, intermingled with text lines.
  303.     The procedure returns the pixel difference between
  304.     the desired position and the current position.
  305. */
  306. Frame *FrameForward(Frame *frame, long top);
  307. Frame *FrameBackward(Frame *frame, long top);
  308. long DeltaHTMLPosition(long h)
  309. {
  310.     long delta;  /* janet 21/07/95; not used:  offset, TopOffset */
  311.     /* janet 21/07/95; not used:    Byte *p, *q; */
  312.     /* janet 21/07/95; not used:    int tag, c1, c2, k; */
  313.     /* janet 21/09/95: not used:    Frame *frame; */
  314.     if (h > PixelOffset)  /* search forwards */
  315.         FrameForward(&background, h);
  316.     else if (h == 0) /* shortcut to start */
  317.     {
  318.         FreeFrames(background.child);
  319.         background.child = NULL;
  320.         background.top = paint + FRAMESTLEN;
  321.     }
  322.     else  /* search backwards */
  323.         FrameBackward(&background, h);
  324.     delta = h - PixelOffset;
  325.     PixelOffset = h;
  326.     return delta;
  327. }
  328. /*
  329.   Move forwards thru frame, adjusting frame->top to last text line
  330.   before top. The routine iterates thru peer frames and recurses
  331.   thru decendent frames. The frame (and its descendents) are removed
  332.   from the peer list if it (and therefore they) finish before top.
  333.   This is implemented by returning the frame if it is needed otherwise
  334.   returning NULL
  335.   Question: what happens when top is the bottom of the buffer?
  336.             can this ever occur in practice, e.g. with a null file?
  337. */
  338. Frame *FrameForward(Frame *frame, long top)
  339. {
  340.     long offset, height;
  341.     unsigned int c1, c2;
  342.     unsigned int width, length, len;
  343.     int tag, indent, style, border;
  344.     unsigned char *p, *p2, *obj;
  345.     Frame *peer, *child, *last;
  346. #ifdef STYLE_COLOR_BORDER
  347.     Byte cb_ix;
  348. #endif
  349.     if (!frame)
  350.         return NULL;
  351.  /* move down each of peer frames */
  352.     peer = FrameForward(frame->next, top);
  353.  /* Does this frame and its descendants end before top ? */
  354.     if (frame->offset + frame->height <= top)
  355.     {
  356.         if (frame == &background) /* should never occur in practice! */
  357.         {
  358.             FreeFrames(background.child);
  359.             background.child = NULL;
  360.             background.top = paint + paintlen;
  361.             return &background; /* never has peers ! */
  362.         }
  363.      /* remove self and any descendents BUT not our peers! */
  364.         frame->next = NULL;  /* unlink from list before freeing */
  365.         FreeFrames(frame);
  366.         return peer;
  367.     }
  368.     frame->next = peer;
  369.     frame->child = FrameForward(frame->child, top);
  370.  /* find last child in list to avoid inserting
  371.     new children in reverse order */
  372.     for (last = frame->child; last; last = last->next)
  373.     {
  374.         if (last->next == NULL)
  375.             break;
  376.     }
  377.     
  378.  /* now move frame->top down until we reach top and insert
  379.     any new children at end of frame->child list */
  380.     p = frame->top;
  381.     p2 = paint + frame->info + FRAMESTLEN + frame->length;
  382.     while (p < p2)
  383.     {
  384.         obj = p;
  385.         tag = *p++;
  386.      /* if frame intersects top then create frame structure
  387.         and find paint position within it (and its children)
  388.         then insert it in front of frame->child list */
  389.         if (tag == BEGIN_FRAME)
  390. {
  391.             c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  392.             c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  393.             if (offset > top)
  394.             {
  395.                 frame->top = obj;
  396.                 break;
  397.             }
  398.          /* otherwise pickup frame header params */
  399.             c1 = *p++; c2 = *p++; indent = c1 | c2<<8;
  400.             c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  401.             c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  402.             c1 = *p++; c2 = *p++; height |= (c1 | c2<<8) << 16;
  403.     style = *p++; border = *p++;
  404. #ifdef STYLE_COLOR_BORDER
  405.     cb_ix = *p++;
  406. #endif
  407. #ifdef STYLE_BACKGROUND
  408.     GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  409. #endif
  410.             c1 = *p++; c2 = *p++; length = c1 | c2<<8;
  411.     if (offset + height > top)
  412.             {
  413.                 child = (Frame *)malloc(sizeof(Frame));
  414.                 child->next = NULL;
  415.                 child->child = NULL;
  416.                 child->offset = offset;
  417.                 child->indent = indent;
  418.                 child->width = width;
  419.                 child->height = height;
  420.                 child->info = obj - paint;
  421.                 child->top = p;  /* == obj + FRAMESTLEN */
  422.                 child->length = length;
  423.                 child->style = style;
  424.                 child->border = border;
  425. child->box_list = NULL;
  426. #ifdef STYLE_COLOR_BORDER
  427.                 child->cb_ix = cb_ix;
  428. #else
  429. child->cb_ix = 0;
  430. #endif
  431.                 FrameForward(child, top);
  432.              /* and insert new child in same order
  433.                 as it appears in paint buffer */
  434.                 if (last)
  435.                     last->next = child;
  436.                 else
  437.                     frame->child = child;
  438.                 last = child;
  439.             }
  440.             p += length+2; /* to skip over frame's contents */
  441.             continue;
  442.         }
  443.      /* the END_FRAME is only used when scrolling backwards */
  444.         if (tag == END_FRAME)
  445.         {
  446.             p += FRAMENDLEN - 1;
  447.             continue;
  448.         }
  449.      /* safety net for garbled paint structure */
  450.         if (tag != TEXTLINE)
  451.         {
  452.             fprintf(stderr, "Unexpected internal tag (1) %dn", tag);
  453.             Exit(1);
  454.         }
  455.       /* stop if textline overlaps top or starts after it */
  456.         c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  457.         c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  458.         if (offset >= top)
  459.         {
  460.             frame->top = obj;
  461.             break;
  462.         }
  463.         p += 4; /* skip over baseline, indent */
  464.         c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  465.         if (offset + height > top)
  466.         {
  467.             frame->top = obj;
  468.             break;
  469.         }
  470.         /* skip elements in text line to reach next object */
  471.         while ((tag = *p++) != '')
  472.         {
  473.             switch (tag & 0xF)
  474.             {
  475.                 case RULE:
  476.                     p += RULEFLEN - 1;
  477.                     break;
  478.                 case LINE:
  479.                     p += LINEFLEN - 1;
  480.                     break;
  481.                 case BULLET:
  482.                     p += BULLETFLEN - 1;
  483.                     break;
  484.                 case STRING:
  485.                     p += STRINGFLEN - 1;
  486.                     break;
  487.                 case SEQTEXT:
  488.     ++p; ++p; /* skip over emph */
  489.                     ++p;       /* skip over font */
  490. #ifdef STYLE_COLOR
  491.     ++p; /* skip over color */
  492. #endif
  493. #ifdef STYLE_BACKGROUND
  494.     p+=POINTERSIZE; /* skip over background --Spif 18-Oct-95 */
  495. #endif
  496.                     ++p; ++p;  /* skip over x position */
  497.                     ++p; ++p;  /* skip over y position */
  498.                     len = *p++;
  499.                     p += len;
  500.                     break;
  501.                 case IMAGE:
  502.                     p += IMAGEFLEN - 1;
  503.                     break;
  504.                 case INPUT:
  505.                     p += INPUTFLEN - 1;
  506.                     break;
  507.                 default:
  508.                     fprintf(stderr, "Unexpected internal tag (2) %dn", tag);
  509. /*                    Exit(1); */
  510.             }
  511.         }
  512.         ++p; ++p;  /* skip over textline size param */
  513.     }
  514.     return frame;
  515. }
  516. /*
  517.   Move backwards thru frame, adjusting frame->top to last text line
  518.   before top. The routine iterates thru peer frames and recurses
  519.   thru decendent frames. The frame (and its descendents) are removed
  520.   from the peer list if it (and therefore they) start at or after top.
  521.   This is implemented by returning the frame if it is needed otherwise
  522.   returning NULL
  523. */
  524. Frame *FrameBackward(Frame *frame, long top)
  525. {
  526.     long offset, height;
  527.     unsigned int c1, c2;
  528.     unsigned int width, length, size; /* janet 21/07/95: not used: len */
  529.     int tag, indent, style, border, k, known;
  530.     unsigned char *p, *p1, *p2, *obj;
  531.     Frame *peer, *child;
  532. #ifdef STYLE_COLOR_BORDER
  533.     Byte cb_ix;
  534. #endif
  535.     if (!frame)
  536.         return NULL;
  537.  /* if this frame starts after top then remove from peer list */
  538.     if (frame->offset >= top)
  539.     {
  540.         if (frame == &background)
  541.         {
  542.             FreeFrames(background.child);
  543.             background.child = NULL;
  544.             background.top = paint + paintlen;
  545.             return &background; /* never has peers ! */
  546.         }
  547.         peer = frame->next;
  548.         frame->next = NULL; /* unlink from list before freeing */
  549.         FreeFrames(frame);
  550.         return FrameBackward(peer, top);
  551.     }
  552.  /* move backwards through peer frames */
  553.     frame->next = FrameBackward(frame->next, top);
  554.  /* move backwards through current children */
  555.     frame->child = FrameBackward(frame->child, top);
  556.  /* now move frame->top back until we reach top and insert
  557.     any new children in front of frame->child list */
  558.     p = TopObject = frame->top;
  559.     p2 = paint + frame->info + FRAMESTLEN;
  560.     while (p > p2)
  561.     {
  562.         /* pop field size into k */
  563.         c2 = *--p; c1 = *--p; k = c1 | c2<<8;
  564.         p -= k;   /* p points to start of previous object */
  565.         obj = p;
  566.         tag = *p++;
  567.         if (tag == BEGIN_FRAME)
  568.         {
  569.             --p;
  570.             continue;
  571.         }
  572.      /* if frame intersects top then create frame structure
  573.         unless it already is one of my children and find
  574.         paint position within it (and its children)
  575.         then insert it in front of frame->child list */
  576.         if (tag == END_FRAME)
  577.         {
  578.             c1 = *p++; c2 = *p++; length = c1 | c2<<8;
  579.             c1 = *p++; c2 = *p++; size = c1 | c2<<8;
  580.             p = obj - (int)length;  /* kludge for bug in HP92453-01 A.09.19 HP C Compiler */
  581.          /* p now points to BEGIN_FRAME tag */
  582.             if (*p != BEGIN_FRAME)
  583.             {
  584.                 fprintf(stderr, "FrameBackward: Unexpected internal tag %d when BEGIN_FRAME was expectedn", tag);
  585.                 Exit(1);
  586.             }
  587.             p1 = p;
  588.          /* check if frame is one of my children, and hence already done */
  589.             for (known = 0, child = frame->child; child; child = child->next)
  590.             {
  591.                 if (child->info == p - paint)
  592.                 {
  593.                     known = 1;
  594.                     break;
  595.                 }
  596.             }
  597.             if (known)
  598.             {
  599.                 p = obj;
  600.                 continue;
  601.             }
  602.             ++p; /* skip over frame tag */
  603.             c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  604.             c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  605.             if (offset >= top)
  606.             {
  607.                 p = obj;
  608.                 continue;
  609.             }
  610.          /* otherwise pickup frame header params */
  611.             c1 = *p++; c2 = *p++; indent = c1 | c2<<8;
  612.             c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  613.             c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  614.             c1 = *p++; c2 = *p++; height |= (c1 | c2<<8) << 16;
  615.             style = *p++; border = *p++;
  616. #ifdef STYLE_COLOR_BORDER
  617.     cb_ix = *p++;
  618. #endif
  619. #ifdef STYLE_BACKGROUND
  620.     GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  621. #endif
  622.     c1 = *p++; c2 = *p++; length = c1 | c2<<8;
  623.             child = (Frame *)malloc(sizeof(Frame));
  624.             child->next = NULL;
  625.             child->child = NULL;
  626.             child->offset = offset;
  627.             child->indent = indent;
  628.             child->width = width;
  629.             child->height = height;
  630.             child->info = p1 - paint;
  631.             child->top = p + length;
  632.             child->length = length;
  633.             child->style = style;
  634.             child->border = border;
  635.     child->box_list = NULL;
  636. #ifdef STYLE_COLOR_BORDER
  637.     child->cb_ix = cb_ix;
  638. #else
  639.     child->cb_ix = 0;
  640. #endif
  641.     child = FrameBackward(child, top);
  642.          /* and insert new child in front of current children */
  643.             child->next = frame->child;
  644.             frame->child = child;
  645.             p = obj;
  646.             continue;
  647.         }
  648.      /* safety net for garbled paint structure */
  649.         if (tag != TEXTLINE)
  650.         {
  651.             fprintf(stderr, "FrameBackward: Unexpected internal tag: %d when TEXTLINE was expectedn", tag);
  652.             Exit(1);
  653.         }
  654.       /* stop if textline overlaps top or starts before it */
  655.         c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  656.         c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  657.         p = obj;
  658.         if (offset < top)
  659.             break;
  660.     }
  661.     frame->top = p;
  662.     return frame;
  663. }
  664. void DrawHButtonUp(int x, int y, int w, int h)
  665. {
  666.     --x; ++y; ++w;  /* adjust drawing position */
  667.     XSetForeground(display, disp_gc, windowTopShadow);
  668.     XFillRectangle(display, win, disp_gc, x, y, w, 1);
  669.     XFillRectangle(display, win, disp_gc, x, y, 1, h-1);
  670.     XSetForeground(display, disp_gc, windowBottomShadow);
  671.     XFillRectangle(display, win, disp_gc, x+1, y+h-1, w-1, 1);
  672.     XFillRectangle(display, win, disp_gc, x+w-1, y+1, 1, h-2);
  673.     XSetForeground(display, disp_gc, textColor);
  674. }
  675. void DrawHButtonDown(int x, int y, int w, int h)
  676. {
  677.     --x; ++y; ++w;  /* adjust drawing position */
  678.     XSetForeground(display, disp_gc, windowBottomShadow);
  679.     XFillRectangle(display, win, disp_gc, x, y, w, 1);
  680.     XFillRectangle(display, win, disp_gc, x, y, 1, h-1);
  681.     XSetForeground(display, disp_gc, windowTopShadow);
  682.     XFillRectangle(display, win, disp_gc, x+1, y+h-1, w-1, 1);
  683.     XFillRectangle(display, win, disp_gc, x+w-1, y+1, 1, h-2);
  684.     XSetForeground(display, disp_gc, textColor);
  685. }
  686. /* Find which object if any is under the mouse at screen coords px, py
  687.   event is one of BUTTONUP, BUTTONDOWN, MOVEUP, MOVEDOWN */
  688. Byte *WhichFrameObject(int event, int indent, int x, int y, Byte *p1, Byte *p2,
  689.                int *type, char **start, char **end, int *dx, int *dy)
  690. {
  691.     char *s;
  692.     Byte *p, *q;
  693.     unsigned int tag, len, emph;
  694.     unsigned int c1, c2;
  695.     int fnt, x1, y1, xi, yb, yi, y2, width, height; /* janet 21/07/95: not used: action, active */
  696.     int style, border, length;
  697.     long offset, str;
  698.     BG_Style *bg_style;
  699. #ifdef STYLE_COLOR_BORDER
  700.     Byte cb_ix;
  701. #endif
  702.     int i; /* for debug only */
  703. /*    x += PixelIndent; */ /* howcome: applied patch from dsr 18/11/94 */
  704.     for (p = p1; p < p2;)
  705.     {
  706.         tag = *p++;
  707.         if (tag == BEGIN_FRAME)
  708.         {
  709.             c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  710.             c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  711.          /* we are done if frame starts after bottom of window */
  712.             y1 = WinTop + (offset - PixelOffset);
  713.             if (y1 >= WinBottom)
  714.                 break;
  715.          /* otherwise pickup frame header params */
  716.             c1 = *p++; c2 = *p++; x1 = c1 | c2<<8;
  717.             c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  718.             c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  719.             c1 = *p++; c2 = *p++; height |= (c1 | c2<<8) << 16;
  720.             style = *p++; border = *p++;
  721. #ifdef STYLE_COLOR_BORDER
  722.     cb_ix = *p++;
  723. #endif
  724. #ifdef STYLE_BACKGROUND
  725.     GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  726. #endif
  727.             c1 = *p++; c2 = *p++; length = c1 | c2<<8;
  728.          /* call self to find target object in this frame */
  729.             q = WhichFrameObject(event, x1, x /* - x1 */, y, p, p + length, /* howcome 25/1/95 */
  730.                                     type, start, end, dx, dy);
  731.             if (q)
  732.                 return q;
  733.             p += length+2; /* to skip over frame's contents */
  734.             continue;
  735.         }
  736.         if (tag == END_FRAME)
  737.         {
  738.             p += FRAMENDLEN - 1;
  739.             continue;
  740.         }
  741.         if (tag != TEXTLINE)
  742.         {
  743.             fprintf(stderr, "Unexpected internal tag (4) %dn", tag);
  744.             Exit(1);
  745.         }
  746.         c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  747.         c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  748.         /* y1 points to top of line */
  749.         y1 = WinTop + (offset - PixelOffset);
  750.         if (y1 > (int) WinBottom)
  751.             break;
  752.         c1 = *p++; c2 = *p++; yb = y1 + (c1 | c2<<8);
  753.         c1 = *p++; c2 = *p++; xi = indent + (c1 | c2<<8);
  754.         c1 = *p++; c2 = *p++; height = (c1 | c2<<8);
  755.         while ((tag = *p++) != '')
  756.         {
  757.             switch (tag & 0xF)
  758.             {
  759.                 case RULE:
  760.                     p += RULEFLEN - 1;
  761.                     break;
  762.                 case LINE:
  763.                     p += LINEFLEN - 1;
  764.                     break;
  765.                 case BULLET:
  766.                     p += BULLETFLEN - 1;
  767.                     break;
  768.                 case STRING:
  769.     c1 = *p++; c2 = *p++; emph = c1 | c2<<8;
  770.                     fnt = *p++;
  771. #ifdef STYLE_COLOR
  772.     color_text_ix = *p++;
  773. #endif
  774. #ifdef STYLE_BACKGROUND
  775.     bg_style=(BG_Style *)GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  776.     if (bg_style)
  777. color_background_ix = (bg_style->flag & S_BACKGROUND_COLOR) ? rgb2ix(0, bg_style->r, bg_style->g, bg_style->b,0) : 255; /* GRR */
  778.     else
  779. color_background_ix = 255;
  780. #endif
  781.                     yi = *p++ - 128;
  782.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);  /* here */
  783.                     c1 = *p++; c2 = *p++; len = c1 | c2<<8;
  784.                     c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  785.     p += POINTERSIZE;
  786.     str = (long)GetPointer(&p); /* only reference */
  787.     
  788.                     height = LineSpacing[fnt];
  789.                     y2 = yb - yi - ASCENT(fnt) - 1;
  790.                     if ((emph & EMPH_ANCHOR) && x1 <= x && y2 <= y &&
  791.                         x < x1 + width && y < y2 + height)
  792.                     {
  793.                         s = (char *)str;
  794.                         while (s > buffer)
  795.                         {
  796.                             --s;
  797.                             if (s[0] == '<' && TOLOWER(s[1]) == 'a' && s[2] <= ' ')
  798.                                 break;
  799.                         }
  800.                         *start = s;    /* used in next stage */
  801.                         s = (char *)str;
  802.                         while (strncasecmp(s, "</a>", 4) != 0)
  803.                         {
  804.                             if (*s == '')
  805.                                 break;
  806.                             ++s;
  807.                         }
  808.                         *end = s;    /* used in next stage */
  809.                         *dx = *dy = -1;
  810.                         *type = TAG_ANCHOR;
  811.                         /* return pointer to start of anchor object */
  812.                         return p - STRINGFLEN;
  813.                     }
  814.                     break;
  815.                 case SEQTEXT:
  816.     p++; p++; /* skip over emph */
  817.                     p++;      /* skip over font */ /* janet: what about putting *p += 3 here? */
  818. #ifdef STYLE_COLOR
  819.     ++p;  /* skip over color */ /* janet p += 2 */
  820. #endif
  821. #ifdef STYLE_BACKGROUND
  822.     p+=POINTERSIZE; /* skip over the background --Spif 18-Oct-95 */
  823. #endif
  824.                     ++p; ++p;  /* skip over x position */ 
  825.                     ++p; ++p;  /* skip over y position */ /* janet: p += 4  */
  826.                     len = *p++;
  827.                     p += len;
  828.                     break;
  829.                 case IMAGE:
  830.                     c1 = *p++; c2 = *p++; y2 = yb - (c1 | c2<<8); /* delta */
  831.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);  /* here */
  832.                     c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  833.                     c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  834.                     
  835.                     if (x1 <= x && y2 <= y && x < x1 + width && y < y2 + height)
  836.                     {
  837.                         p += POINTERSIZE;  /* past pixmap */
  838. str = (long) GetPointer(&p);
  839. #ifdef STYLE_BACKGROUND
  840. GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  841. #endif
  842. if (tag & EMPH_ANCHOR)
  843.                         {
  844.                             *dx = *dy = -1;
  845.     if ((tag & EMPH_INPUT) == EMPH_INPUT) /* --Spif image input */
  846.     {          /* can be removed, as INPUT is ANCHOR || ISMAP... */
  847.         *dx = x - x1;
  848. *dy = y - y2;
  849.                             } 
  850.     else
  851.     {
  852.                                 if (tag & ISMAP)
  853. {
  854.     *dx = x - x1;
  855.     *dy = y - y2;
  856. };
  857.     };
  858.                             s = (char *)str;
  859.     if ((tag & EMPH_INPUT) == EMPH_INPUT) /* --Spif 10-Oct-95 */
  860.     {
  861.         while (s > buffer) /* find input...*/
  862. {
  863.     --s;
  864.     if ( strncasecmp(s, "<input", 6) !=0 )
  865.         break;
  866. }
  867. *start = s;
  868. s = (char *)str;
  869. while ( *s != '>')
  870. {
  871.     if (*s == '')
  872.         break;
  873.     s++;
  874. }
  875. *end = s;
  876. *type = TAG_INPUT; /* ?? */
  877. return p - IMAGEFLEN;
  878.     }
  879.     else
  880.     {
  881.                                 while (s > buffer) /* find anchor... must also find an input...*/
  882. {
  883.     --s;
  884.     if (s[0] == '<' && TOLOWER(s[1]) == 'a' && s[2] <= ' ')
  885.         break;
  886. }
  887. *start = s;    /* used in next stage */
  888. s = (char *)str;
  889. while (strncasecmp(s, "</a>", 4) != 0)
  890. {
  891.     if (*s == '')
  892.         break;
  893.     ++s;
  894. }
  895. *end = s;    /* used in next stage */
  896. *type = TAG_ANCHOR;
  897. return p - IMAGEFLEN;
  898.     }
  899.                         }
  900. else
  901. {
  902.                             if (tag & ISMAP)
  903.     {
  904. *dx = x - x1;
  905. *dy = y - y2;
  906. *start = (char *)str;
  907. *end = (char *)str;
  908. *type = TAG_IMG;
  909. return p - IMAGEFLEN;
  910.     }
  911. }
  912.                     }
  913.                     else
  914.     {
  915. p += 2 * POINTERSIZE; /* past pixmap and buf pointer */
  916. #ifdef STYLE_BACKGROUND
  917. p += POINTERSIZE;
  918. #endif
  919.     }
  920.     break;
  921.                 case INPUT: /* --Spif only text... */
  922.     ClipToWindow();
  923.     str = (long) GetPointer(&p);
  924. #ifdef STYLE_BACKGROUND
  925.     GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  926. #endif
  927.     if (ClickedInField(disp_gc, xi, yb, (Field *)str, x, y, event))
  928.                     {
  929. s = ((Field *)str)->name; /* updating *start --Spif 14-Oct-95 */ 
  930. while (s > buffer)
  931. {
  932.     if ( strncasecmp(s, "<input", 6) ==0 )
  933.         break;
  934.     if ( strncasecmp(s, "<select", 7) ==0 )
  935.         break;
  936.     s--;
  937. }
  938.   *start = s;
  939.   bufptr = s;
  940. while(*s!='>') s++;
  941. *end = s;
  942. *type = TAG_INPUT;
  943. return (p - INPUTFLEN); 
  944.     };
  945.     break;
  946.     
  947.                 default:
  948.                     fprintf(stderr, "Unexpected internal tag (5) %dn", tag);
  949.                     Exit(1);
  950.             }
  951.         }
  952.         ++p; ++p;  /* skip final frame length field */ /* janet: p += 2? , and: is this ever used? */
  953.     }
  954.     return NULL;
  955. }
  956. /* find which hypertext button contains given point */
  957. Byte *WhichObj(Frame *frame, int event, int x, int y,
  958.                int *type, char **start, char **end, int *dx, int *dy)
  959. {
  960.     Byte *p, *q;
  961.     Frame *peer;
  962.     if (frame->child)
  963.     {
  964.         p = WhichObj(frame->child, event, x, y, type, start, end, dx, dy);
  965.         if (p)
  966.             return p;
  967.     }
  968.     for (peer = frame->next; peer; peer = peer->next)
  969.     {
  970.         p = WhichObj(peer, event, x, y, type, start, end, dx, dy);
  971.         if (p)
  972.             return p;
  973.     }
  974.     p = frame->top;
  975.     q = paint + frame->info + FRAMESTLEN + frame->length;
  976.     x += PixelIndent; /* howcome: applied patch from dsr 18/11/94 */
  977.     return WhichFrameObject(event, frame->indent, x - frame->indent, y, p, q, type, start, end, dx, dy);
  978. }
  979. /* find which hypertext button contains given point */
  980. Byte *WhichObject(int event, int x, int y,
  981.                int *type, char **start, char **end, int *dx, int *dy)
  982. {
  983.     if (focus && focus->type == OPTIONLIST &&
  984.                 focus->flags & CHECKED &&
  985.                 ClickedInDropDown(disp_gc, focus, -1, event, x, y))
  986.     {
  987.         *type = TAG_SELECT;
  988.         *start = *end = focus->name;
  989.         return paint + focus->object;
  990.     }
  991.     return WhichObj(&background, event, x, y, type, start, end, dx, dy);
  992. }
  993. /* drawn anchors in designated state */
  994. void DrawFrameAnchor(int up, int indent, Byte *start, Byte *end)
  995. {
  996.     char *s;
  997.     Byte *p;
  998.     unsigned int tag, len, emph;
  999.     unsigned int c1, c2;
  1000.     int fnt, x1, y1, xi, y2, yi, yb, width, height; /* janet 21/07/95: not used: action*/
  1001.     int style, border, length;
  1002.     long offset, str;
  1003.     BG_Style *bg_style;
  1004. #ifdef STYLE_COLOR_BORDER
  1005.     Byte cb_ix;
  1006. #endif
  1007.     displayRect.x = WinLeft;
  1008.     displayRect.y = WinTop;
  1009.     displayRect.width = WinWidth;
  1010.     displayRect.height = WinHeight;
  1011.     XSetClipRectangles(display, disp_gc, 0, 0, &displayRect, 1, Unsorted);
  1012.     for (p = start; p < end;)
  1013.     {
  1014.         tag = *p++;
  1015.         if (tag == BEGIN_FRAME)
  1016.         {
  1017.            c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  1018.             c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  1019.          /* we are done if frame starts after bottom of window */
  1020.             y1 = WinTop + (offset - PixelOffset);
  1021.             if (y1 >= WinBottom)
  1022.                 break;
  1023.          /* otherwise pickup frame header params */
  1024.             c1 = *p++; c2 = *p++; x1 = c1 | c2<<8;
  1025.             c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  1026.             c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  1027.             c1 = *p++; c2 = *p++; height |= (c1 | c2<<8) << 16;
  1028.     style = *p++; border = *p++;
  1029. #ifdef STYLE_COLOR_BORDER
  1030.     cb_ix = *p++;
  1031. #endif
  1032. #ifdef STYLE_BACKGROUND
  1033.     bg_style = (BG_Style *)GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  1034. #endif 
  1035.             c1 = *p++; c2 = *p++; length = c1 | c2<<8;
  1036.          /* call self to draw anchors in this frame */
  1037.             DrawFrameAnchor(up, x1, p, p + length);
  1038.             p += length+2; /* to skip over frame's contents */
  1039.             continue;
  1040.         }
  1041.         if (tag == END_FRAME)
  1042.         {
  1043.             p += FRAMENDLEN - 1;
  1044.             continue;
  1045.         }
  1046.         if (tag != TEXTLINE)
  1047.         {
  1048.             fprintf(stderr, "Unexpected internal tag (6) %dn", tag);
  1049.             Exit(1);
  1050.         }
  1051.         c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  1052.         c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  1053.         /* y1 points to top of line */
  1054.         y1 = WinTop + (offset - PixelOffset);
  1055.         if (y1 > (int) WinBottom)
  1056.             break;
  1057.         c1 = *p++; c2 = *p++; yb = y1 + (c1 | c2<<8);
  1058.         c1 = *p++; c2 = *p++; xi = (c1 | c2<<8) - PixelIndent;
  1059.         c1 = *p++; c2 = *p++; height = (c1 | c2<<8);
  1060.         xi += indent;
  1061.         while ((tag = *p++) != '')
  1062.         {
  1063.             switch (tag & 0xF)
  1064.             {
  1065.                 case RULE:
  1066.                     p += RULEFLEN - 1;
  1067.                     break;
  1068.                 case LINE:
  1069.                     p += LINEFLEN - 1;
  1070.                     break;
  1071.                 case BULLET:
  1072.                     p += BULLETFLEN - 1;
  1073.                     break;
  1074.                 case STRING:
  1075.                     c1 = *p++; c2 = *p++; emph = c1 | c2<<8;
  1076.                     fnt = *p++;
  1077. #ifdef STYLE_COLOR
  1078.     color_text_ix = *p++;
  1079. #endif
  1080. #ifdef STYLE_BACKGROUND
  1081.     bg_style=(BG_Style *)GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  1082.     if(bg_style)
  1083. color_background_ix = (bg_style->flag & S_BACKGROUND_COLOR) ? rgb2ix(0, bg_style->r, bg_style->g, bg_style->b,0) : 255; /* GRR */
  1084.     else
  1085. color_background_ix = 255;  
  1086. #endif
  1087.                     yi = *p++ - 128;
  1088.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);  /* here */
  1089.                     c1 = *p++; c2 = *p++; len = c1 | c2<<8;
  1090.                     c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  1091.     str = (long)GetPointer(&p);
  1092.     p += POINTERSIZE; /* skip the reference pointer */
  1093. #ifdef STYLE_COLOR
  1094.     font = fnt;
  1095.     SetColor(disp_gc, color_text_ix, color_background_ix);
  1096.     SetFont(disp_gc, font);
  1097. #else
  1098.                     if (font != fnt)
  1099.                     {
  1100.                         font = fnt;
  1101.                         SetFont(disp_gc, font);
  1102.                     }
  1103. #endif
  1104.                     height = LineSpacing[font];
  1105.                     y2 = yb - yi - ASCENT(font) - 1;
  1106.                     if (emph & EMPH_ANCHOR) 
  1107.                     {
  1108.                         s = (char *)str;
  1109.                         if (anchor_start <= s && s <= anchor_end)
  1110.                         {
  1111.                             if (up)
  1112.                                 DrawHButtonUp(x1, y2, width, height);
  1113.                             else
  1114.                                 DrawHButtonDown(x1, y2, width, height);
  1115.                         }
  1116.                     }
  1117.                     break;
  1118.                 case SEQTEXT:
  1119.     p++; p++; /* skip over emph */
  1120.                     p++;      /* skip over font */ /* janet: what about putting *p += 3 here? */
  1121. #ifdef STYLE_COLOR
  1122.     ++p;  /* skip over color */ /* janet p += 2 */
  1123. #endif
  1124. #ifdef STYLE_BACKGROUND
  1125.     p+=POINTERSIZE; /* skip over background */
  1126. #endif
  1127.                     ++p; ++p;  /* skip over x position */ 
  1128.                     ++p; ++p;  /* skip over y position */ /* janet: p += 4  */
  1129.                     len = *p++;
  1130.                     p += len;
  1131.                     break;
  1132.                 case IMAGE:
  1133.                     c1 = *p++; c2 = *p++; y2 = yb - (c1 | c2<<8);
  1134.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);  /* here */
  1135.                     c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  1136.                     c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  1137.                     p += POINTERSIZE;  /* past pixmap id */
  1138.     s = (char *)GetPointer(&p);
  1139. #ifdef STYLE_BACKGROUND
  1140.     p += POINTERSIZE; /* skip background */
  1141. #endif
  1142.       
  1143.                     if (tag & ISMAP && anchor_start == s)
  1144.                     {
  1145.                         x1 -= PixelIndent;
  1146.                         if (up)
  1147.                         {
  1148.                             DrawOutSet(win, disp_gc, x1, y2, width, height);
  1149.                             XSetForeground(display, disp_gc, textColor);
  1150.                             DrawHButtonDown(x1+4, y2+2, width-7, height-6);
  1151.                         }
  1152.                         else
  1153.                         {
  1154.                             DrawInSet(win, disp_gc, x1, y2, width, height);
  1155.                             XSetForeground(display, disp_gc, textColor);
  1156.                             DrawHButtonUp(x1+4, y2+2, width-7, height-6);
  1157.                         }
  1158.                         width -= 8;
  1159.                         height -= 8;
  1160.                         x1 += 4;
  1161.                         y2 += 4;
  1162.                     }
  1163.                     break;
  1164.                 case INPUT:
  1165.   /* --Spif 13-Oct-95 take care of this...it may be the cause of crashes */
  1166.                     p += INPUTFLEN - 1;
  1167.                     break;
  1168.                 default:
  1169.                     fprintf(stderr, "Unexpected internal tag (7) %dn", tag);
  1170.                     Exit(1);
  1171.             }
  1172.         }
  1173.         ++p; ++p;  /* skip final frame length field */
  1174.     }
  1175.     XFlush(display);
  1176. }
  1177. void DrawAnchor(Frame *frame, int state)
  1178. {
  1179.     Byte *start, *end;
  1180.     Frame *peer;
  1181.     if (frame->child)
  1182.         DrawAnchor(frame->child, state);
  1183.     for (peer = frame->next; peer; peer = peer->next)
  1184.         DrawAnchor(peer, state);
  1185.     start = frame->top;
  1186.     end = paint + frame->info + FRAMESTLEN + frame->length;
  1187.     DrawFrameAnchor(state, frame->indent, start, end);
  1188. }
  1189. /* find topmost object's pointer to the html buffer */
  1190. char *TopStrSelf(Byte *start, Byte *end)
  1191. {
  1192.     Byte *p;
  1193.     char *s;
  1194.     unsigned int tag, len, emph, fnt;
  1195.     unsigned int c1, c2;
  1196.     int style, border, length, x1, y1, xi, yb, yi, width, height; /* janet 21/07/95: not used: action, y2 */
  1197.     long offset, str;
  1198. #ifdef STYLE_COLOR_BORDER
  1199.     Byte cb_ix;
  1200. #endif
  1201.     for (p = start; p < end;)
  1202.     {
  1203.         tag = *p++;
  1204.         if (tag == BEGIN_FRAME)
  1205.         {
  1206.             c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  1207.             c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  1208.             c1 = *p++; c2 = *p++; x1 = c1 | c2<<8;
  1209.             c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  1210.             c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  1211.             c1 = *p++; c2 = *p++; height |= (c1 | c2<<8) << 16;
  1212.             style = *p++; border = *p++;
  1213. #ifdef STYLE_COLOR_BORDER
  1214.     cb_ix = *p++;
  1215. #endif
  1216. #ifdef STYLE_BACKGROUND
  1217.     GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  1218. #endif
  1219.             c1 = *p++; c2 = *p++; length = c1 | c2<<8;
  1220.             if ((s = TopStrSelf(p, p + length)))
  1221.                 return s;
  1222.             p += length+2; /* to skip over frame's contents */
  1223.             continue;
  1224.         }
  1225.         if (tag == END_FRAME)
  1226.         {
  1227.             p += FRAMENDLEN - 1;
  1228.             continue;
  1229.         }
  1230.         if (tag != TEXTLINE)
  1231.         {
  1232.             fprintf(stderr, "Unexpected internal tag (8) %dn", tag);
  1233.             Exit(1);
  1234.         }
  1235.         c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  1236.         c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  1237.         /* y1 points to top of line */
  1238.         y1 = WinTop + (offset - PixelOffset);
  1239.         if (y1 > (int) WinBottom)
  1240.             break;
  1241.         c1 = *p++; c2 = *p++; yb = y1 + (c1 | c2<<8);
  1242.         c1 = *p++; c2 = *p++; xi = (c1 | c2<<8);
  1243.         c1 = *p++; c2 = *p++; height = (c1 | c2<<8);
  1244.         while ((tag = *p++) != '')
  1245.         {
  1246.             switch (tag & 0xF)
  1247.             {
  1248.                 case RULE:
  1249.                     p += RULEFLEN - 1;
  1250.                     break;
  1251.                 case LINE:
  1252.                     p += LINEFLEN - 1;
  1253.                     break;
  1254.                 case BULLET:
  1255.                     p += BULLETFLEN - 1;
  1256.                     break;
  1257.                 case STRING:
  1258.                     c1 = *p++; c2 = *p++; emph = c1 | c2<<8;
  1259.                     fnt = *p++;
  1260. #ifdef STYLE_COLOR
  1261.     p++; /* skip over color */
  1262. #endif
  1263. #ifdef STYLE_BACKGROUND
  1264.     p+=POINTERSIZE; /* --Spif 20-Oct-95 skip over style background */
  1265. #endif
  1266.                     yi = *p++ - 128;
  1267.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);  /* here */
  1268.                     c1 = *p++; c2 = *p++; len = c1 | c2<<8;
  1269.                     c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  1270.     p += POINTERSIZE; 
  1271.     str = (long)GetPointer(&p);
  1272.                     return (char *)str; /* return (char *)GetPointer(&p); ??? */
  1273.                 case SEQTEXT:
  1274.     ++p; ++p;  /* skip over emph */
  1275.                     ++p;       /* skip over font */
  1276. #ifdef STYLE_COLOR
  1277.     ++p; /* skip over color */
  1278. #endif
  1279. #ifdef STYLE_BACKGROUND
  1280.     p+=POINTERSIZE; /* skip over background -_Spif 20-Oct-95 */
  1281. #endif
  1282.                     ++p; ++p;  /* skip over x position */
  1283.                     ++p; ++p;  /* skip over y position */
  1284.                     len = *p++;
  1285.                     p += len;
  1286.                     break;
  1287.                 case IMAGE:
  1288.                     p += IMAGEFLEN - 1;
  1289.                     break;
  1290.                 case INPUT:
  1291.                     p += INPUTFLEN - 1;
  1292.                     break;
  1293.                 default:
  1294.                     fprintf(stderr, "Unexpected internal tag (9) %dn", tag);
  1295.                     Exit(1);
  1296.             }
  1297.         }
  1298.         ++p; ++p;  /* skip final frame length field */ /* janet: p += 2? , and: is this ever used? */
  1299.     }
  1300.     return NULL;
  1301. }
  1302. char *TopStr(Frame *frame)
  1303. {
  1304.     Frame *peer;
  1305.     char *s;
  1306.     Byte *start, *end;
  1307.     if (frame->child && (s = TopStr(frame->child)))
  1308.         return s;
  1309.     for (peer = frame->next; peer; peer = peer->next)
  1310.         if ((s = TopStr(peer)))
  1311.             return s;
  1312.     start = frame->top;
  1313.     end = paint + frame->info + FRAMESTLEN + frame->length;
  1314.     return TopStrSelf(start, end);
  1315. }
  1316. void ClipToWindow(void)
  1317. {
  1318.     displayRect.x = WinLeft;
  1319.     displayRect.y = WinTop;
  1320.     displayRect.width = WinWidth;
  1321.     displayRect.height = WinHeight;
  1322.     XSetClipRectangles(display, disp_gc, 0, 0, &displayRect, 1, Unsorted);
  1323. /*    XSetClipRectangles(display, gc_fill, 0, 0, &displayRect, 1, Unsorted); -- tracking */
  1324. }
  1325. void DrawBorder(int border, int x, int y, unsigned int w, unsigned int h, Byte cb_ix)
  1326. {
  1327. #ifdef STYLE_COLOR_BORDER
  1328.     if (cb_ix < 128) {
  1329. XSetForeground(display, disp_gc, stdcmap[cb_ix]);
  1330.     } else if (cb_ix < 144) {
  1331. XSetForeground(display, disp_gc, greymap[cb_ix & 0xf]);
  1332.     }
  1333. #endif
  1334.     XFillRectangle(display, win, disp_gc, x, y, w, 1);
  1335.     XFillRectangle(display, win, disp_gc, x+w, y, 1, h);
  1336.     XFillRectangle(display, win, disp_gc, x, y+h, w, 1);
  1337.     XFillRectangle(display, win, disp_gc, x, y, 1, h);
  1338. }
  1339. void FreeBox(box_link *box_list)
  1340. {
  1341.     box_link *current_link;
  1342.     box_link *next_link;
  1343.     if(!box_list)
  1344. return;
  1345.     current_link = box_list;
  1346.     next_link = box_list->next;
  1347.     
  1348.     while(next_link)
  1349.     {
  1350. Free(current_link->box);
  1351. Free(current_link);
  1352. current_link = next_link;
  1353. next_link = next_link->next;
  1354.     }
  1355.     Free(current_link->box);
  1356.     Free(current_link);
  1357. }
  1358. /* free frame structures except for background frame */
  1359. void FreeFrames(Frame *frame)
  1360. {
  1361.   /* janet 21/07/95    Frame *peer; */
  1362.     if (frame)
  1363.     {
  1364. /*
  1365.    patch from Kai.Arstila@Helsinki.FI replaces
  1366.         FreeFrames(frame->child);
  1367.         for (peer = frame->next; peer; peer = peer->next)
  1368.              FreeFrames(peer);
  1369.         Free(frame);
  1370.    with:
  1371. */
  1372.         if(frame->child)   
  1373.                 FreeFrames(frame->child);
  1374.         if(frame->next)   
  1375.                 FreeFrames(frame->next);
  1376.         FreeBox(frame->box_list);
  1377. Free(frame);
  1378. /* end replacement */
  1379.     }
  1380. }
  1381. void PaintSelf(Frame *frame, int y, unsigned int h);
  1382. void PaintPeers(Frame *frame, int y, unsigned int h);
  1383. void PaintFrame(Window w,unsigned char *p, unsigned char *p_end, int x, int y, unsigned int h);
  1384. void DisplayHTML(int x, int y, unsigned int w, unsigned int h)
  1385. {
  1386.     long count = 0;
  1387.     BG_Style *bg_style;
  1388.     unsigned char *p;
  1389.     GC gc_bg;
  1390.     XGCValues values;
  1391.     unsigned int valuemask;
  1392.     XRectangle frameRect;
  1393.     if (UsePaper)
  1394.        XSetTSOrigin(display, gc_fill,
  1395.             -PixelIndent % tileHeight, -(int)(PixelOffset % tileHeight));
  1396.  /* make absolutely certain we don't overwrite the scrollbar */
  1397.     if (w > WinWidth)
  1398.         w = WinWidth;
  1399.     if (y < WinTop)
  1400.     {
  1401.         h -= (WinTop - y);
  1402.         y = WinTop;
  1403.         if (h <= 0)
  1404.             return;
  1405.     }
  1406.  /* make absolutely certain we don't overwrite the status bar */
  1407.     if (y + h > WinBottom)
  1408.     {
  1409.         h = WinBottom - y;
  1410.         if (h <= 0)
  1411.             return;
  1412.     }
  1413.  /* the text must be clipped to avoid running over into adjacent
  1414.     regions, i.e. the scrollbar at the rhs */
  1415.     displayRect.x = x;
  1416.     displayRect.y = y;
  1417.     displayRect.width = w;
  1418.     displayRect.height = h;
  1419.     XSetClipRectangles(display, disp_gc, 0, 0, &displayRect, 1, Unsorted);
  1420.     XSetClipRectangles(display, gc_fill, 0, 0, &displayRect, 1, Unsorted);
  1421.     /* howcome 25/4/95 */
  1422.     FormatElementStart(TAG_HTML, NULL, 0);
  1423. #ifdef STYLE_BACKGROUND
  1424.     p = paint + 15; /* --Spif 25-Oct-95 offset to style_bckng pointer */
  1425.     bg_style=(BG_Style *)GetPointer(&p);
  1426.     if(bg_style)
  1427.     {
  1428. if(bg_style->flag & S_BACKGROUND_COLOR) /* background color */
  1429. {
  1430.     /* if(!((bg_style->image) && (bg_style->flag & S_BACKGROUND_X_REPEAT) && (bg_style->flag & S_BACKGROUND_Y_REPEAT)))
  1431.      */{
  1432. XSetForeground(display, disp_gc, rgb2color(0, bg_style->r, bg_style->g, bg_style->b,0)); 
  1433. XFillRectangle(display, win, disp_gc, x,y,w,h);
  1434.     } 
  1435. }
  1436. else
  1437.     XFillRectangle(display, win, gc_fill, x,y,w,h);
  1438. if(bg_style->flag & S_BACKGROUND_IMAGE) /* background image */
  1439. {
  1440.     if(bg_style->image)
  1441.     {
  1442. gc_bg = XCreateGC(display, win,0,NULL);
  1443. XCopyGC(display,gc_fill,0xFFFF,gc_bg);
  1444. valuemask = GCTile|GCFillStyle|GCTileStipXOrigin|GCTileStipYOrigin;
  1445. values.fill_style = FillTiled;
  1446. values.tile = bg_style->image->pixmap;
  1447. if(bg_style->flag & S_BACKGROUND_ORIGIN)
  1448. {
  1449.     if(bg_style->flag & S_BACKGROUND_FIXED)
  1450.     {
  1451. values.ts_x_origin = bg_style->x_pos*(WinWidth-bg_style->image->width)/100;
  1452. values.ts_y_origin = bg_style->y_pos*(WinHeight-bg_style->image->height)/100 + WinTop;
  1453.     }
  1454.     else
  1455.     {
  1456. values.ts_x_origin = bg_style->x_pos*(WinWidth-bg_style->image->width)/100 -PixelIndent;
  1457. values.ts_y_origin = bg_style->y_pos*(WinHeight-bg_style->image->height)/100 + WinTop - PixelOffset;
  1458.     };
  1459. }
  1460. else
  1461. {
  1462.     if(bg_style->flag & S_BACKGROUND_FIXED)
  1463.     {
  1464. values.ts_x_origin = 0;
  1465. values.ts_y_origin = WinTop;
  1466.     }
  1467.     else
  1468.     {
  1469. values.ts_x_origin = -PixelIndent;
  1470. values.ts_y_origin = WinTop - PixelOffset;
  1471.     }
  1472. }
  1473. XChangeGC(display, gc_bg, valuemask, &values);
  1474. if(bg_style->flag & S_BACKGROUND_Y_REPEAT)
  1475. {
  1476.     frameRect.y      = WinTop;
  1477.     frameRect.height = WinHeight;
  1478. }
  1479. else
  1480. {
  1481.     frameRect.y      = values.ts_y_origin;
  1482.     frameRect.height = bg_style->image->height; 
  1483. }
  1484. if(bg_style->flag & S_BACKGROUND_X_REPEAT)
  1485. {
  1486.     frameRect.x = WinLeft;
  1487.     frameRect.width = WinWidth;
  1488. }
  1489. else
  1490. {
  1491.     frameRect.x = values.ts_x_origin;
  1492.     frameRect.width = bg_style->image->width;
  1493. }
  1494. XSetClipRectangles(display, gc_bg, 0, 0,&frameRect, 1, Unsorted); 
  1495. XFillRectangle(display, win, gc_bg, x, y, w, h);
  1496. XFreeGC(display, gc_bg);
  1497.     }
  1498.     else
  1499. if(!(bg_style->flag & (S_BACKGROUND_COLOR))) /* use paper if no pixmap and color */
  1500.     XFillRectangle(display, win, gc_fill, x, y, w, h);
  1501. }
  1502. if(!(bg_style->flag & (S_BACKGROUND_COLOR |S_BACKGROUND_IMAGE)))
  1503.     XFillRectangle(display, win, gc_fill, x, y, w, h);
  1504.     } else 
  1505. XFillRectangle(display, win, gc_fill, x, y, w, h);
  1506. #else
  1507.     count = StyleGet(S_BACKGROUND);
  1508.     if (count == 255) { /* i.e. is the background transparent? */
  1509. XFillRectangle(display, win, gc_fill, x, y, w, h);
  1510.     } else {
  1511. XSetForeground(display, disp_gc, ix2color(count));
  1512. XSetFillStyle(display, disp_gc, FillSolid);
  1513. XFillRectangle(display, win, disp_gc, x, y, w, h);
  1514.     } 
  1515. #endif
  1516.     FormatElementEnd();
  1517.  /* and paint all frames intersecting top of window */
  1518.     PaintSelf(&background, y, h);
  1519.     if (focus && focus->type == OPTIONLIST && focus->flags & CHECKED)
  1520.         PaintDropDown(disp_gc, focus, -1);
  1521. }
  1522. /* paint children then self - first called for background frame */
  1523. void PaintSelf(Frame *frame, int y, unsigned int h)
  1524. {
  1525.     long y1;
  1526.     unsigned char *p1, *p2;
  1527.     /* Test that this frame is at least partly visible */
  1528.     y1 = PixelOffset + y - WinTop;   /* pixel offset for screen coord y */
  1529.     if (frame->offset < y1 + h && frame->offset + frame->height > y1)
  1530.     {
  1531.         if (frame->child)
  1532.             PaintPeers(frame->child, y, h);
  1533.         if (frame->border)
  1534.         {
  1535.             DrawBorder(frame->border, frame->indent-PixelIndent,
  1536.                                WinTop + (frame->offset - PixelOffset),
  1537.                                frame->width, frame->height, frame->cb_ix);
  1538.         }
  1539. if (TAG_TRACE)
  1540. #if defined PRINTF_HAS_PFORMAT
  1541.     fprintf(stderr,"html.c: PaintSelf p1 = frame->top = %p, info = %d, lenght = %dn",
  1542. #else
  1543.     fprintf(stderr,"html.c: PaintSelf p1 = frame->top = %lx, info = %d, lenght = %dn",
  1544. #endif /* PRINTF_HAS_PFORMAT */
  1545.     frame->top, frame->info, frame->length);
  1546.         p1 = frame->top;
  1547.         p2 = paint + frame->info + FRAMESTLEN + frame->length;
  1548.         PaintFrame(win,p1, p2, frame->indent, y, h);
  1549.     }
  1550. }
  1551. /* paint list of peer frames */
  1552. void PaintPeers(Frame *frame, int y, unsigned int h)
  1553. {
  1554.     while (frame)
  1555.     {
  1556.         PaintSelf(frame, y, h);
  1557.         frame = frame->next;
  1558.     }
  1559. }
  1560. /*
  1561.     p, p_end point to paint buffer while x,y,w,h define region to paint
  1562.     This routine recursively calls itself to paint nested frames when
  1563.     it comes across the BEGIN_FRAME tag. Note that the border for the
  1564.     current frame is already drawn - and saves having to pass the
  1565.     relevant params to this routine.
  1566. */
  1567. void PaintFrame(Window w,unsigned char *p, unsigned char *p_end, int x, int y, unsigned int h)
  1568. {
  1569.     char *s;
  1570.     unsigned int tag, len, width;
  1571.     unsigned int c1, c2;
  1572.     int fnt, fnt_size, x1, y1, x2, y2, xi, yb, yi, depth, tmp; /* janet 21/07/95: not used: action, active */
  1573.     unsigned int emph;
  1574.     int style, border, length;
  1575.     long offset, height, str;
  1576.     BG_Style *bg_style;
  1577. #ifdef STYLE_COLOR_BORDER
  1578.     Byte cb_ix;
  1579. #endif
  1580.     GC gc_bg = NULL;
  1581.     XGCValues values;
  1582.     unsigned int valuemask;
  1583.     Pixmap bg_pixmap = NULL;
  1584.     XRectangle frameRect,bgRect;
  1585.     int dirtyscroll;
  1586.     dirtyscroll=0;
  1587.     displayRect.x = WinLeft;
  1588.     displayRect.y = WinTop;
  1589.     displayRect.width = WinWidth;
  1590.     displayRect.height = WinHeight;
  1591.     if (TAG_TRACE)
  1592. #if defined PRINTF_HAS_PFORMAT
  1593. fprintf(stderr,"html.c: PaintFrame %pn",p);
  1594. #else
  1595. fprintf(stderr,"html.c: PaintFrame %lxn",p);
  1596. #endif /* PRINTF_HAS_PFORMAT */
  1597.     while (p < p_end)
  1598.     {
  1599.         if (p >= paint + paintlen)
  1600.         {
  1601.             fprintf(stderr, "Panic: ran off end of paint buffer!n");
  1602.     Exit(1);
  1603.         }
  1604. if (TAG_TRACE && VERBOSE_TRACE)
  1605. #if defined PRINTF_HAS_PFORMAT
  1606.     fprintf(stderr,"PaintFrame: tag %d read from %p, p_end = %pn",*p, p, p_end);
  1607. #else
  1608.     fprintf(stderr,"PaintFrame: tag %d read from %lx, p_end = %lxn",*p, p, p_end);
  1609. #endif /* PRINTF_HAS_PFORMAT */
  1610.         tag = *p++;
  1611.         if (tag == BEGIN_FRAME)
  1612.         {
  1613.             c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  1614.             c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  1615.          /* we are done if frame starts after bottom of window */
  1616.             y1 = WinTop + (offset - PixelOffset);
  1617.     /*   
  1618.     if (y1 >= y + (int)h)
  1619.                 break; 
  1620.     */
  1621.          /* otherwise pickup frame header params */
  1622.             c1 = *p++; c2 = *p++; x1 = c1 | c2<<8;
  1623.             c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  1624.             c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  1625.             c1 = *p++; c2 = *p++; height |= (c1 | c2<<8) << 16;
  1626.     style = *p++; border = *p++;
  1627. #ifdef STYLE_COLOR_BORDER
  1628.     cb_ix = *p++;
  1629. #endif
  1630. #ifdef STYLE_BACKGROUND
  1631.     bg_style=(BG_Style *)GetPointer(&p);
  1632.     if(bg_style)
  1633.     {
  1634. if(bg_style->flag & S_BACKGROUND_COLOR) /* background color */
  1635. {
  1636.     XSetForeground(display, disp_gc, rgb2color(0, bg_style->r, bg_style->g, bg_style->b,0)); 
  1637.     if(bg_style->flag & S_BACKGROUND_IMAGE)
  1638.     {
  1639. if(!((bg_style->image) && (bg_style->flag & S_BACKGROUND_X_REPEAT) && (bg_style->flag & S_BACKGROUND_Y_REPEAT)))
  1640.     XFillRectangle(display, w, disp_gc,x1-PixelIndent, y1 , width, height);
  1641.     }
  1642.     else
  1643. XFillRectangle(display, w, disp_gc,x1-PixelIndent, y1 , width, height);
  1644. }   
  1645. if(bg_style->flag & S_BACKGROUND_IMAGE) /* bacground image */
  1646. {
  1647.     if(bg_style->image)
  1648.     {
  1649. dirtyscroll = 1;
  1650. frameRect.x = x1;
  1651. frameRect.y = y1;
  1652. frameRect.width = (frameRect.x+width < WinLeft+WinWidth) ? width : width+x-frameRect.x;
  1653. frameRect.height = (frameRect.y+height < WinTop+WinHeight) ? height : height+y-frameRect.y;
  1654. bg_pixmap = XCreatePixmap(display, RootWindow(display, screen),WinWidth+WinLeft,WinHeight+WinTop,DefaultDepth(display,screen));
  1655. gc_bg = XCreateGC(display, w,0,NULL);
  1656. XCopyGC(display,gc_fill,0xFFFF,gc_bg);
  1657. valuemask = GCTile|GCFillStyle|GCGraphicsExposures|GCTileStipXOrigin|GCTileStipYOrigin;
  1658. values.tile = bg_style->image->pixmap;
  1659. values.fill_style = FillTiled;
  1660. values.graphics_exposures = FALSE;
  1661. if(bg_style->flag & S_BACKGROUND_ORIGIN)
  1662. {
  1663.     if(bg_style->flag & S_BACKGROUND_FIXED)
  1664.     {
  1665. values.ts_x_origin = bg_style->x_pos*(WinWidth-bg_style->image->width)/100;
  1666. values.ts_y_origin = bg_style->y_pos*(WinHeight-bg_style->image->height)/100 + WinTop;
  1667.     }
  1668.     else
  1669.     {
  1670. values.ts_x_origin = bg_style->x_pos*(WinWidth-bg_style->image->width)/100 -PixelIndent;
  1671. values.ts_y_origin = bg_style->y_pos*(WinHeight-bg_style->image->height)/100 + WinTop - PixelOffset;
  1672.     };
  1673. }
  1674. else
  1675. {
  1676.     if(bg_style->flag & S_BACKGROUND_FIXED)
  1677.     {
  1678. values.ts_x_origin = 0;
  1679. values.ts_y_origin = WinTop;
  1680.     }
  1681.     else
  1682.     {
  1683. values.ts_x_origin = -PixelIndent;
  1684. values.ts_y_origin = WinTop - PixelOffset;
  1685.     }
  1686. }
  1687. XChangeGC(display, gc_bg, valuemask, &values);
  1688. XSetClipRectangles(display, disp_gc, 0, 0, &frameRect, 1, Unsorted);
  1689. XSetClipRectangles(display, gc_fill, 0, 0, &frameRect, 1, Unsorted);
  1690. if(bg_style->flag & S_BACKGROUND_COLOR)
  1691.     XFillRectangle(display, bg_pixmap, disp_gc,x1-PixelIndent, y1 , width, height);
  1692. else
  1693.     XFillRectangle(display, bg_pixmap, gc_fill,x1-PixelIndent, y1 , width, height);
  1694. if(bg_style->flag & S_BACKGROUND_Y_REPEAT)
  1695. {
  1696.     bgRect.y      = WinTop;
  1697.     bgRect.height = WinHeight;
  1698. }
  1699. else
  1700. {
  1701.     bgRect.y      = values.ts_y_origin;
  1702.     bgRect.height = bg_style->image->height; 
  1703. }
  1704. if(bg_style->flag & S_BACKGROUND_X_REPEAT)
  1705. {
  1706.     bgRect.x = WinLeft;
  1707.     bgRect.width = WinWidth;
  1708. }
  1709. else
  1710. {
  1711.     bgRect.x = values.ts_x_origin;
  1712.     bgRect.width = bg_style->image->width;
  1713. }
  1714. XSetClipRectangles(display, gc_bg, 0, 0,&bgRect, 1, Unsorted); 
  1715. XFillRectangle(display, bg_pixmap, gc_bg, x1-PixelIndent, y1 , width, height);
  1716. XSetClipRectangles(display, gc_bg, 0, 0, &frameRect, 1, Unsorted);
  1717.     }
  1718.     else
  1719. if(!(bg_style->flag & (S_BACKGROUND_COLOR))) /* use paper if no pixmap and color */
  1720.    XFillRectangle(display, w, gc_fill, x1-PixelIndent, y1 , width, height);
  1721. }
  1722. if(!(bg_style->flag & (S_BACKGROUND_COLOR |S_BACKGROUND_IMAGE)))
  1723.     XFillRectangle(display, w, gc_fill,x1-PixelIndent, y1 , width, height);
  1724.     };
  1725. #endif
  1726.             c1 = *p++; c2 = *p++; length = c1 | c2<<8;
  1727.     /* printf("BEGIN_FRAME %xh (x1 %d, y1 %d, width %d, height %d, length %dn",(p-12),x1,y1,width,height,length);  
  1728.      */
  1729.     
  1730.          /* call self to paint this frame */
  1731.     
  1732.     if(dirtyscroll && bg_style)
  1733.     {
  1734. PaintFrame(bg_pixmap, p, p + length, x1, y, h);
  1735.     }
  1736. else
  1737.     PaintFrame(w, p, p + length, x1, y, h);
  1738.     p += length+2; /* to skip over frame's contents */
  1739.     if(dirtyscroll && bg_style)
  1740.     {
  1741. XCopyGC(display,gc_fill,0xFFFF,gc_bg);
  1742. valuemask = GCGraphicsExposures;
  1743. valuemask |= GCTile|GCFillStyle;
  1744. values.tile = bg_style->image->pixmap; 
  1745. values.fill_style = FillTiled;
  1746. values.graphics_exposures = 0;
  1747. XChangeGC(display, gc_bg, valuemask, &values);
  1748. XSetClipRectangles(display, disp_gc, 0, 0, &displayRect, 1, Unsorted);
  1749. XSetClipRectangles(display, gc_fill, 0, 0, &displayRect, 1, Unsorted); 
  1750. XSetClipRectangles(display, gc_bg, 0, 0, &displayRect, 1, Unsorted);
  1751. XCopyArea(display,bg_pixmap,w,gc_bg,frameRect.x,frameRect.y,frameRect.width,frameRect.height,frameRect.x,frameRect.y); 
  1752. XFreePixmap(display,bg_pixmap); 
  1753. XFreeGC(display, gc_bg); 
  1754.     };
  1755.     if (border)
  1756. DrawBorder(border, x+x1-PixelIndent, y1, width, height, 0 /* cb_ix */);
  1757.     continue;
  1758. }
  1759.         /* skip end of frame marker */
  1760.   
  1761.        if (tag == END_FRAME)
  1762.         {
  1763.     p += FRAMENDLEN - 1;  /* skip start/size params */
  1764.             continue;
  1765.         }
  1766.         if (tag != TEXTLINE)
  1767.         {
  1768.     printf("Unexpected Internal Tag %d at %Xn",tag,(p-1));
  1769.     tag = *p++;
  1770. }
  1771.         c1 = *p++; c2 = *p++; offset = c1 | c2<<8;
  1772.         c1 = *p++; c2 = *p++; offset |= (c1 | c2<<8) << 16;
  1773.         /* we are done if TextLine starts after bottom of window */
  1774.         y1 = WinTop + (offset - PixelOffset);
  1775. /*
  1776. if (y1 >= y + (int)h)
  1777.             break; 
  1778.     */
  1779.         c1 = *p++; c2 = *p++; yb = y1 + (c1 | c2<<8);
  1780.         c1 = *p++; c2 = *p++; xi = x + (c1 | c2<<8);
  1781.         c1 = *p++; c2 = *p++; height = (c1 | c2<<8);
  1782. while ((tag = *p++) != '')
  1783.         {
  1784.             switch (tag & 0xF)
  1785.             {
  1786.     case RULE:
  1787.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);
  1788.                     c1 = *p++; c2 = *p++; x2 = c1 | c2<<8;
  1789.                     c1 = *p++; c2 = *p++; yi = c1 | c2<<8;
  1790.                     if (tag & HLINE)
  1791.                         x2 += x1;
  1792. #ifdef STYLE_COLOR
  1793.     color_text_ix = *p++;
  1794. #endif
  1795. #ifdef STYLE_BACKGROUND
  1796.     GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  1797. #endif
  1798. /*                    if (tag & GROOVE)*/
  1799.     if (color_text_ix == 255)
  1800.                     {
  1801.                         XSetForeground(display, disp_gc, windowBottomShadow);
  1802.                         XFillRectangle(display, w, disp_gc, x1-PixelIndent, yb-yi, x2-x1, 1);
  1803.                         XSetForeground(display, disp_gc, windowTopShadow);
  1804.                         XFillRectangle(display, w, disp_gc, x1-PixelIndent, yb+1-yi, x2-x1, 1);
  1805.                         XSetForeground(display, disp_gc, textColor);
  1806.                     }
  1807.                     else {
  1808. XSetForeground(display, disp_gc, ix2color(color_text_ix)); /* howcome 22/5/95 */
  1809.                         XFillRectangle(display, w, disp_gc, x1-PixelIndent, yb-yi, x2-x1, 1);
  1810.     }
  1811.                         
  1812.                     break;
  1813.                 case LINE:
  1814.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);
  1815.                     c1 = *p++; c2 = *p++; x2 = xi + (c1 | c2<<8);
  1816.                     c1 = *p++; c2 = *p++; y1 = c1 | c2<<8;
  1817.                     c1 = *p++; c2 = *p++; y2 = c1 | c2<<8;
  1818. #ifdef STYLE_COLOR
  1819.                     color_text_ix = *p++;
  1820. #endif
  1821. #ifdef STYLE_BACKGROUND
  1822.                     GetPointer(&p);
  1823. #endif
  1824.                     XSetForeground(display, disp_gc, ix2color(color_text_ix));
  1825.                     XDrawLine(display, win, disp_gc, x1-PixelIndent, yb-y1, x2, yb-y2);
  1826.                     break;
  1827.                 case BULLET:
  1828.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);
  1829.                     c1 = *p++; c2 = *p++; depth = (c1 | c2<<8);
  1830.                     fnt = *p++; /* howcome 25/4/95 */
  1831.     fnt_size = *p++;
  1832.     
  1833. #ifdef STYLE_COLOR
  1834.     color_text_ix = *p++;
  1835. #endif
  1836. #ifdef STYLE_BACKGROUND
  1837.     bg_style=(BG_Style *)GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  1838.     if(bg_style)
  1839. color_background_ix = (bg_style->flag & S_BACKGROUND_COLOR ) ? rgb2ix(0, bg_style->r, bg_style->g, bg_style->b,0) : 255; 
  1840.     else
  1841. color_background_ix = 255;
  1842. #endif
  1843.                     SetColor(disp_gc, color_text_ix, color_background_ix);
  1844.     if (depth > 0)
  1845.                         XFillRectangle(display, w, disp_gc, x1 - PixelIndent, yb - LineSpacing[fnt]*3/8, LineSpacing[fnt]/4, 2);
  1846.                     else
  1847.     {
  1848. XFillRectangle(display, w, disp_gc, x1 - PixelIndent, yb - LineSpacing[fnt]*3/8, LineSpacing[fnt]/5, LineSpacing[fnt]/5);
  1849.     }
  1850.                     break;
  1851.                 case STRING:
  1852.                     c1 = *p++; c2 = *p++; emph = c1 | c2<<8;
  1853.                     fnt = *p++;
  1854. #ifdef STYLE_COLOR
  1855.     color_text_ix = *p++;
  1856. #endif
  1857. #ifdef STYLE_BACKGROUND
  1858.     bg_style=(BG_Style *)GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  1859.     if (bg_style)
  1860.     {
  1861. if(!bg_style->image)
  1862.     color_background_ix = (bg_style->flag & S_BACKGROUND_COLOR) ? rgb2ix(0, bg_style->r, bg_style->g, bg_style->b,0) : 255; 
  1863. else
  1864.     color_background_ix = 255; 
  1865.     }
  1866.     else
  1867. color_background_ix = 255;
  1868.    
  1869. #endif
  1870.                     yi = *p++ - 128;
  1871.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);  /* here */
  1872.                     c1 = *p++; c2 = *p++; len = c1 | c2<<8;
  1873.                     c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  1874.     str = (long) GetPointer(&p);
  1875.     p += POINTERSIZE; /* skip ref */
  1876.     /*     printf("howcome reading %xn", str); */
  1877.                     preformatted = (tag & PRE_TEXT);
  1878.                     s = CopyLine((char *)str, len);
  1879.     
  1880. #ifdef STYLE_COLOR
  1881.     font = fnt;
  1882.     SetColor(disp_gc, color_text_ix, color_background_ix);
  1883.     SetFont(disp_gc, font);
  1884. #else
  1885.                     if (font != fnt)
  1886.                     {
  1887.                         font = fnt;
  1888.                         SetFont(disp_gc, font);
  1889.                     }
  1890.     
  1891. #endif
  1892.                     if (emph & EMPH_HIGHLIGHT)
  1893.                     {
  1894.                         XSetForeground(display,disp_gc, labelColor);
  1895.                         XDrawString(display, w, disp_gc, x1-PixelIndent, yb-yi, s, len);
  1896.                         XSetForeground(display,disp_gc, textColor);
  1897.                     }
  1898.                     else {
  1899. #ifdef STYLE_COLOR
  1900. if (color_background_ix == 255)
  1901. #endif
  1902.     XDrawString(display, w, disp_gc, x1-PixelIndent, yb-yi, s, len);
  1903. #ifdef STYLE_COLOR
  1904. else
  1905.     XDrawImageString(display, w, disp_gc, x1-PixelIndent, yb-yi, s, len);
  1906. #endif
  1907.     }
  1908.     if (emph & EMPH_ANCHOR)
  1909.                     {
  1910.                         y2 = yb - yi - ASCENT(font) - 1;
  1911.                         DrawHButtonUp(x1-PixelIndent, y2, width, LineSpacing[fnt]);
  1912.                     }
  1913.                     if (emph & EMPH_UNDERLINE)
  1914.                     {
  1915.                         y2 = yb - yi + DESCENT(font);
  1916.                         XFillRectangle(display, w, disp_gc, x1+1-PixelIndent, y2 - LineThickness[font], width-2, LineThickness[font]);
  1917.                     }
  1918.                     if (emph & EMPH_STRIKE)
  1919.                     {
  1920.                         y2 = yb - yi - ASCENT(font)/3;
  1921.                         XSetForeground(display,disp_gc, strikeColor);
  1922.                         XFillRectangle(display, w, disp_gc, x1-PixelIndent, y2 - LineThickness[font], width, LineThickness[font]);
  1923.                         XSetForeground(display,disp_gc, textColor);
  1924.                     }
  1925.                     break;
  1926.                 case SEQTEXT:
  1927.     c1 = *p++; c2 = *p++; emph = (c1 | c2<<8);
  1928.                     fnt = *p++;
  1929. #ifdef STYLE_COLOR
  1930.     color_text_ix = *p++;
  1931. #endif
  1932. #ifdef STYLE_BACKGROUND
  1933.     bg_style=(BG_Style *)GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  1934.     if (bg_style)
  1935. color_background_ix = (bg_style->flag & S_BACKGROUND_COLOR) ? rgb2ix(0, bg_style->r, bg_style->g, bg_style->b,0) : 255;
  1936.     else
  1937. color_background_ix = 255;
  1938. #endif
  1939.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);  /* here */
  1940.                     c1 = *p++; c2 = *p++; yi = (c1 | c2<<8);       /* y offset */
  1941.                     len = *p++;
  1942.     width = XTextWidth(Fonts[fnt], (char *)p, len);
  1943. #ifdef STYLE_COLOR
  1944.     font = fnt;
  1945.     SetColor(disp_gc, color_text_ix, color_background_ix);
  1946.     SetFont(disp_gc, font);
  1947.     if (color_background_ix == 255)
  1948. XDrawString(display, w, disp_gc,
  1949.     x1-PixelIndent, yb-yi, (char *)p, len);
  1950.     else
  1951. XDrawImageString(display, w, disp_gc,
  1952.  x1-PixelIndent, yb-yi,
  1953.  (char *)p, len);
  1954. #else
  1955.                     if (font != fnt)
  1956.                     {
  1957.                         font = fnt;
  1958.                         SetFont(disp_gc, font);
  1959.                     }
  1960.                     XDrawString(display, w, disp_gc, x1-PixelIndent,
  1961. yb-yi, (char *)p, len);
  1962. #endif
  1963.     /* different emphasis used in maths */
  1964.     /* under effects */
  1965.                     if (emph & EMPH_UNDERLINE)
  1966.                     {
  1967.                         y2 = yb - yi + DESCENT(font);
  1968.                         XFillRectangle(display, w, disp_gc,
  1969.        x1+1-PixelIndent,
  1970.        y2 - LineThickness[font], width-2,
  1971.        LineThickness[font]);
  1972.                     }
  1973.                     if (emph & EMPH_UNDERLARR)
  1974.                     {
  1975.                         y2 = yb - yi + DESCENT(font);
  1976.                         XFillRectangle(display, w, disp_gc,
  1977.        x1+1-PixelIndent,
  1978.        y2 - LineThickness[font], width,
  1979.        LineThickness[font]);
  1980.                         SetFont(disp_gc, IDX_SUBSYMFONT);
  1981.                         tmp = 60;
  1982.                         XDrawString(display, w, disp_gc,
  1983.     x1-PixelIndent, y2+3,
  1984.     (char *)&tmp, 1);
  1985.                         SetFont(disp_gc, font);
  1986.                     }
  1987.                     if (emph & EMPH_UNDERRARR)
  1988.                     {
  1989.                         y2 = yb - yi + DESCENT(font);
  1990.                         XFillRectangle(display, w, disp_gc,
  1991.        x1+1-PixelIndent,
  1992.        y2 - LineThickness[font], width,
  1993.        LineThickness[font]);
  1994.                         SetFont(disp_gc, IDX_SUBSYMFONT);
  1995.                         tmp = 62;
  1996.                         XDrawString(display, w, disp_gc,
  1997.     x1-PixelIndent+width-4, y2+3,
  1998.     (char *)&tmp, 1);
  1999.                         SetFont(disp_gc, font);
  2000.                     }
  2001.                     if (emph & EMPH_UNDERHAT)
  2002.                     {
  2003.                     }
  2004.                     if (emph & EMPH_UNDERTILDE)
  2005.                     {
  2006.                     }
  2007.     /* OVER effects */
  2008.                     if (emph & EMPH_OVERLINE)
  2009.                     {
  2010.                         y2 = yb - yi + DESCENT(font)/2 - ASCENT(font);
  2011.                         XFillRectangle(display, w, disp_gc,
  2012.        x1+1-PixelIndent,
  2013.        y2 - LineThickness[font], width-2,
  2014.        LineThickness[font]);
  2015.                     }
  2016.                     if (emph & EMPH_OVERLARR)
  2017.                     {
  2018.                         y2 = yb - yi + DESCENT(font)/2 - ASCENT(font);
  2019.                         XFillRectangle(display, w, disp_gc,
  2020.        x1+1-PixelIndent,
  2021.        y2 - LineThickness[font], width-2,
  2022.        LineThickness[font]);
  2023.                         SetFont(disp_gc, IDX_SUBSYMFONT);
  2024.                         tmp = 60;
  2025.                         XDrawString(display, w, disp_gc,
  2026.     x1-PixelIndent, y2+3,
  2027.     (char *)&tmp, 1);
  2028.                         SetFont(disp_gc, font);
  2029.                     }
  2030.                     if (emph & EMPH_OVERRARR)
  2031.                     {
  2032.                         y2 = yb - yi + DESCENT(font)/2 - ASCENT(font);
  2033.                         XFillRectangle(display, w, disp_gc,
  2034.        x1-PixelIndent, y2, width, 1);
  2035.                         SetFont(disp_gc, IDX_SUBSYMFONT);
  2036.                         tmp = 62;
  2037.                         XDrawString(display, w, disp_gc,
  2038.     x1-PixelIndent+width-4, y2+3,
  2039.     (char *)&tmp, 1);
  2040.                         SetFont(disp_gc, font);
  2041.                     }
  2042.                     if (emph & EMPH_OVERHAT)
  2043.                     {
  2044.                     }
  2045.                     if (emph & EMPH_OVERDOT)
  2046.                     {
  2047.                     }
  2048.                     if (emph & EMPH_OVERDDOT)
  2049.                     {
  2050.                     }
  2051.                     if (emph & EMPH_OVERTILDE)
  2052.                     {
  2053.                     }
  2054.                     p += len;
  2055.                     break;
  2056.                 case IMAGE:
  2057.                     c1 = *p++; c2 = *p++; y2 = yb - (c1 | c2<<8);
  2058.                     c1 = *p++; c2 = *p++; x1 = xi + (c1 | c2<<8);  /* here */
  2059.                     c1 = *p++; c2 = *p++; width = c1 | c2<<8;
  2060.                     c1 = *p++; c2 = *p++; height = c1 | c2<<8;
  2061.     str = (long)GetPointer(&p);
  2062.    
  2063.                     p += POINTERSIZE;  /* skip past buffer pointer */
  2064. #ifdef STYLE_BACKGROUND
  2065.     GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  2066. #endif
  2067.     if (y2 > y + (int)h)
  2068.                         break;
  2069.                     if (y2 + height < y)
  2070.                         continue;
  2071.                     x1 -= PixelIndent;
  2072.                     if (tag & (ISMAP | EMPH_ANCHOR))
  2073.                     {
  2074.                         DrawOutSet(w, disp_gc, x1, y2, width, height);
  2075.                         XSetForeground(display, disp_gc, textColor);
  2076.                         DrawHButtonDown(x1+4, y2+2, width-7, height-6);
  2077.                         width -= 8;
  2078.                         height -= 8;
  2079.                         x1 += 4;
  2080.                         y2 += 4;
  2081.                     }
  2082.     if (str) {
  2083. XCopyArea(display, (Pixmap)str, w, disp_gc, 0, 0, width, height, x1, y2);
  2084.     } else if (!(tag & (ISMAP | EMPH_ANCHOR))){
  2085. XPoint points[3];
  2086. points[0].x = x1;
  2087. points[0].y = y2 + IMG_INDICATOR;
  2088. points[1].x = x1;
  2089. points[1].y = y2;
  2090. points[2].x = x1 + IMG_INDICATOR;
  2091. points[2].y = y2;
  2092. XDrawLines(display, w, disp_gc, points, 3, CoordModeOrigin);
  2093. points[0].x = x1 + width - IMG_INDICATOR;
  2094. points[0].y = y2;
  2095. points[1].x = x1 + width;
  2096. points[1].y = y2;
  2097. points[2].x = x1 + width;
  2098. points[2].y = y2 + IMG_INDICATOR;
  2099. XDrawLines(display, w, disp_gc, points, 3, CoordModeOrigin);
  2100. points[0].x = x1 + width;
  2101. points[0].y = y2 + height - IMG_INDICATOR;
  2102. points[1].x = x1 + width;
  2103. points[1].y = y2 + height;
  2104. points[2].x = x1 + width - IMG_INDICATOR;
  2105. points[2].y = y2 + height;
  2106. XDrawLines(display, w, disp_gc, points, 3, CoordModeOrigin);
  2107. points[0].x = x1 + IMG_INDICATOR ;
  2108. points[0].y = y2 + height;
  2109. points[1].x = x1;
  2110. points[1].y = y2 + height;
  2111. points[2].x = x1;
  2112. points[2].y = y2 + height - IMG_INDICATOR;
  2113. XDrawLines(display, w, disp_gc, points, 3, CoordModeOrigin);
  2114.     }
  2115.                     break;
  2116.                 case INPUT:
  2117.     str = (long)GetPointer(&p);
  2118. #ifdef STYLE_BACKGROUND
  2119.     GetPointer(&p); /* must be set to the structures defined by the style --Spif 18-Oct-95 */
  2120. #endif
  2121.                     PaintField(disp_gc, xi, yb, (Field *)str);
  2122.                     break;
  2123.             }
  2124.         }
  2125.         ++p; ++p;  /* skip size param to start of next object */
  2126.     }
  2127.     if (TAG_TRACE && VERBOSE_TRACE)
  2128. #if defined PRINTF_HAS_PFORMAT
  2129. fprintf(stderr,"PaintFrame: after while p = %p, p_end = %pn", p, p_end);
  2130. #else
  2131. fprintf(stderr,"PaintFrame: after while p = %lx, p_end = %lxn", p, p_end);
  2132. #endif /* PRINTF_HAS_PFORMAT */
  2133. }
  2134. /* search for anchor point in document */
  2135. /* search index for given keywords */
  2136. void SearchIndex(char *keywords)
  2137. {
  2138. #if 0
  2139.     char *p, *q;
  2140.     /* janet 21/07/95: not used:    int where; */
  2141.     p = SearchRef(keywords);
  2142.     if (*p)  /* attempt to get new document */
  2143.     {
  2144. /*        XDefineCursor(display, win, hourglass);*/
  2145. /*        XFlush(display);*/
  2146.         q = libGetDocument(p, NULL, REMOTE); /* howcome */
  2147.         if (q && *q)
  2148.         {
  2149.             CurrentDoc.offset = PixelOffset;
  2150.             PushDoc(CurrentDoc.offset);
  2151.             SetBanner(BANNER);
  2152.             SetCurrent();
  2153.             NewBuffer(q);
  2154.             if (IsIndex)
  2155.                 ClearStatus();
  2156.             SetStatusString(NULL);  /* to refresh screen */
  2157.         }
  2158.         DisplayScrollBar();
  2159.         DisplayDoc(WinLeft, WinTop, WinWidth, WinHeight);
  2160.         XUndefineCursor(display, win);
  2161.         XFlush(display);
  2162.     }
  2163. #endif
  2164. }
  2165. int WindowButtonDown(int x, int y)
  2166. {
  2167.     int tag, dx, dy;
  2168.     /* the window should only be cliackable for certain content_types and modes */
  2169.     if (!DocHTML(CurrentDoc))
  2170. return VOID;
  2171.     if (CurrentDoc->show_raw)
  2172. return VOID;
  2173.     anchor_start = anchor_end = 0;
  2174.     tag = 0;
  2175.     clicked_element = WhichObject(BUTTONDOWN, x, y, &tag, &anchor_start, &anchor_end, &dx, &dy);
  2176.    
  2177.     if (tag == TAG_ANCHOR || tag == TAG_IMG) /* redraw anchor if type=image or src= */
  2178.     {
  2179.         DrawAnchor(&background, 0);
  2180. return WINDOW;
  2181.     }
  2182.     if (tag == TAG_INPUT || TAG_SELECT)
  2183.         /* toggle checked here ??? --SPif 13-oct-95 */
  2184.       return WINDOW;
  2185.     Beep();
  2186.     return VOID;
  2187. }
  2188. /* --Spif must do this right (11-Oct-95) */
  2189. void www_encode(char *raw)
  2190. {
  2191.     int i,rlen;
  2192.     char *encoded,*j;
  2193.     rlen=strlen(raw);
  2194.     encoded=(char *)malloc(3*rlen+1); /* max size = size*3 */
  2195.     j=encoded;
  2196.     for(i=0;i<rlen;i++)
  2197.     {
  2198.       if( *(raw+i) ==' ')
  2199. *j++ = '+';       
  2200.       else if ((*(raw+i) == '-')||(*(raw+i) == '_'))
  2201. *j++=*(raw+i);
  2202.       else if ((*(raw+i) < '0' ) || ((*(raw+i)<'A')&&(*(raw+i)>'9'))){
  2203. *j++ = '%';
  2204. sprintf(j,"%X",*(raw+i));
  2205. j+=2;
  2206.       } else if ((*(raw+i) > 'z') || ((*(raw+i)<'a')&&(*(raw+i)>'Z'))){
  2207. *j++ = '%';
  2208. sprintf(j,"%X",*(raw+i));
  2209. j+=2;
  2210.       } else 
  2211. *j++=*(raw+i);
  2212.     };
  2213.     *j=0;
  2214.     strcpy(raw,encoded); /* short term hack... must return the pointer */
  2215. }
  2216. void WindowButtonUp(int shifted, int px, int py)
  2217. {
  2218.     Byte *object;
  2219.     char *start, *end, *href, *name, *link, *value, buf[16], *action;
  2220.     int tag, hreflen, namelen, align, ismap, dx, dy, width, height;
  2221.     int type, vlen, flags, size, method, alen, nlen;
  2222.     Image *image = NULL;
  2223.     Form *form = NULL;
  2224.     /* the window should only be cliackable for certain content_types and modes */
  2225.     if (!DocHTML(CurrentDoc))
  2226. return;
  2227.     if (CurrentDoc->show_raw)
  2228. return;
  2229.     if (anchor_start && anchor_end)
  2230.         DrawAnchor(&background, 1);
  2231.     tag=UNKNOWN; /* -- avoid any pb with this --Spif 16-Oct-95 */
  2232.     object = WhichObject(BUTTONUP, px, py, &tag, &start, &end, &dx, &dy);
  2233.     
  2234.     if ((tag == TAG_ANCHOR || tag == TAG_IMG) &&
  2235. start == anchor_start && end == anchor_end)
  2236.     {
  2237.         if (tag == TAG_IMG)
  2238.         {
  2239.             bufptr = anchor_start+5;
  2240.             ParseImageAttrs(&href, &hreflen, &align, &ismap, &width, &height);
  2241.             sprintf(buf, "?%d,%d", dx, dy);
  2242.             link = (char *)malloc(hreflen+strlen(buf)+1);
  2243.             memcpy(link, href, hreflen);
  2244.             link[hreflen] = '';
  2245.             strcat(link, buf);
  2246.         }
  2247.         else /* tag == TAG_ANCHOR */
  2248.         {
  2249.     int class_len; 
  2250.     char *class = NULL;
  2251.             bufptr = anchor_start+3;
  2252.             ParseAnchorAttrs(&href, &hreflen, &name, &namelen, &class, &class_len);
  2253.             if (dx >= 0 && dy >= 0)
  2254.             {
  2255.                 sprintf(buf, "?%d,%d", dx, dy);
  2256.                 link = (char *)malloc(hreflen+strlen(buf)+1);
  2257.                 memcpy(link, href, hreflen);
  2258.                 link[hreflen] = '';
  2259.                 strcat(link, buf);
  2260.             }
  2261.             else
  2262.             {
  2263.                 link = (char *)malloc(hreflen+1);
  2264.                 memcpy(link, href, hreflen);
  2265.                 link[hreflen] = '';
  2266.             }
  2267.         }
  2268. /*
  2269.         if (shifted)
  2270.         {
  2271.             if (CloneSelf())
  2272.                 OpenDoc(link);
  2273.         }
  2274.         else */
  2275. OpenDoc(link);
  2276.         Free(link);
  2277.     }
  2278.     else
  2279.     { 
  2280.         if (tag == TAG_INPUT) /* --Spif FORM 10-Oct-95 */
  2281. {
  2282.     bufptr = start + 7 ;
  2283.     ParseInputAttrs(&type, &name, &nlen, &value, &vlen, &size, &flags, &image);
  2284.     /* backtrack to find the previous <FORM..> */
  2285.     for(;(strncasecmp(bufptr, "<form", 5) != 0)&&(*bufptr);bufptr--);
  2286.     bufptr+=5; 
  2287.     ParseFormAttrs(&method,&action,&alen);  /* must test that a form was found */
  2288.     form = FindForm(forms,action);
  2289.     if(form!=NULL)
  2290.     {
  2291. if (type == RESETBUTTON)
  2292. {/* printf("reset formn"); --Spif 12-Oct-95 */}; /* reset the whole form */
  2293. if (type == SUBMITBUTTON)
  2294. {
  2295.     SubmitForm(form,method,action,alen,type,name,nlen,value,vlen,image,dx,dy,bufptr);
  2296. }
  2297. else
  2298. {
  2299.     /* not a submitbutton  but who cares ? ;)  -- Spif 18-Oct-95*/
  2300. };
  2301.     };
  2302. };
  2303.     };
  2304.     XFlush(display);
  2305. }