diff -u --recursive -N ../chimera-1.70p0/CHANGES ./CHANGES --- ../chimera-1.70p0/CHANGES Wed May 7 14:50:39 1997 +++ ./CHANGES Thu May 22 11:48:02 1997 @@ -4,8 +4,107 @@ * no "rowspan=" or align=center support in tables; Minor annoyance: the (now) rare, "spurious" extra spaces added during formatting can result in equally spurious blank lines in the Print/Select - output. + output. [WBE] +Surprise: The PS converter leaves the general background white, good for + b&w printers, but otherwise honors the colors it finds; in particular, + transparent GIF backgrounds _are_ rendered in the window background color. + May not be easy to fix though. [GN] +Nonfeature: Methinks the PS converter can't handle FORMs at present. And + delayed images come out blank gray. [GN] --------------------------------------------------------------------------- +1.70p1 (collected by Gerhard Niklasch ) +------------ +libhtmlw/{HTML.c,HTMLP.h,HTMLformat.c,HTMLimages.c,HTMLparse.c}, src/{main.c, + widget.h}: Support for and added by + D J Hawkey Jr +libhtmlw/HTML.h, src/Chimera.ad, lib/help.html and the above: Minor modifi- + cations, and added *html.{useBodyColors,delayedImageBorders} resources. [GN] + Surprise: the internal icons for delayed or broken images get drawn in the + colors of the first page on which we use them, and never change afterwards. +lib/help.html,src/{main.c,widget.[ch]}: Rewrote the live anchor display + callback routine after changing its widget to match the other two header + display boxes. Added resources for it, renaming the on/off switch + *anchorDisplay to *showLiveAnchors for consistency.-- Also rearranged + (and added to) a number of X Resource descriptions in lib/help.html + for easier navigation. [GN] + And introduced, and removed, a stupid off-by-one error in LiveAnchorCallback + (in src/main.c) in the process. [GN] + And renamed the entire widget to "hrefdisplay" so 1.70's *anchordisplay + resource won't interfere with it. (It still doesn't like running with an + old app-defaults file; the fallbacks simply won't be used.) [GN] +libhtmlw/{HTML.[ch],HTMLformat.c,HTML.h}: Added hooks for parsing and re- + membering ALT tags of images. Probably stupid the way it's done now but + it sort of works. Changed TrackMotion (which is the parent of the + LiveAnchorCallback) to display ISMAP attributes and ALT strings along + with HREFs whenever this makes sense. [GN] + Also added resource *html.truncateALT to prevent long ALT strings from + pushing the HREF off the display. [GN] + Finally, rewrote all that because it was way too stupid to let anyone else + see it [GN] +README: Descriptions of new img/body attribute features added [GN] +src/{fallback.c,Chimera.ad}: Many more resources (all the HTML widget stuff) + are now listed. Changed default for *titledisplay.sensitive to True so we + can select (bits of) the Title and paste them elsewhere [GN] +INSTALL: cwd might not be in the path, so say ./test-chimera. And add hint + about editing Common.tmpl [Hallvard B Furuseth ] +util/chimera-frontend.script: when mentioning a minor version number, use + the current one [HBF] +src/main.c: Optical feedback about Cancel button's being sensitive added + [GN following suggestion by HBF]. Also: poll XEvent queue for exposes, + redrawing as necessary, during downloads. This may not have the desired + effect once we've received the page and are chasing up images. [GN] + And toggle sensitivity of all other buttons as well [GN] +src/ftp.c: Don't try to FTP directories as files if the URL ends with a slash, + and remove the slash before adding another one in the listing page. [GN] + And be more lenient with responses to PASV. [HBF&GN] + And if we'ge got a 230 already from USER, don't bother with PASS. [GN] + And don't try SIZE when we know it's a directory, and don't try RETR if SIZE + tells us it's a directory [sheesh -- had overlooked this at first. GN] +src/input.c: c_select introduced, to avoid hangs while waiting for a socket + opened by a non-blocking connect, by Larry Doolittle +src/url.c: MakeURLParts was leaving hostname==NULL in certain situations, + causing segfaults at DNS [HBF & GN] +src/{url.c,main.c}: Try to do a little more for inlined images which are + subject to authorization, (a) upon a 401 response like HandleDoc does for + standalone documents, and (b) by letting relative URLs inherit tentative + authorization info from their parents. Problem noted by Volker Broeske + , code by GN. + And re­sensitize Home and Back buttons after image loads, too [GN, cf. above] +src/main.c: Show contents of page returned with a 401 Auth failure response + when the auth popup is dismissed [DJHJr] +libhtmlw/HTMLimages.c: New color depth code by Tom Lane + should work on weird X servers with strange bpp's +libhtmlw/{HTMLimages.c,HTMLformat.c}: calls with wrong # args found and fixed + by Frank G Liu +libhtmlw/HTML-PSformat.c: Use new stdarg instead of obsolete varargs, and + more robust PSprintf(). Snarfed from mMosaic by FGL +src/{ftp.c,local.c}: changed private strcmp wrappers to pass const char*'s + to strcmp and accept const void*'s from qsort + [Nelson H F Beebe ]. + And made that const char**'s, and call qsort explicitly with the _address_ + of the comparison function. Now it does actually _sort_ entries. [GN] + And get rid of some of those extra spaces in the local dir' listings [GN] +libhtmlw/HTMLimages.c: two functions get both old and new style definitions + to avoid type conflicts caused by Boolean args on some platforms [NHFB] +src/{Imakefile,util.c,net.c,input.c}: QNX support added [FGL, and independently + by DJHJr] +src/{net.c,input.c}: HP-UX support added [NHFB] +lib/Imakefile: adjusted INSTDATFLAGS to install lib/* stuff mode 644 not 444 + following suggestion by NHFB +mxw/AxeStrDefs.h: extra text after #endif belongs inside /*...*/ [NHFB] +mxw/Bookmark.c: Missing bookmarkfile should not generate an XAppWarning [GN] +xloadimage/new.c: got rid of warning about overlong (signed) decimal + constants which were meant to be unsigned long anyway [GN] +Common.tmpl.dist: enhanced comment re XAPPLOADDIR & non-root install [HBF & GN] +libhtmlw/HTMLlists.c: Plug another memory leak [WBE] +src/{main.c,url.c,local.c}: (Ab)use MakeURLParts to do some sanity checks + on URLs for which there's no context, and let "" denote "localhost" for + the purposes of "file:" [GN] +src/{document.[ch],main.c}: Ignore fragment ids ("anchors") except when + displaying a document for the first time (i.e., use the remembered + scrollbar positions instead) [GN] +Chimera.ad.test: Reflect some of the changes made to src/Chimera.ad [GN] + 1.70p0 ------------ src/main.c: Bookmark use vs. local files bug fixed! Needed an alloc_string diff -u --recursive -N ../chimera-1.70p0/Chimera.ad.test ./Chimera.ad.test --- ../chimera-1.70p0/Chimera.ad.test Fri Apr 18 13:18:32 1997 +++ ./Chimera.ad.test Thu May 22 10:01:53 1997 @@ -99,32 +99,45 @@ Chimera*search.title: Enter search Chimera*search.strreqMessage: Enter search -Chimera*urllabel.label: URL : -Chimera*urllabel.left: ChainLeft -Chimera*urllabel.right: ChainLeft -Chimera*urldisplay.left: ChainLeft -Chimera*urldisplay.right: ChainRight -Chimera*urldisplay.fromHoriz: urllabel -Chimera*urldisplay*sensitive: true -Chimera*urldisplay.width: 500 -Chimera*urldisplay*editType: edit - -Chimera*titlelabel.label: Title : +Chimera*titlelabel.label: Status/Title: Chimera*titlelabel.left: ChainLeft Chimera*titlelabel.right: ChainLeft Chimera*titledisplay.left: ChainLeft Chimera*titledisplay.right: ChainRight Chimera*titledisplay.fromHoriz: titlelabel -Chimera*titledisplay*sensitive: false +Chimera*titledisplay*sensitive: True Chimera*titledisplay.width: 500 Chimera*titledisplay*displayCaret: False Chimera*titledisplay*editType: read +Chimera*urllabel.label: Latest URL : +Chimera*urllabel.left: ChainLeft +Chimera*urllabel.right: ChainLeft +Chimera*urldisplay.left: ChainLeft +Chimera*urldisplay.right: ChainRight +Chimera*urldisplay.fromHoriz: urllabel +Chimera*urldisplay*sensitive: True +Chimera*urldisplay.width: 500 +Chimera*urldisplay*displayCaret: True +Chimera*urldisplay*editType: edit + +Chimera*hreflabel.label: ALT / HREF : +Chimera*hreflabel.left: ChainLeft +Chimera*hreflabel.right: ChainLeft +Chimera*hrefdisplay.left: ChainLeft +Chimera*hrefdisplay.right: ChainRight +Chimera*hrefdisplay.fromHoriz: hreflabel +Chimera*hrefdisplay*sensitive: False +Chimera*hrefdisplay.width: 500 +Chimera*hrefdisplay*displayCaret: False +Chimera*hrefdisplay*editType: read + Chimera*Label.font: -*-lucidatypewriter-medium-r-normal-*-*-120-*-*-*-*-iso8859-1 Chimera*Command.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 Chimera*Toggle.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 -Chimera*urldisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 -Chimera*titledisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +Chimera*titledisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +Chimera*urldisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +Chimera*hrefdisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 Chimera*header1Font: -*-helvetica-bold-r-normal-*-*-240-*-*-*-*-iso8859-1 Chimera*header2Font: -*-helvetica-bold-r-normal-*-*-180-*-*-*-*-iso8859-1 diff -u --recursive -N ../chimera-1.70p0/Common.tmpl.dist ./Common.tmpl.dist --- ../chimera-1.70p0/Common.tmpl.dist Sun Apr 2 05:20:24 1995 +++ ./Common.tmpl.dist Mon May 12 12:00:44 1997 @@ -40,8 +40,19 @@ -DHOME_URL=\"file:$(CLIBDIR)/home.html\" /* + * The following ensures that the app-defaults file and the stuff in lib/ + * gets installed with user write permissions. Suggested by Nelson H F Beebe + * 1997May09. + */ +INSTDATFLAGS = -m 0644 + +/* * These may need to be changed if you customize the location of the * app-defaults or the man pages. + * If you're doing a non-root installation, change XAPPLOADDIR to something + * you have write access to. The install will put the app-defaults file there, + * calling it `Chimera'. The executable automatically looks for it in your + * home directory and in the current working directory. */ /* XAPPLOADDIR = $(CLIBDIR) diff -u --recursive -N ../chimera-1.70p0/INSTALL ./INSTALL --- ../chimera-1.70p0/INSTALL Fri Apr 18 13:18:32 1997 +++ ./INSTALL Fri May 9 17:18:53 1997 @@ -41,7 +41,7 @@ You can test chimera by typing - test-chimera + ./test-chimera If the test worked OK, you can install chimera by typing @@ -51,4 +51,5 @@ work OK. I suggest that you look at Common.tmpl and options.h to make sure that the -settings look OK to you. +settings look OK to you. (To change Makefile variables, e.g. CC = gcc, +insert them in Common.tmpl before running or re-running `xmkmf -a'.) diff -u --recursive -N ../chimera-1.70p0/README ./README --- ../chimera-1.70p0/README Wed May 7 14:48:18 1997 +++ ./README Thu May 22 11:46:35 1997 @@ -47,6 +47,9 @@ loading on and off (or you can type 'i' if you prefer). 9) If serious HTML command errors are encountered on a visited page, a small message saying so will appear at the bottom of the page. +To which Chimera-1.70p1 adds: + 10) Image BORDER and ALT attributes do something useful. + 11) Color attributes to the BODY tag are honored (unless you turn this off). Chimera 1.70 also contains a long list of bug fixes, including these: * Some 20 different memory leaks have been fixed, including all the @@ -57,6 +60,7 @@ but prevent ALL further image display has been fixed. * A page's Title and URL are now restored in many cases where before they weren't. +A lot more things have been fixed in 1.70p1. All the Chimera 1.65 patches up through 1.65p1 (plus one stray) are included. @@ -187,6 +191,44 @@ specified cutoff. +10. Image attributes + + We parse both the ALT and the BORDER attribute. ALT strings of delayed +images are shown in the live anchor display (unless you have disabled it) +preceding the HREF of any anchor the image might be a part of. Since ALT +strings can be arbitrarily long and we don't want to push the HREF off the +display, long ALT strings will be truncated (this can be tuned by changing +the X resource *html.truncateAlt). + + BORDER attributes do the obvious thing when they are present. Delayed +images are normally shown with a default border even if they are not part +of an anchor; anchored images always get a border unless the IMG tag says +BORDER=0, and other images don't get borders forced upon them unless they +ask for it. There are boolean X resources to change some of this behavior +(*html.imageBorders and *html.delayedImageBorders). + + +11. Body colors + + The following color attributes of BODY tags are used if we can recognize +the color names or specifications: + * BGCOLOR setting the background of the HTML view area (and of + transparent images), + * TEXT to set the foreground color, + * LINK to set the foreground of unvisited anchors, + * ALINK to set the foreground of active anchors + (used while you hold down the mouse button), + * VLINK to set the foreground of visited anchors. +If you set *html.useBodyColors to False, we will ignore these and stick to +our default color scheme. + +Deficiencies: The internal icons for broken or delayed images are created +when they are first used, and retain the colors they were painted with for +the remainder of the session. Buttons in FORMs do not change colors (there +simply is no suitable attribute to do this), nor do their borders, although +these are affected by general *foreground and *background X resources. + + WHAT FILES ARE HERE ------------------- @@ -248,3 +290,4 @@ Gerhard Niklasch Tuesday, May 6, 1997 +Thursday, May 22, 1997 (1.70p1 -- GN) diff -u --recursive -N ../chimera-1.70p0/lib/help.html ./lib/help.html --- ../chimera-1.70p0/lib/help.html Tue May 6 12:04:01 1997 +++ ./lib/help.html Wed May 21 19:03:21 1997 @@ -69,8 +69,7 @@ a colon nor a slash, so you can still access relative URLs like otherdoc.html by typing ./otherdoc.html; the shortcut expansion feature can be turned off entirely by setting the -X resource Chimera*openButtonShortcut to False or -off). +X resource Chimera*openButtonShortcut to False).

Home

@@ -271,43 +270,51 @@ and in the Common.tmpl file in the source tree.
-convertFiles           A colon separated list of files that describe the
-                       converters.
-
 homeURL                URL of the first document to load.
 
-helpURL                URL of the help document.
+helpURL                URL of the help document.  Defaults to this page
+                       (if it was installed where we expect it to be).
+
+convertFiles           A colon separated list of files that describe the
+                       converters.
 
 path                   A colon separated list of directories to search
                        for viewer and conversion programs.
 
+showTitle              Boolean variable used to specify whether or not
+                       the status/title display should appear on the screen.
+
 showURL                Boolean variable used to specify whether or not the
-                       URL should be displayed on the screen.
+                       document URL display should appear on the screen.
 
-showTitle              Boolean variable used to specify whether or not
-                       the title should be displayed on the screen.
+showLiveAnchors        Boolean variable used to specify whether or not the
+                       HREF contents of hyperlink anchors should be displayed
+                       on the fly as the mouse moves over them.  The display
+                       will also show ALT strings and ISMAP attributes of
+                       delayed images.  These three default to True.
 
-anchorDisplay          Boolean variable used to specify whether or not the
-                       URL contents of hyperlink anchors should be displayed
-                       on the fly as the mouse moves over them.
+button1Box             A comma separated list of buttons to appear on the
+                       first button row.  Possible button names are quit,
+                       open, home, back, source, reload, file, help,
+                       bookmark, search, cancel, and deferpix, all of which
+                       are used  (in this order)  by default.
+
+button2Box             A list of buttons to appear on the second button
+                       row.  Defaults to empty.
 
 openButtonShortcut     Boolean variable used to specify whether user input
                        in the URL field or Open Document box should be assumed
                        to refer to a WWW site if it contains neither a slash
-                       nor a colon.
+                       nor a colon.  Defaults to True, so you can go to
+                       http://www.hot.site.com/ by typing www.hot.site.com
+                       (but take care:  when typing in a filename as a relative
+                       URL you must then precede it with ./).
 
 localIndexFiles        A colon separated list of files which Chimera should
                        try to display in this order when pointed at a directory
                        via a file:... URL.  When empty or when nothing matches,
-                       a directory listing will be generated.
-
-button1Box             A comma separated list of buttons to appear on the
-                       first button row.  Possible button names are quit,
-                       open, home, back, source, reload, file, help,
-                       bookmark, search, and cancel.
-
-button2Box             A list of buttons to appear on the second button
-                       row.
+                       a directory listing will be generated.  Defaults to
+                       index.html .
 
 printerName            Used to specify the name of the default printer.
 
@@ -315,9 +322,8 @@
                        Performance falls way off if you set this to true.
 
 cacheDir               This is used to specify the directory of the default
-                       cache.  Chimera will not create the
-                       directory if it does not exist and caching will not
-                       occur.
+                       cache.  Chimera will not create the directory if it
+                       does not exist and caching will then not occur.
 
 cacheTTL               This specifies the time-to-live for the default cache.
                        If a document is accessed and the cache entry for that
@@ -334,7 +340,17 @@
                        grow to any size.
 
 cacheClean             If True then chimera will remove the files from the
-                       default cache that it creates when it exits.
+                       default cache that it creates when it exits.  Defaults
+                       to True.  If several chimeras are running at once, and
+                       some of them have been pointed at the same documents,
+                       each upon exiting will happily purge these common
+                       documents from the cache behind the others' backs.
+
+cacheInfoFiles         It is a colon delimited list of cache info files.
+
+cacheIgnoreExpires     If this is set to True then chimera will ignore
+                       'expires' data from the information server.  Defaults
+                       to False.
 
 mimeTypeFiles          A colon separated list of files that map file
                        extensions to MIME content-types.
@@ -342,21 +358,37 @@
 mailCapFiles           A colon separated list of MIME mailcap files to be used
                        by chimera.
 
-bookmarkFile           The location of the bookmark file.
-
 protocolFiles          A colon separated list of files that describe the
                        programs to be used for handling protocols.
+                       These three have compile-time defaults.
+
+bookmarkFile           The location of the bookmark file.  Defaults to
+                       ~/.chimera_bookmark .
 
 statusUpdate           The number of times to update the download status
                        per read (or something).  Setting this to 1 gives
                        the most frequent updates while higher numbers give
                        fewer updates.  (Default is 10.)
 
+html.truncateALT       Long ALT strings will be truncated to at most this many
+                       characters before displaying them  (so the HREF if any
+                       is still visible to the right of them).  Defaults to 60.
+                       When set to 0, it will act like 1024  (effectively no
+                       truncation),  when set to anything else less than 7,
+                       it will be increased to 7.
+
 html.htmlErrorMsgCutoff    If negative, never display the "# HTML errors
                        found in document" message.  If non-negative, only
                        display the message if the number of errors found
                        is greater than this cutoff.  (Default value: 0)
 
+html.useBodyColors     If True (the default), color attributes of HTML BODY
+                       tags will be honored;  otherwise we'll stick to our
+                       default color scheme.
+
+html.delayImageLoads   This determines the initial state of the DeferPix
+                       button.  Defaults to False  (images not delayed).
+
 inPort                 The port number that chimera listens on for
                        incoming information from other programs.
                        By default, this is set to zero which disables
@@ -364,7 +396,11 @@
 
 languageDB             Specifies the language database file.  The language
                        database is a file with a name/value pair per line.
-                       The name and value are separated by a colon.
+                       The name and value are separated by a colon.  By
+                       default, Chimera uses the built-in English database
+                       which you'll find in src/lang.c  (the names are all
+                       there, but note this is in C, not in the language
+                       database format).
 
 httpProxy              HTTP proxy URL.
 
@@ -384,16 +420,8 @@
 
 allProxy               Used to specify the default proxy for all protocols.
 
-maxColors              Specify the maximum colors that a single inline
-                       image can have.
-
-delayImageLoads        This determines the initial state of the DeferPix
-                       button.
-
-cacheInfoFiles         It is a colon delimited list of cache info files.
-
-cacheIgnoreExpires     If this is set to True then chimera will ignore
-                       'expires' data from the information server.
+maxColors              Specify the maximum number of colors that a single
+                       inline image can have.
 
 gammaCorrect           Set the gamma correction for inline images.  Default
                        is 0.0 (gamma correction turned off).
diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTML-PSformat.c ./libhtmlw/HTML-PSformat.c
--- ../chimera-1.70p0/libhtmlw/HTML-PSformat.c	Sun May  4 10:08:32 1997
+++ ./libhtmlw/HTML-PSformat.c	Wed May 14 22:11:15 1997
@@ -41,7 +41,7 @@
  *              permission of John Bradley.
  */
 
-#include 
+#include 
 
 #include 
 #include 
@@ -153,86 +153,74 @@
 }
 
 
-/*__________________________________________________________________________
- |
- | PSprintf - dynamic string concatenation function.
- |
- |  In successive calls, the formatted string will be appended to the global
- |  output string Sp.
- |  It assumes that on each call, the length of the text appended to Sp
- |  is less than 1024.
- |  The format string is used as in printf, so you can use additional
- |  arguments.
- |
- |  When successful, PSprintf returns the number of characters printed
- |  in this call, otherwise it returns EOF (just as printf does)
- |
-*/
+/* PSprintf - dynamic string concatenation function.
+ *
+ *  In successive calls, the formatted string will be appended to the global
+ *  output string Sp.
+ *  It assumes that on each call, the length of the text appended to Sp
+ *  is less than 1024.
+ *  The format string is used as in printf, so you can use additional
+ *  arguments.
+ *
+ *  When successful, PSprintf returns the number of characters printed
+ *  in this call, otherwise it returns EOF (just as printf does)
+ */
 
-#ifdef BROKEN_SOLARIS_COMPILER_STDARG
-/* "Looks like there's a bug in Sun's C compiler and the stdarg.h use
-   of va_start() in HTML-PSformat.c. Until the SunPro folks can take a
-   look at the problem, the following pre-ANSI code should workaround
-   the problem." */
-static int PSprintf 
-ARG1V (char *, format,...)
+#ifdef OLDC
+static int PSprintf(format, va_alist)
+    char * format;
+    va_dcl
+{
+    int 	len;
+    char 	*s;
+    va_list	ap;
+
+    if (PS_size - PS_len < 1024) {
+	PS_size += 1024;
+	if ((s = (char *) realloc(PS_string, PS_size)) == NULL) {
+#ifdef VERBOSE
+		fprintf(stderr, "PSprintf malloc failed\n");
+#endif
+		return(EOF);
+	}
+	PS_string = s;
+    }
+    va_start(ap);
+    len = (int) vsprintf(PS_string+PS_len, format, ap);
+    /* this is a hack to make it work on systems were vsprintf(s,...)
+     * returns s, instead of the len.  */
+    if (len != EOF && len != (int) NULL) 
+	PS_len += strlen(PS_string+PS_len);
+    va_end(ap);
+    return(len);
+}
+#else
+static int PSprintf(char *format, ...)       
 {
-  va_dcl
     va_list args;
-  int len;
-  char *s;
-
-  if (PS_size - PS_len < 1024)
-  {
-    PS_size += 1024;
-    if ((s = (char *) XtRealloc (PS_string, PS_size)) == NULL)
-    {
-      fprintf (stderr, "PSprintf malloc failed\n");
-      return (EOF);
-    }
-    PS_string = s;
-  }
-  va_start (args);
-  len = vsprintf (PS_string + PS_len, format, args);
-  /* this is a hack to make it work on systems were vsprintf(s,.)
-   * returns s, instead of the len.
-   */
-  if (len != EOF && len != NULL)
-    PS_len += strlen (PS_string + PS_len);
-  va_end (args);
-  return (len);
-}
-#else /* not BROKEN_SOLARIS_COMPILER_STDARG */
-static int
-PSprintf (format, va_alist)
-char *format;
-va_dcl
-{
-  int len;
-  char *s;
-  va_list args;
-
-  if (PS_size - PS_len < 1024)
-  {
-    PS_size += 1024;
-    if ((s = (char *) XtRealloc (PS_string, PS_size)) == NULL)
-    {
-      fprintf (stderr, "PSprintf malloc failed\n");
-      return (EOF);
-    }
-    PS_string = s;
-  }
-  va_start (args);
-  len = vsprintf (PS_string + PS_len, format, args);
-  /* this is a hack to make it work on systems were vsprintf(s,...)
-   * returns s, instead of the len.
-   */
-  if (len != EOF && len != 0)
-    PS_len += strlen (PS_string + PS_len);
-  va_end (args);
-  return (len);
+    int     len;        
+    char    *s;                 
+    va_start(args, format);
+  
+    if (PS_size - PS_len < 1024) {
+        PS_size += 1024;
+        if ((s = (char *) realloc(PS_string, PS_size)) == NULL) {
+#ifdef VERBOSE
+		fprintf(stderr, "PSprintf malloc failed\n");
+#endif
+                return(EOF);
+        }
+        PS_string = s;
+    }           
+    len = (int) vsprintf(PS_string+PS_len, format, args);
+    /* this is a hack to make it work on systems were vsprintf(s,.)
+     * returns s, instead of the len. */
+    if (len != EOF && len != (int) NULL)
+        PS_len += strlen(PS_string+PS_len);
+    va_end(args);
+    return(len);
 }
-#endif /* not BROKEN_SOLARIS_COMPILER_STDARG */
+#endif
 
 /*__________________________________________________________________________
  |
@@ -736,7 +724,9 @@
 
   if (t2 == NULL)
   {
+#ifdef VERBOSE
     fprintf (stderr, "PStext malloc failed\n");
+#endif
     return;
   }
 
@@ -1392,7 +1382,9 @@
     rleline = (unsigned char *) XtMalloc (w * 2);
     if (!rleline)
     {
+#ifdef VERBOSE
       fprintf (stderr, "failed to malloc space for rleline\n");
+#endif
       return;
     }
 
diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTML.c ./libhtmlw/HTML.c
--- ../chimera-1.70p0/libhtmlw/HTML.c	Tue May  6 01:07:42 1997
+++ ./libhtmlw/HTML.c	Thu May 22 11:22:39 1997
@@ -362,6 +362,11 @@
     XtOffset (HTMLWidget, html.html_errmsg_cutoff),
     XtRString, "0"
   },
+  { WbNtruncateALT,
+    WbCTruncateALT, XtRInt, sizeof(int),
+    XtOffset(HTMLWidget, html.truncate_alt),
+    XtRString, "60"
+  },
   {
     WbNimageBorders,
     WbCImageBorders, XtRBoolean, sizeof (Boolean),
@@ -369,6 +374,18 @@
     XtRString, "False"
   },
   {
+    WbNdelayedImageBorders,
+    WbCDelayedImageBorders, XtRBoolean, sizeof (Boolean),
+    XtOffset (HTMLWidget, html.border_delayed_images),
+    XtRString, "True"
+  },
+  {
+    WbNuseBodyColors,
+    WbCUseBodyColors, XtRBoolean, sizeof (Boolean),
+    XtOffset (HTMLWidget, html.use_body_colors),
+    XtRString, "True"
+  },
+  {
     WbNdelayImageLoads,
     WbCDelayImageLoads, XtRBoolean, sizeof (Boolean),
     XtOffset (HTMLWidget, html.delay_images),
@@ -1067,7 +1084,7 @@
   XtAddEventHandler ((Widget) hw->html.view, ExposureMask, True,
 		     (XtEventHandler) DrawExpose, (caddr_t) hw);
   /*
-   * As described previoisly, for some reason with Motif1.2/X11R5
+   * As described previously, for some reason with Motif1.2/X11R5
    * the list actionsList is corrupted when we get here,
    * so we have to use the special copy SpareActionsList
    */
@@ -1643,6 +1660,22 @@
   }
 
   /*
+   *    Set ALT string truncation to something reasonable
+   *    --GN 1997May22
+   */
+  if (new->html.truncate_alt == 0)
+    new->html.truncate_alt = 1024; /* effectively turns off truncation */
+  else if (new->html.truncate_alt < 7)
+    new->html.truncate_alt = 7;
+
+  /*
+   *    Save the initial color settings to internal variables
+   *    so we can retrieve them later
+   *    - djhjr - May 19 97
+   */
+  HTMLStoreDefaultBodyAttr ((Widget)new);
+
+  /*
    * Initialize the document's object lists and properties
    */
   new->html.formatted_elements = NULL;
@@ -1658,7 +1691,8 @@
    * Parse the raw text with the HTML parser.
    * (This code used to precede formatted_elements = NULL above, but calling
    *  HTMLParse and then discarding whatever it produced looked like a memory
-   *  leak as well as bad policy.  -WBE 97May04)
+   *  leak as well as bad policy.  -WBE 97May04) [Not true, the parser only
+   *  sets new->html.html_objects -- GN 1997May19]
    */
   new->html.html_objects = HTMLParse (NULL, request->html.raw_text);
   CallLinkCallbacks (new);
@@ -3150,7 +3184,9 @@
     atoms = (Atom *) XtMalloc (*num_params * sizeof (Atom));
     if (atoms == NULL)
     {
+#ifdef DEBUG
       fprintf (stderr, "cannot allocate atom list\n");
+#endif
       return;
     }
     XmuInternStrings (XtDisplay ((Widget) hw), params, *num_params, atoms);
@@ -3293,9 +3329,84 @@
   if (eptr != NULL && eptr != hw->html.cached_tracked_ele &&
       eptr->anchorHRef != NULL)
   {
+    char *c, *cp;
+    int len, alen = 0, hlen;
+    int delayed_only;
+
     hw->html.cached_tracked_ele = eptr;
+    /*
+     * We're going to display, in this order, and separated by single spaces:
+     *
+     * - "ISMAP", if the image is a delayed imagemap (in a form or otherwise)
+     * - (the recorded part of) the ALT string, enclosed in double quotes,
+     *   if there was one (eptr->img_data->alt != NULL) and if we are one a
+     *   delayed image  (which will be anchored, but with a useless anchorHRef
+     *   unless it is contained in a genuine anchor element),  and
+     * - the current anchorHRef, preceded by "->", unless this is a delayed
+     *   image not contained in a genuine anchor  (i.e. unless IsDelayedHRef
+     *   returns True).
+     *
+     * We flag various cases by setting hlen to strlen(eptr->anchorHRef)
+     * or 0  (NB the anchorHRef is non-NULL here),  and alen to
+     * strlen(eptr->img_data->alt)  or to -1 if that is NULL.  We allocate
+     * a string sufficiently long to cover all cases, possibly wasting
+     * a part of it.
+     */
+
+    delayed_only = IsDelayedHRef(hw, eptr->anchorHRef);
+    if (delayed_only)
+      hlen = 0;
+    else
+      hlen = strlen(eptr->anchorHRef);
+#ifdef DEBUG_HREF_DISPLAY
+    fprintf(stderr, "HREF: %s %d\n", eptr->anchorHRef, hlen);
+#endif
+
+    if (eptr->img_data != (IMGInfo *) NULL &&
+	(delayed_only ||
+	 (eptr->img_data->pic_data != NULL &&
+	  eptr->img_data->pic_data->delayed)))
+    {
+      if (eptr->img_data->alt != (const char *) NULL)
+	alen = strlen(eptr->img_data->alt);
+      else
+	alen = -1;		/* flag absence of ALT tag */
+
+      cp = c = alloc_mem (12 + alen + hlen);	/* worst case */
+				/* ("ISMAP \"\" ->" and a '\0') */
+      *cp = '\0';		/* terminate it -- it might stay that way */
+
+      if (eptr->img_data != (IMGInfo *) NULL  && /* paranoia */
+	  eptr->img_data->ismap)
+      {
+	strcpy(cp, "ISMAP");	/* this terminates the string-so-far */
+	cp += 5;
+      }
+      if (alen >= 0)
+      {
+	if (cp > c) *cp++ = ' '; /* separating space, if necessary */
+	*cp++ = '\"';
+	strcpy(cp, eptr->img_data->alt);
+	cp += alen;
+	*cp++ = '\"';
+	*cp = '\0';		/* dunno yet whether anything will follow */
+      }
+      if (hlen > 0)
+      {
+	if (cp > c) *cp++ = ' '; /* separating space, if necessary */
+	strcpy(cp, "->");
+	strcpy(cp + 2, eptr->anchorHRef);
+      }
+    }
+    else			/* no delayed image, just track the HRef */
+    {
+      c = alloc_mem (3 + hlen);
+      strcpy(c, "->");
+      strcpy(c + 2, eptr->anchorHRef);
+    }
     (*(pointerTrackProc)
-     (hw->html.pointer_motion_callback)) (hw, eptr->anchorHRef);
+     (hw->html.pointer_motion_callback)) (hw, c);
+    free_mem(c);
     XDefineCursor (XtDisplay (hw), XtWindow (hw), in_anchor_cursor);
   }
   /*
@@ -4645,7 +4756,9 @@
   atoms = (Atom *) XtMalloc (2 * sizeof (Atom));
   if (atoms == NULL)
   {
+#ifdef DEBUG
     fprintf (stderr, "cannot allocate atom list\n");
+#endif
     return;
   }
   XmuInternStrings (XtDisplay ((Widget) hw), params, 2, atoms);
@@ -4776,7 +4889,9 @@
   text = (char *) XtMalloc (length + 1);
   if (text == NULL)
   {
+#ifdef DEBUG
     fprintf (stderr, "No space for return string\n");
+#endif
     return (NULL);
   }
   strcpy (text, "");
@@ -5440,4 +5555,34 @@
   {
     return (-1);
   }
+}
+
+
+/* added this - djhjr - May 19 97 */
+void
+HTMLStoreDefaultBodyAttr (Widget w)
+{
+  HTMLWidget hw = (HTMLWidget)w;
+
+  hw->html.default_anchor_fg = hw->html.anchor_fg;
+  hw->html.default_activeAnchor_fg = hw->html.activeAnchor_fg;
+  hw->html.default_visitedAnchor_fg = hw->html.visitedAnchor_fg;
+  hw->html.default_foreground = hw->html.foreground;
+  hw->html.default_activeAnchor_bg = hw->html.activeAnchor_bg;
+  hw->html.default_background = hw->core.background_pixel;
+}
+
+
+/* added this - djhjr - May 19 97 */
+void
+HTMLRestoreDefaultBodyAttr (Widget w)
+{
+  HTMLWidget hw = (HTMLWidget)w;
+
+  hw->html.anchor_fg = hw->html.default_anchor_fg;
+  hw->html.activeAnchor_fg = hw->html.default_activeAnchor_fg;
+  hw->html.visitedAnchor_fg = hw->html.default_visitedAnchor_fg;
+  hw->html.foreground = hw->html.default_foreground;
+  hw->html.activeAnchor_bg = hw->html.default_activeAnchor_bg;
+  hw->core.background_pixel = hw->html.default_background;
 }
diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTML.h ./libhtmlw/HTML.h
--- ../chimera-1.70p0/libhtmlw/HTML.h	Sun May  4 10:49:32 1997
+++ ./libhtmlw/HTML.h	Thu May 22 14:16:59 1997
@@ -129,10 +129,13 @@
 	int ismap;		/* if image has the ISMAP attribute */
 	FormInfo *fptr;		/* if image is part of a Form */
 	const char *text;	/* HTML tag NAME= value for image */
+	const char *alt;	/* HTML att ALT= value --GN 1997May22 */
+	int border_width;	/* HTML att BORDER= value - djhjr - May 9 97 */
 	/* int width, height; if  override is ever supported */
 } IMGInfo;
 
-#define FreeIMGInfo(x)  XtFree ((char *)(x));  /* x=NULL OK */
+#define FreeIMGInfo(x) {if (x) XtFree((char *)((x)->alt)); \
+			XtFree ((char *)(x));} /* x=NULL OK */
 
 typedef struct wid_rec {
 	Widget w;
@@ -269,6 +272,7 @@
 #define M_TABLE_HEADER	47
 #define M_TABLE_ROW	48
 #define M_CAPTION       49
+#define M_BODY		50	/* djhjr - May 9 97 */
 
 /* syntax of Mark types */
 #define	MT_TITLE	"title"
@@ -320,6 +324,7 @@
 #define MT_TABLE_HEADER	"th"
 #define MT_TABLE_ROW	"tr"
 #define MT_CAPTION      "caption"
+#define MT_BODY		"body"	/* djhjr - May 9 97 */
 
 /* anchor tags */
 #define	AT_NAME		"name"
@@ -355,8 +360,11 @@
 #define	WbNactiveAnchorBG	"activeAnchorBG"
 #define	WbNfancySelections	"fancySelections"
 #define	WbNimageBorders		"imageBorders"
+#define WbNdelayedImageBorders	"delayedImageBorders"
+#define WbNuseBodyColors	"useBodyColors"
 #define	WbNdelayImageLoads	"delayImageLoads"
 #define WbNhtmlErrorMsgCutoff   "htmlErrorMsgCutoff"
+#define WbNtruncateALT          "truncateALT"
 #define	WbNisIndex		"isIndex"
 #define	WbNitalicFont		"italicFont"
 #define	WbNboldFont		"boldFont"
@@ -378,9 +386,9 @@
 #define	WbNlinkCallback		"linkCallback"
 #define	WbNsubmitFormCallback	"submitFormCallback"
 #define	WbNpreviouslyVisitedTestFunction "previouslyVisitedTestFunction"
-#define	WbNresolveImageFunction "resolveImageFunction"
-#define	WbNresolveDelayedImage "resolveDelayedImage"
-#define	WbNpercentVerticalSpace "percentVerticalSpace"
+#define	WbNresolveImageFunction	"resolveImageFunction"
+#define	WbNresolveDelayedImage	"resolveDelayedImage" /* used?? */
+#define	WbNpercentVerticalSpace	"percentVerticalSpace"
 #define WbNpointerMotionCallback "pointerMotionCallback"
 #define WbNverticalScrollOnRight "verticalScrollOnRight"
 #define WbNhorizontalScrollOnTop "horizontalScrollOnTop"
@@ -409,8 +417,11 @@
 #define	WbCActiveAnchorBG	"ActiveAnchorBG"
 #define	WbCFancySelections	"FancySelections"
 #define	WbCImageBorders		"ImageBorders"
+#define WbCDelayedImageBorders	"DelayedImageBorders"
+#define WbCUseBodyColors	"UseBodyColors"
 #define	WbCDelayImageLoads	"DelayImageLoads"
 #define WbCHTMLErrorMsgCutoff   "HTMLErrorMsgCutoff"
+#define WbCTruncateALT          "TruncateALT"
 #define	WbCIsIndex		"IsIndex"
 #define	WbCItalicFont		"ItalicFont"
 #define	WbCBoldFont		"BoldFont"
@@ -478,5 +489,8 @@
 					   ElementRef *m_start,
 					   ElementRef *m_end,
 					   int backward, int caseless));
+/* added these two - djhjr - May 19 97 */
+extern void HTMLStoreDefaultBodyAttr _ArgProto((Widget w));
+extern void HTMLRestoreDefaultBodyAttr _ArgProto((Widget w));
 
 #endif /* HTML_H */
diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTMLP.h ./libhtmlw/HTMLP.h
--- ../chimera-1.70p0/libhtmlw/HTMLP.h	Sun May  4 19:39:53 1997
+++ ./libhtmlw/HTMLP.h	Thu May 22 10:21:59 1997
@@ -106,7 +106,7 @@
 	char			*header_text;
 	char			*footer_text;
 /*
- * Without motif we have to define our own forground resource
+ * Without motif we have to define our own foreground resource
  * instead of using the manager's
  */
 	Pixel			foreground;
@@ -114,15 +114,25 @@
 	Pixel			visitedAnchor_fg;
 	Pixel			activeAnchor_fg;
 	Pixel			activeAnchor_bg;
+/* added these six - djhjr - May 9,10 97 */
+	Pixel			default_foreground;
+	Pixel			default_background;
+	Pixel			default_anchor_fg;
+	Pixel			default_visitedAnchor_fg;
+	Pixel			default_activeAnchor_fg;
+	Pixel			default_activeAnchor_bg;
 	int			num_anchor_underlines;
 	int			num_visitedAnchor_underlines;
 	Boolean			dashed_anchor_lines;
 	Boolean			dashed_visitedAnchor_lines;
 	Boolean			fancy_selections;
 	Boolean			border_images;
+	Boolean			border_delayed_images;
+	Boolean			use_body_colors;
 	Boolean			delay_images;
 	Boolean			is_index;
 	int			html_errmsg_cutoff;  /* <0 off, else do if > */
+	int                     truncate_alt;
 	int			percent_vert_space;
 
 	XFontStruct		*font;
diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTMLformat.c ./libhtmlw/HTMLformat.c
--- ../chimera-1.70p0/libhtmlw/HTMLformat.c	Tue May  6 00:58:12 1997
+++ ./libhtmlw/HTMLformat.c	Thu May 22 14:34:20 1997
@@ -117,6 +117,9 @@
 extern void PrepareFormEnd ();
 extern char *ComposeCommaList ();
 extern void FreeCommaList ();
+/* added this - djhjr - May 11 97 */
+static Boolean ParseBodyAttr (/* HTMLWidget hw, char *tag, char *attr,
+				 Pixel *value */);
 
 /*
  * To allow arbitrary nesting of lists
@@ -263,8 +266,12 @@
 
   EmptyRegion = False;		/* there's about to be at least 1 element */
 
-/* if (type == E_TEXT)  printf (" %d/[%d+%d,%d]'%s'%p ", LineNumber, y,LineHeight,x, edata, fp); else printf (" %d/[%d,%d]%c ", LineNumber, y,x, "0tbLiWh"[type]); /*DEBUG*/
-
+#ifdef DEBUG_ADDFELEMENT
+  if (type == E_TEXT)
+    printf (" %d/[%d+%d,%d]'%s'%p ", LineNumber, y,LineHeight,x, edata, fp);
+  else
+    printf (" %d/[%d,%d]%c ", LineNumber, y,x, "0tbLiWh"[type]);
+#endif
   /*
    * If the linked list of elements is empty, or if we've reached
    * the "physical" end of the list, we have to create a new element and
@@ -279,6 +286,7 @@
     eptr = (struct ele_rec *) XtMalloc (sizeof(struct ele_rec));
     if (eptr == NULL)
     {
+      /* panicking */
       fprintf (stderr, "AddFElement: memory alloc failed\n");
       exit (1);
     }
@@ -489,13 +497,17 @@
      */
     if (eptr->widget_data == NULL)
     {
+#ifdef DEBUG
       fprintf (stderr, "AddFElement: Could not make widget.\n");
+#endif
     }
 
     break;
 
   default:
+#ifdef DEBUG
     fprintf (stderr, "AddFElement:  Unknown type %d\n", type);
+#endif
     eptr->ele_id = ElementId;
     break;
   }
@@ -574,8 +586,9 @@
     }
   }
   /* (else) non-table LFs have width=0, meaning "infinitely far right" */
-/* printf (" LF@[%d,%d-%d] ", *y, *x, *x + Current->width); /*DEBUG*/
-
+#ifdef DEBUG_LINEFEEDPLACE
+  printf (" LF@[%d,%d-%d] ", *y, *x, *x + Current->width);
+#endif
   *x = TextIndent;
   *y = *y + BaseLine + LineBottom;
 
@@ -744,8 +757,10 @@
 {
   int baseline = Current->font->max_bounds.ascent;
 
-/* printf (" ABL baseline= %d, Baseline= %d, LB= %d, LH= %d\n", baseline, BaseLine, LineBottom, LineHeight); /*DEBUG*/
-
+#ifdef DEBUG_ADJUSTBASELINE
+  printf (" ABL baseline= %d, Baseline= %d, LB= %d, LH= %d\n",
+	  baseline, BaseLine, LineBottom, LineHeight);
+#endif
   if (!HaveRealBaseLine (baseline))
   {
     /* this section intentionally left blank */
@@ -1537,9 +1552,11 @@
 unsigned int width;		/* = right hand margin */
 {
   struct ele_rec *const savedCurrent = Current;
-  char *tptr;
+  char *tptr, *aptr;
   char *spc;
   int dx, dy;			/* image width and height, incl. borders */
+  /* added this - djhjr - May 9 97 */
+  int border = IMAGE_BORDER;
   int extra;
   int marginw = (CurrentTable != NULL) ?  0 : MarginW;
 
@@ -1551,7 +1568,16 @@
   /*
    * Place the image in order to find out its dimensions.
    * If it doesn't fit on the line, back up Current and start over.
+   * Yank out the SRC, ALT and BORDER attributes here (ALT added by GN,
+   * BORDER by djhjr, May 9 97)
    */
+  if (tptr = ParseMarkTag (taginfo, MT_IMAGE, "BORDER"))
+  {
+    int border_spec = atoi(tptr);
+    if (border_spec < 0) border_spec = 0;
+    border = border_spec;
+    XtFree(tptr);
+  }
 
   tptr = ParseMarkTag (taginfo, MT_IMAGE, "SRC");
   AddFElement (hw, E_IMAGE, currentFont, *x, *y, tptr);
@@ -1559,9 +1585,14 @@
    * AddFElement promises pic_data will be something usable.
    */
 
+  if (hw->html.border_delayed_images &&
+      Current->img_data->pic_data->delayed &&
+      border < IMAGE_BORDER)
+    border = IMAGE_BORDER;
+
   if (hw->html.border_images == True  ||  Current->anchorHRef != NULL)
   {
-    extra = 2 * IMAGE_BORDER;
+    extra = 2 * border;		/* djhjr - May 9 97 */
   }
   else
   {
@@ -1591,11 +1622,35 @@
   if (tptr != NULL) XtFree(tptr);
 
   /*
-   * Yank out the name field, and stick it in text.
-   * We may use this for ALT to at some later date.
+   * Yank out the name and alt fields, and stick them in text and alt.
+   * alt added --GN 1997May22
    */
   tptr = ParseMarkTag (taginfo, MT_IMAGE, "NAME");
   Current->img_data->text = tptr;
+  /* stash the border width, too - djhjr - May 9 97 */
+  Current->img_data->border_width = border;
+
+  aptr = ParseMarkTag (taginfo, MT_IMAGE, "ALT");
+  if (aptr != (char *) NULL && *aptr)
+  {
+    char *alt, *t, *c;
+    int trunc_alt = hw->html.truncate_alt;
+
+    alt = (char *) XtMalloc((trunc_alt + 4) * sizeof(char));
+    strncpy(alt, aptr, trunc_alt);
+    if (strlen(aptr) > trunc_alt)
+      strcpy(alt + trunc_alt, "...");
+    else
+      alt[trunc_alt] = '\0';
+    XtFree ((char *) aptr);
+    aptr = alt;
+  }
+#ifdef DEBUG_HREF_DISPLAY
+  fprintf(stderr, "Recording ALT=\"%s\"\n", aptr);
+#endif
+
+  Current->img_data->alt = (const char *) aptr;
+  /* (Freed later by FreeIMGInfo called from FreeLineList or HTMLGetImage) */
 
   /*
    * Check if this image has the ISMAP attribute, so we know the
@@ -1679,7 +1734,10 @@
     if (baseline <= BaseLine)
     {
       Current->y_offset = BaseLine - baseline;
-/* printf (" [%d,%d]I(m): ý=%d (%d-%d) ", Current->y,Current->x, Current->y_offset, BaseLine, baseline); /*DEBUG*/
+#ifdef DEBUG_IMAGEPLACE
+      printf (" [%d,%d]I(m): ý=%d (%d-%d) ", Current->y, Current->x,
+	      Current->y_offset, BaseLine, baseline);
+#endif
     }
     else
     {
@@ -1697,7 +1755,10 @@
       for (eptr = Current->prev;  eptr != PrevContextEnd;  eptr = eptr->prev)
       {
 	eptr->y_offset += incy;
-/* printf (" [%d,%d]I(m) set [%d,%d]ý+=%d ", Current->y,Current->x, eptr->y, eptr->x, incy); /*DEBUG*/
+#ifdef DEBUG_IMAGEPLACE
+	printf (" [%d,%d]I(m) set [%d,%d]ý+=%d ", Current->y, Current->x,
+		eptr->y, eptr->x, incy);
+#endif
       }
     }
   }
@@ -1706,7 +1767,10 @@
     if (dy <= BaseLine)
     {
       Current->y_offset = BaseLine - dy;
-/* printf (" [%d,%d]I(b): ý=%d (%d-%d) ", Current->y,Current->x, Current->y_offset, BaseLine, dy); /*DEBUG*/
+#ifdef DEBUG_IMAGEPLACE
+      printf (" [%d,%d]I(b): ý=%d (%d-%d) ", Current->y, Current->x,
+	      Current->y_offset, BaseLine, dy);
+#endif
     }
     else
     {
@@ -1722,7 +1786,10 @@
       for (eptr = Current->prev;  eptr != PrevContextEnd;  eptr = eptr->prev)
       {
 	eptr->y_offset += incy;
-/* printf (" [%d,%d]I(b) set [%d,%d]ý+=%d ", Current->y,Current->x, eptr->y, eptr->x, incy); /*DEBUG*/
+#ifdef DEBUG_IMAGEPLACE
+	printf (" [%d,%d]I(b) set [%d,%d]ý+=%d ", Current->y, Current->x,
+		eptr->y, eptr->x, incy);
+#endif
       }
     }
   }
@@ -1859,7 +1926,10 @@
       for (eptr = Current->prev;  eptr != PrevContextEnd;  eptr = eptr->prev)
       {
 	eptr->y_offset += incy;
-/* printf (" [%d,%d]W set [%d,%d]y+=%d ", Current->y,Current->x, eptr->y, eptr->x, incy); /*DEBUG*/
+#ifdef DEBUG_WIDGETPLACE
+	printf (" [%d,%d]W set [%d,%d]y+=%d ", Current->y, Current->x,
+		eptr->y, eptr->x, incy);
+#endif
       }
 
       /*
@@ -1886,9 +1956,9 @@
 XFontStruct *font;
 {
   FontRec *fptr;
-
-/* printf (" PushFont %p ", font); /*DEBUG*/
-
+#ifdef DEBUG_PUSHFONT
+  printf (" PushFont %p ", font);
+#endif
   fptr = (FontRec *)XtMalloc(sizeof(FontRec));
   fptr->font = font;
   fptr->next = FontStack;
@@ -1907,7 +1977,9 @@
     fptr = FontStack;
     FontStack = FontStack->next;
     font = fptr->font;
-/* printf (" PopFont %p ", font); /*DEBUG*/
+#ifdef DEBUG_POPFONT
+    printf (" PopFont %p ", font);
+#endif
     XtFree((char *) fptr);
   }
   else
@@ -1916,7 +1988,9 @@
     fprintf (stderr, "Warning, popping empty font stack!\n");
 #endif
     font = FontStack->font;
-/* printf (" EmptyPop to %p ", font); /*DEBUG*/
+#ifdef DEBUG_POPFONT
+    printf (" EmptyPop to %p ", font);
+#endif
   }
 
   return (font);
@@ -2185,7 +2259,7 @@
 
 	XtFree (tptr);
       }
-      if (wrap)  LineFeed (hw, x, y, 1);  /* requires CurrentTable==NULL! */
+      if (wrap)  LineFeed (hw, x, y);  /* requires CurrentTable==NULL! */
     }
     else
     {
@@ -2220,7 +2294,7 @@
     CurrentTable->cellpadding = ((n < 0) ?  0 : n*4) + 3;
 
 #ifdef TABLE_DEBUG
- printf ("\n%s D%d @[%d,%d]\n", opstr, TableDepth, *y, *x); /*DEBUG*/
+    printf ("\n%s D%d @[%d,%d]\n", opstr, TableDepth, *y, *x);
 #endif
 }
 
@@ -2232,7 +2306,7 @@
 int *x, *y;
 {
 #ifdef TABLE_DEBUG
- printf ("%s %d\n", opstr, TableDepth); /*DEBUG*/
+  printf ("%s %d\n", opstr, TableDepth);
 #endif
    if (CurrentTable != NULL)
    {
@@ -2261,7 +2335,11 @@
        if (deltax > 0)
        {
 	 WidenTableColumn (col, deltax);
-/* if (col < CurrentTable->ncols)  printf ("\n crazy widen: moving col %d at %d + %d\n", col+1, x0, deltax); /*DEBUG*/
+#ifdef TABLE_DEBUG
+	 if (col < CurrentTable->ncols)
+	   printf ("\n crazy widen: moving col %d at %d + %d\n",
+		   col+1, x0, deltax);
+#endif
 	 prevx0 = x0 + deltax;
        }
        else prevx0 = x0;
@@ -2285,10 +2363,14 @@
 	   /*
 	    * If this happens, someone's installed a bug.  Complain.
 	    */
-	   fprintf (stderr, "\a\nL#%d [%d,%d]: Bug in %s Table item width fixup: %d > %d\n\a",
-		    eptr->line_number, eptr->y + eptr->y_offset, eptr->x,
-		    ((eptr->type == E_HRULE) ? "HR" : "LF"),
-		    w, CurrentTable->ncols);
+#ifdef TABLE_DEBUG
+	   fprintf
+	     (stderr,
+	      "\nL#%d [%d,%d]: Bug in %s Table item width fixup: %d > %d\n",
+	      eptr->line_number, eptr->y + eptr->y_offset, eptr->x,
+	      ((eptr->type == E_HRULE) ? "HR" : "LF"),
+	      w, CurrentTable->ncols);
+#endif
 	   w = CurrentTable->ncols;
 	 }
 	 if (eptr->type == E_HRULE)
@@ -2382,7 +2464,7 @@
     CharsInLine = 0;
     CurrentTable->state = TBL_ROW_OPEN;
 #ifdef TABLE_DEBUG
- printf("%s D%d, L#%d @[%d,%d]\n", opstr, TableDepth, LineNumber, *y, *x); /*DEBUG*/
+    printf("%s D%d, L#%d @[%d,%d]\n", opstr, TableDepth, LineNumber, *y, *x);
 #endif
 }
 
@@ -2417,7 +2499,7 @@
     if (*y < CurrentTable->Ymax)  *y = CurrentTable->Ymax;
     CurrentTable->state = TBL_OPEN;
 #ifdef TABLE_DEBUG
- printf ("\n%s D%d, L#%d, *y=%d\n", opstr, TableDepth, LineNumber, *y); /*DEBUG*/
+    printf ("\n%s D%d, L#%d, *y=%d\n", opstr, TableDepth, LineNumber, *y);
 #endif
 }
 
@@ -2446,7 +2528,10 @@
       {
 	/* retroactively adjust everything */
 	WidenTableColumn (mycol, deltax);
-/* printf ("widen1: col %d moved from %d --> %d\n", mycol+1, myx0, loc); /*DEBUG*/
+#ifdef TABLE_DEBUG
+	printf ("widen1: col %d moved from %d --> %d\n",
+		mycol+1, myx0, loc);
+#endif
       }
       else
       {
@@ -2520,7 +2605,11 @@
     else Width = CurrentTable->oldWidth;  /* at last column (so far) */
 
     w = CurrentTable->col_x0[nextcol];
-/* printf ("T%d, c%d: %d + (%d-%d) * %d/%d = %d vs %d\n", TableDepth, mycol+1, myx0, CurrentTable->oldWidth, CurrentTable->tbl_x0, span, sx, Width, w - pad); /*DEBUG*/
+#ifdef TABLE_DEBUG
+    printf ("T%d, c%d: %d + (%d-%d) * %d/%d = %d vs %d\n",
+	    TableDepth, mycol+1, myx0, CurrentTable->oldWidth,
+	    CurrentTable->tbl_x0, span, sx, Width, w - pad);
+#endif
     if (w - pad > Width)   Width = w - pad;
 
     w -= myx0;			/* is <0 for new cols */
@@ -2554,7 +2643,10 @@
 	  int deltax = loc - nextx0;
 	  /* retroactively adjust everything */
 	  WidenTableColumn (nextcol, deltax);
-/* printf ("widen2: col %d moved from %d --> %d\n", nextcol+1, nextx0, loc); /*DEBUG*/
+#ifdef TABLE_DEBUG
+	  printf ("widen2: col %d moved from %d --> %d\n",
+		  nextcol+1, nextx0, loc);
+#endif
 	}
 #endif
       }
@@ -2566,7 +2658,9 @@
     CurrentTable->nextcol = nextcol;
 
 #ifdef TABLE_DEBUG
- printf("%s D%d#%d*%d @[%d,%d-%d]  W%d\n", opstr, TableDepth, mycol+1, span, *y, *x, CurrentTable->col_x0[nextcol], w); /*DEBUG*/
+    printf("%s D%d#%d*%d @[%d,%d-%d]  W%d\n",
+	   opstr, TableDepth, mycol+1, span, *y, *x,
+	   CurrentTable->col_x0[nextcol], w);
 #endif
 }
 
@@ -2593,7 +2687,8 @@
     }
 
 #ifdef TABLE_DEBUG
- printf ("\n%s @[%d,%d] D%d, Ymax %d, L#%d\n", opstr, *y, *x, TableDepth, CurrentTable->Ymax, LineNumber); /*DEBUG*/
+    printf ("\n%s @[%d,%d] D%d, Ymax %d, L#%d\n",
+	    opstr, *y, *x, TableDepth, CurrentTable->Ymax, LineNumber);
 #endif
     /* suppress spurious formatted output of whitespace after  */
     NeedSpace = 0;
@@ -2984,12 +3079,12 @@
       font = hw->html.header6_font;
     }
     break;
+
     /*
      * Anchors change the text color, and may set
      * underlining attributes.
      * No linefeeds, so they can be imbedded anywhere.
      */
-
   case M_ANCHOR:
     if (mark->is_end)
     {
@@ -3044,6 +3139,32 @@
     break;
 
     /*
+     * BODY tag attributes change the text, border and underline colors
+     * of anchors, the text foreground color, and the background color -
+     * this'll support 'em if found at the tag start - djhjr - May 11,13 97
+     */
+  case M_BODY:
+    if (!mark->is_end)
+    {
+      ParseBodyAttr (hw, mark->start,
+		     "LINK", &hw->html.anchor_fg);
+      ParseBodyAttr (hw, mark->start,
+		     "ALINK", &hw->html.activeAnchor_fg);
+      ParseBodyAttr (hw, mark->start,
+		     "VLINK", &hw->html.visitedAnchor_fg);
+      ParseBodyAttr (hw, mark->start,
+		     "TEXT", &hw->html.foreground);
+      if (ParseBodyAttr (hw, mark->start,
+			 "BGCOLOR", &hw->core.background_pixel))
+	hw->html.activeAnchor_bg = hw->core.background_pixel;
+
+      Fg = hw->html.foreground;
+      Bg = hw->core.background_pixel;
+    }
+
+    break;
+
+    /*
      * Just insert a linefeed, or ignore if this is prefomatted
      * text because the 

will be followed by a linefeed. */ @@ -3626,7 +3747,10 @@ { if (mark->is_end) { -/* if (CurrentTable->state != TBL_ITEM_OPEN) printf ("<%s> but in state %d?\n", mark->end, CurrentTable->state); /*DEBUG*/ +#ifdef TABLE_DEBUG + if (CurrentTable->state != TBL_ITEM_OPEN) + printf ("<%s> but in state %d?\n", mark->end, CurrentTable->state); +#endif if (CurrentTable->state == TBL_ITEM_OPEN) Table_Item_Close (hw, mark->end, x, y); /* if state isn't TBL_ITEM_OPEN, it's too late now to fix things */ @@ -4094,12 +4218,15 @@ */ hw->html.is_index = False; + /* ham-fisted, but guaranteed - djhjr - May 13 97, moved here GN 1997May21 */ + HTMLRestoreDefaultBodyAttr ((Widget)hw); + /* * Initialize local variables, some from the widget */ - MarginW = hw->html.margin_width; Fg = hw->html.foreground; Bg = hw->core.background_pixel; + MarginW = hw->html.margin_width; Underlines = 0; DashedUnderlines = False; Width = width; @@ -4428,6 +4555,14 @@ *Fwidth = MaxWidth; } + /* added this - better here than in the callers? - djhjr - May 11 97 */ + { + Arg arg[1]; + + XtSetArg(arg[0], XtNbackground, hw->core.background_pixel); + XtSetValues(hw->html.view, arg, 1); + } + #ifdef TIMING gettimeofday (&Tv, &Tz); fprintf (stderr, "FormatAll exit (%d.%d)\n", Tv.tv_sec, Tv.tv_usec); @@ -4451,7 +4586,9 @@ x1 = eptr->x; if (x1 < -20000) { - fprintf (stderr, "\aTABLE BUG! LF refresh with x=%d\n\a", x1); +#ifdef TABLE_DEBUG + fprintf (stderr, "TABLE BUG! LF refresh with x=%d\n", x1); +#endif return; /* who knows where it should have been */ } @@ -4850,7 +4987,9 @@ /* * If this ever happens, somebody's introduced a bug. Complain. (WBE) */ - fprintf (stderr, "\aBad width (%d) in


\n\a", width); +#ifdef TABLE_DEBUG + fprintf (stderr, "Bad width (%d) in
\n", width); +#endif width = 0; } @@ -4897,7 +5036,7 @@ if (hw->html.border_images == True || eptr->anchorHRef != NULL) { - extra = IMAGE_BORDER; + extra = eptr->img_data->border_width; /* - djhjr - May 9 97 */ } else { @@ -5106,9 +5245,9 @@ x = x + hw->html.scroll_x; y = y + hw->html.scroll_y; - -/* printf (" find %d,%d:", y, x); /*DEBUG*/ - +#ifdef DEBUG_LOCATEELEMENT + printf (" find %d,%d:", y, x); +#endif /* * Narrow the search down to a 2 line range * before beginning to search element by element @@ -5305,9 +5444,13 @@ */ if (rptr != NULL) { - -/* printf (" matched %d/[%d,%d]-%c'%s' ", rptr->line_number, rptr->y + rptr->y_offset,rptr->x, "0tbLiWh"[rptr->type], (rptr->type == E_TEXT ? rptr->edata : "")); fflush(stdout); /*DEBUG*/ - +#ifdef DEBUG_LOCATEELEMENT + printf (" matched %d/[%d,%d]-%c'%s' ", + rptr->line_number, rptr->y + rptr->y_offset, rptr->x, + "0tbLiWh"[rptr->type], + (rptr->type == E_TEXT ? rptr->edata : "")); + fflush(stdout); +#endif if (rptr->type != E_TEXT || x < rptr->x) { *pos = 0; @@ -5621,8 +5764,10 @@ int line = lineadj + ((eptr->y + eptr->y_offset) - ymin) / height; if (line >= maxlines -1) { - fprintf (stderr, "\aProblem in conversion to string: L%d? (>%d)\n\a", +#ifdef DEBUG_PARSETEXTTOSTRING + fprintf (stderr, "Problem in conversion to string: L%d? (>%d)\n", line, maxlines - 2); +#endif fflush (stderr); line = maxlines - 2; } @@ -5839,4 +5984,55 @@ width = lwidth; } return (width); +} + + +/* + * BODY tag attributes change the text, border and underline colors + * of anchors, the text foreground color, and the background color - + * djhjr - May 11 97 + */ +static Boolean +ParseBodyAttr (HTMLWidget hw, char *tag, char *attr, Pixel *value) +{ + char *col_spec, *t; + XColor xcolor; + Colormap cmap; + + if (!(hw->html.use_body_colors)) + return (False); + + if (col_spec = t = ParseMarkTag(tag, MT_BODY, attr)) + { + /* + * yech! some HTML "authors" don't bother with the + * leading '#' on RGB values, so this gross hack - + * probably grabs a couple valid color names... + */ + if (strlen(col_spec) == 6 && + !strcspn(col_spec, "0123456789ABCDEFabcdef")) + { + char tmp[8]; + + sprintf(tmp, "#%s", col_spec); + col_spec = tmp; + } + { + Arg arg[1]; + XtSetArg(arg[0], XtNcolormap, &cmap); + XtGetValues((Widget) hw, arg, 1); + } + if (XParseColor(XtDisplay(hw), cmap, col_spec, &xcolor) == 0) + { + XtFree(t); + return(False); + } + FindColor (XtDisplay(hw), cmap, &xcolor); + *value = xcolor.pixel; + + XtFree (t); + return (True); + } + + return (False); } diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTMLimages.c ./libhtmlw/HTMLimages.c --- ../chimera-1.70p0/libhtmlw/HTMLimages.c Sun May 4 19:28:27 1997 +++ ./libhtmlw/HTMLimages.c Thu May 22 13:51:49 1997 @@ -129,7 +129,8 @@ if (NumCells <= 2) { colr->pixel = (colr->red + colr->green + colr->blue > 98304) ? - WhitePixel(dsp, DefaultScreen(dsp)) : BlackPixel(dsp, DefaultScreen(dsp)) ; + WhitePixel(dsp, DefaultScreen(dsp)) : + BlackPixel(dsp, DefaultScreen(dsp)) ; XQueryColor(dsp, colormap, colr); return; } @@ -232,27 +233,6 @@ } - -int -hb (ul) -unsigned long ul; -{ - int i; - unsigned long testval; - - for (i = 31; i >= -1; i--) - { - if (i != -1) - { - testval = 1 << i; - if (testval & ul) - return i; - } - } - return -1; -} - - /* * Make an image of appropriate depth for display from image data. */ @@ -264,193 +244,184 @@ int depth; const ImageInfo *img_info; { - int linepad, shiftnum; - int shiftstart, shiftstop, shiftinc; - int bitsperpixel, scanline_pad; - int bytesperline; + int shiftnum, shiftstart, shiftstop, shiftinc; + int bpp; int temp; int w, h; XImage *newimage; - unsigned char *bit_data, *bitp, *datap; - Visual *theVisual; - int bmap_order; + unsigned char *bit_data, *bitp, *datap, *endofline; unsigned long c; int rshift, gshift, bshift; + int rmask, gmask, bmask; + Visual *theVisual = DefaultVisual(dsp, DefaultScreen(dsp)); - bitsperpixel = _XGetBitsPerPixel(dsp, depth); - scanline_pad = _XGetScanlinePad(dsp, depth); + /* We create the XImage first so that we can rely on Xlib to choose + * the correct bits_per_pixel and scanline width for the image. + * It's OK to pass a NULL data pointer to XCreateImage. + * Note we use a worst-case assumption of bitmap_pad = 32. + * + * (New code donated by Tom Lane also used in recent + * NCSA Mosaic, incorporated 1997May08) + */ + newimage = XCreateImage(dsp, theVisual, + depth, ZPixmap, 0, (char *) NULL, + width, height, 32, 0); + if (!newimage) + return NULL; + /* Allocate data space using scanline width from XCreateImage. */ + bit_data = (unsigned char *) XtMalloc(newimage->bytes_per_line * height); + newimage->data = (char *) bit_data; + if (!bit_data) { + XDestroyImage(newimage); + return NULL; + } - switch (bitsperpixel) - { - case 6: - case 8: - bit_data = (unsigned char *) XtMalloc (width * height); - memcpy(bit_data, data, (width * height)); - bytesperline = width; - newimage = XCreateImage (dsp, - DefaultVisual (dsp, DefaultScreen (dsp)), - depth, ZPixmap, 0, (char *) bit_data, - width, height, 8, bytesperline); - break; + /* Fill in the image data. */ + bpp = newimage->bits_per_pixel; /* not always the same as depth! */ + + switch(bpp) { case 1: case 2: case 4: - if (BitmapBitOrder (dsp) == LSBFirst) - { - shiftstart = 0; - shiftstop = 8; - shiftinc = bitsperpixel; - } - else - { - shiftstart = 8 - bitsperpixel; - shiftstop = -bitsperpixel; - shiftinc = -bitsperpixel; - } - linepad = scanline_pad - (width % scanline_pad); - bit_data = (unsigned char *) XtMalloc (((width + linepad) * height) - + 1); - bitp = bit_data; - datap = data; - *bitp = 0; - shiftnum = shiftstart; - for (h = 0; h < height; h++) - { - for (w = 0; w < width; w++) - { - temp = *datap++ << shiftnum; - *bitp = *bitp | temp; - shiftnum = shiftnum + shiftinc; - if (shiftnum == shiftstop) - { - shiftnum = shiftstart; - bitp++; - *bitp = 0; - } + /* FIXME: this code assumes byte_order == bitmap_bit_order */ + if (newimage->bitmap_bit_order==LSBFirst) { + shiftstart=0; + shiftstop=8; + shiftinc=bpp; + } + else { + shiftstart=8-bpp; + shiftstop=(-bpp); + shiftinc=(-bpp); + } + datap=data; + bitp=bit_data; + for (h=0; hbytes_per_line; + temp = 0; + shiftnum=shiftstart; + for (w=0; wbytes_per_line == width) { + /* easy if no padding needed */ + memcpy(bit_data, data, (width*height)); + } else { + /* copy a scanline at a time; don't bother to fill pad bytes */ + datap=data; + bitp=bit_data; + for (h=0; hbytes_per_line; } } - bytesperline = (width + linepad) * bitsperpixel / 8; - newimage = XCreateImage (dsp, - DefaultVisual (dsp, DefaultScreen (dsp)), - depth, ZPixmap, 0, (char *) bit_data, - (width + linepad), height, scanline_pad, - bytesperline); break; + /* - * WARNING: This depth 16 code is donated code for 16 bit - * TrueColor displays. I have no access to such displays, so I - * can't really test it. - * Donated by - andrew@icarus.demon.co.uk - * - * And its totally broken on different 16bit displays - * This hopefully fixes it. - DWH 6/10/94 - davidh@use.com + * Donated by - nosmo@ximage.com */ case 16: - { - unsigned long red_mask, green_mask, blue_mask; - int red_shift, green_shift, blue_shift; - Visual *visual_info; - - visual_info = DefaultVisual (dsp, DefaultScreen (dsp)); - - red_mask = visual_info->red_mask; - green_mask = visual_info->green_mask; - blue_mask = visual_info->blue_mask; - - red_shift = 15 - hb (red_mask); - green_shift = 15 - hb (green_mask); - blue_shift = 15 - hb (blue_mask); - - bit_data = (unsigned char *) XtMalloc (width * height * 2); - bitp = bit_data; - datap = data; - for (w = (width * height); w > 0; w--) - { - temp = (((img_info->reds[(int) *datap] >> red_shift) & - red_mask) | - ((img_info->greens[(int) *datap] >> green_shift) & - green_mask) | - ((img_info->blues[(int) *datap] >> blue_shift) & - blue_mask)); - - if (BitmapBitOrder (dsp) == MSBFirst) - { - *bitp++ = (temp >> 8) & 0xff; - *bitp++ = temp & 0xff; + rmask = theVisual->red_mask; + gmask = theVisual->green_mask; + bmask = theVisual->blue_mask; + rshift=15-highbit((unsigned long)rmask); + gshift=15-highbit((unsigned long)gmask); + bshift=15-highbit((unsigned long)bmask); + + datap=data; + bitp=bit_data; + if (newimage->byte_order==MSBFirst) { + for (h=0; hbytes_per_line; + for (w=width; w>0; w--) { + temp = (int) *datap++; + temp = ((img_info->reds[temp]>>rshift)&rmask)| + ((img_info->greens[temp]>>gshift)&gmask)| + ((img_info->blues[temp]>>bshift)&bmask); + *bitp++ = (temp>>8)&0xff; + *bitp++ = temp&0xff; + } + bitp = endofline; + } + } else { + for (h=0; hbytes_per_line; + for (w=width; w>0; w--) { + temp = (int) *datap++; + temp = ((img_info->reds[temp]>>rshift)&rmask)| + ((img_info->greens[temp]>>gshift)&gmask)| + ((img_info->blues[temp]>>bshift)&bmask); + *bitp++ = temp&0xff; + *bitp++ = (temp>>8)&0xff; } - else - { - *bitp++ = temp & 0xff; - *bitp++ = (temp >> 8) & 0xff; - } - - datap++; + bitp = endofline; } - - newimage = XCreateImage (dsp, - DefaultVisual (dsp, DefaultScreen (dsp)), - depth, ZPixmap, 0, (char *) bit_data, - width, height, 16, 0); } break; - case 24: - case 32: - bit_data = (unsigned char *) XtMalloc (width * height * 4); - theVisual = DefaultVisual (dsp, DefaultScreen (dsp)); - rshift = highbit (theVisual->red_mask) - 7; - gshift = highbit (theVisual->green_mask) - 7; - bshift = highbit (theVisual->blue_mask) - 7; - bmap_order = BitmapBitOrder (dsp); - - bitp = bit_data; - datap = data; - for (w = (width * height); w > 0; w--) - { - c = - (((img_info->reds[(int) *datap] >> 8) & 0xff) << rshift) | - (((img_info->greens[(int) *datap] >> 8) & 0xff) << gshift) | - (((img_info->blues[(int) *datap] >> 8) & 0xff) << bshift); - - datap++; - - if (bmap_order == MSBFirst) - { - *bitp++ = (unsigned char) ((c >> 24) & 0xff); - *bitp++ = (unsigned char) ((c >> 16) & 0xff); - *bitp++ = (unsigned char) ((c >> 8) & 0xff); - *bitp++ = (unsigned char) (c & 0xff); - } - else - { - *bitp++ = (unsigned char) (c & 0xff); - *bitp++ = (unsigned char) ((c >> 8) & 0xff); - *bitp++ = (unsigned char) ((c >> 16) & 0xff); - *bitp++ = (unsigned char) ((c >> 24) & 0xff); + case 32: + /* bletcherous code ... assumes masks are 8 bits wide. */ + rshift = highbit((unsigned long)theVisual->red_mask)-7; + gshift = highbit((unsigned long)theVisual->green_mask)-7; + bshift = highbit((unsigned long)theVisual->blue_mask)-7; + + datap=data; + bitp=bit_data; + for (h=0; hbytes_per_line; + for (w=width; w>0; w--) { + temp = (int) *datap++; + c = (((img_info->reds[temp]>>8)&0xff)<greens[temp]>>8)&0xff)<blues[temp]>>8)&0xff)<byte_order==MSBFirst) { + *bitp++=(unsigned char)((c>>24)&0xff); + *bitp++=(unsigned char)((c>>16)&0xff); + *bitp++=(unsigned char)((c>>8)&0xff); + *bitp++=(unsigned char)(c&0xff); + } + else { + *bitp++=(unsigned char)(c&0xff); + *bitp++=(unsigned char)((c>>8)&0xff); + *bitp++=(unsigned char)((c>>16)&0xff); + *bitp++=(unsigned char)((c>>24)&0xff); + } } + bitp = endofline; } - - newimage = XCreateImage (dsp, - DefaultVisual (dsp, DefaultScreen (dsp)), - depth, ZPixmap, 0, (char *) bit_data, - width, height, 32, 0); break; + default: - fprintf (stderr, "Don't know how to format image for display of depth %d\n", depth); - return (NULL); +#ifdef VERBOSE + fprintf(stderr, "Don't know how to format image for display of depth %d\n", + bpp); +#endif + XtFree (newimage->data); + newimage->data = (unsigned char *) NULL; + XDestroyImage(newimage); + return(NULL); } - return (newimage); + return(newimage); } @@ -489,15 +460,18 @@ * ExtendEnd for button up events in an anchor, and _HTMLInput only * processes elements that look like anchors; * 2) a standard anchor-style bounding box will be drawn around the delayed - * image icon, so that it's borders are obvious; and + * image icon, so that its borders are obvious; and * 3) the Anchor Display feature will consider the presence of the mouse * cursor in the delayed image area to be worth highlighting. * * Clicking on a delayed image will cause the image to be loaded (see * _HTMLInput() ). + * + * Changed that pseudo-href string to look like a scheme (`protocol') name + * which is less likely to appear in real HRefs. --GN 1997May14 */ -static const char *const delayedhrefstring = "Delayed Image"; +static const char *const delayedhrefstring = "DelayedImage:"; char * DelayedHRef (hw) @@ -516,10 +490,18 @@ strcmp (href, delayedhrefstring) == 0); } - +/* + * two-style function definition avoids conflict in meaning of Boolean on + * some Unices -- Nelson H F Beebe 1997May09 (not really needed here) + */ +#ifdef __STDC__ +ImageInfo * +DelayedImageData (Boolean anchored) +#else ImageInfo * DelayedImageData (anchored) Boolean anchored; +#endif { static Boolean di_inited = False; @@ -863,6 +845,11 @@ { if (tmpimage != NULL) { + if (tmpimage->data != NULL) + { + XtFree((char *)(tmpimage->data)); + tmpimage->data = (unsigned char *) NULL; + } XDestroyImage (tmpimage); } if (Img != (Pixmap) NULL) @@ -875,6 +862,11 @@ { XPutImage (XtDisplay (hw), Img, hw->html.drawGC, tmpimage, 0, 0, 0, 0, img_info->width, img_info->height); + if (tmpimage->data != NULL) + { + XtFree((char *)(tmpimage->data)); + tmpimage->data = (unsigned char *) NULL; + } XDestroyImage (tmpimage); } @@ -971,11 +963,21 @@ * to whatever image we're going to display. * This code does not generate pic_data->image; ImageRefresh() does that. */ + +/* + * two-style function definition avoids conflict in meaning of Boolean on + * some Unices -- Nelson H F Beebe 1997May09 + */ +#ifdef __STDC__ +void +HTMLGetImage (HTMLWidget hw, struct ele_rec *eptr, Boolean now) +#else void HTMLGetImage (hw, eptr, now) HTMLWidget hw; struct ele_rec *eptr; Boolean now; /* True: force loading now */ +#endif { const char *const edata = eptr->edata; ImageInfo *pic_data; @@ -991,9 +993,13 @@ { /* * arg 3: True = don't load if downloading is required + * + * controls arg4 for the resolveImageProc, and arg3 + * passes the appropriate bg color - djhjr - May 12 97 */ pic_data = (* (resolveImageProc) (hw->html.resolveImage) ) - (hw, edata, (hw->html.delay_images && !now)); + (hw, edata, hw->core.background_pixel, + (hw->html.delay_images && !now)); if (pic_data != NULL) /* got a real image */ { @@ -1013,7 +1019,7 @@ } else /* well, *that* was useless */ { - (void) FreeOneImage (pic_data); + (void) FreeOneImage (hw, pic_data); /* --Frang G Liu 1997May09 */ pic_data = NULL; } } @@ -1060,6 +1066,7 @@ FreeIMGInfo (eptr->img_data); /* free any old img_data; NULL okay */ eptr->img_data = (IMGInfo *) XtMalloc (sizeof (IMGInfo)); + eptr->img_data->alt = (const char *) NULL; eptr->img_data->pic_data = pic_data; /* diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTMLlists.c ./libhtmlw/HTMLlists.c --- ../chimera-1.70p0/libhtmlw/HTMLlists.c Sun May 4 00:54:16 1997 +++ ./libhtmlw/HTMLlists.c Thu May 22 13:09:00 1997 @@ -345,18 +345,10 @@ current = current->next; eptr->next = NULL; - if (eptr->edata != NULL) - { - XtFree((char *) eptr->edata); - } - if (eptr->anchorHRef != NULL) - { - XtFree((char *) eptr->anchorHRef); - } - if (eptr->anchorName != NULL) - { - XtFree((char *) eptr->anchorName); - } + XtFree((char *) eptr->edata); /* accepts NULL... */ + XtFree((char *) eptr->anchorHRef); + XtFree((char *) eptr->anchorName); + FreeIMGInfo (eptr->img_data); /* also accepts NULL */ XtFree((char *) eptr); } } @@ -400,9 +392,9 @@ /* - * Contruct and return an array of pointers into the element list that + * Construct and return an array of pointers into the element list that * indexes the elements by line number. - * Note, lines containing only while space will have NULL pointers + * Note, lines containing only white space will have NULL pointers * into the element list. * (FreeLineList and MakeLineList are completely unrelated functionally.) */ diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTMLparse.c ./libhtmlw/HTMLparse.c --- ../chimera-1.70p0/libhtmlw/HTMLparse.c Tue May 6 00:43:08 1997 +++ ./libhtmlw/HTMLparse.c Wed May 21 09:20:01 1997 @@ -1202,6 +1202,11 @@ { type = M_CAPTION; } + /* added this - djhjr - May 9 97 */ + else if (caseless_equal (str, MT_BODY)) + { + type = M_BODY; + } else { #ifdef VERBOSE diff -u --recursive -N ../chimera-1.70p0/libhtmlw/HTMLwidgets.c ./libhtmlw/HTMLwidgets.c --- ../chimera-1.70p0/libhtmlw/HTMLwidgets.c Tue May 6 20:58:02 1997 +++ ./libhtmlw/HTMLwidgets.c Wed May 14 22:12:21 1997 @@ -937,11 +937,12 @@ if (vlist_cnt > 0) { +#ifdef VERBOSE if (vlist_cnt > 1) { fprintf (stderr, "HTML: only a single selection allowed!\n"); } - +#endif for (i = 0; i < list_cnt; i++) { if (!strcasecmp (string_list[i], val_list[0])) @@ -2245,11 +2246,12 @@ if (vlist_cnt > 0) { +#ifdef VERBOSE if (vlist_cnt > 1) { fprintf (stderr, "HTML: only a single selection allowed!\n"); } - +#endif for (i = 0; i < list_cnt; i++) { if (!strcasecmp (string_list[i], val_list[0])) diff -u --recursive -N ../chimera-1.70p0/mxw/AxeStrDefs.h ./mxw/AxeStrDefs.h --- ../chimera-1.70p0/mxw/AxeStrDefs.h Sun Apr 2 04:59:11 1995 +++ ./mxw/AxeStrDefs.h Fri May 9 13:01:43 1997 @@ -16,7 +16,7 @@ #if !defined(XtNcancelCallback) #define XtNcancelCallback "cancelCallback" -#endif XtNcancelCallback +#endif /* XtNcancelCallback */ #define XtNcaretBitmap "caretBitmap" #define XtNchangeCallback "changeCallback" diff -u --recursive -N ../chimera-1.70p0/mxw/Bookmark.c ./mxw/Bookmark.c --- ../chimera-1.70p0/mxw/Bookmark.c Wed May 7 14:48:18 1997 +++ ./mxw/Bookmark.c Wed May 14 22:07:30 1997 @@ -782,7 +782,8 @@ if (fp == NULL) { BREC.blist = CreateBookmarkGroup("default"); - XtAppWarning(BREC.appcon, BREC.cantReadBookmarkFile); + /* Sheesh. GN 1997May10 */ + /* XtAppWarning(BREC.appcon, BREC.cantReadBookmarkFile); */ return; } diff -u --recursive -N ../chimera-1.70p0/mxw/ScrollText.c ./mxw/ScrollText.c --- ../chimera-1.70p0/mxw/ScrollText.c Sat Mar 4 08:55:04 1995 +++ ./mxw/ScrollText.c Wed May 21 18:05:09 1997 @@ -231,7 +231,7 @@ { /* * Positioning with the mouse results in work_proc being corrupted with -p * the result that the test fails and scrolling stops happening. I don't + * the result that the test fails and scrolling stops happening. I don't * understand what is going on. Therefore, for the time being always * register a work proc. It is probably unlikely that events will come * in fast enough anyway for there to be an unexecuted one still around. diff -u --recursive -N ../chimera-1.70p0/options.h.dist ./options.h.dist --- ../chimera-1.70p0/options.h.dist Wed May 7 14:51:06 1997 +++ ./options.h.dist Fri May 9 10:17:49 1997 @@ -7,7 +7,7 @@ */ #define PRINT_COMMAND "lpr -h -P%s" /* command to pipe to print */ -#define USER_AGENT "Chimera/1.70p0" /* User-Agent field for HTTP */ +#define USER_AGENT "Chimera/1.70p1" /* User-Agent field for HTTP */ #define EMAIL_COMMAND "mail %s" /* pipe to command for mail */ #define PATH CUTILDIR /* default program PATH */ /*#define CHILD_STDERR "/dev/null"*/ /* stderr for children diff -u --recursive -N ../chimera-1.70p0/src/Chimera.ad ./src/Chimera.ad --- ../chimera-1.70p0/src/Chimera.ad Wed Apr 30 23:06:55 1997 +++ ./src/Chimera.ad Thu May 22 10:20:36 1997 @@ -1,3 +1,8 @@ +! DON'T uncomment any resource specifications whose values are given in +! parentheses (you may change the values if you know what you're doing). +! The parenthesized stuff is merely a hint where you can find the actual +! default or fallback values in the sources. + ! All of the Proxy resources default to null strings unless set explicitly: !.httpProxy: http://www.somewhere.org:8000/ !.gopherProxy: http://www.somewhere.org:8000/ @@ -26,14 +31,18 @@ !.cacheInfoFiles: (CACHE_INFO_FILES) !.path: (PATH at compile time, not in Common.tmpl) -!Resources which have their fallback values hardwired into src/main.c: +! Resources which have their fallback values hardwired into src/main.c . +! These are the ones you'd be most likely to want to customize. !.showURL: True !.showTitle: True -!.anchorDisplay: False +!.showLiveAnchors: True +!.button1Box: (BUTTON_LIST, see src/main.c) !.button2Box: +! (This is empty by default, but could be used to re-arrange the buttons into +! two rows.) !.openButtonShortcut: True !.printerName: lp -!.keyTrans: defaultTranslations, see src/main.c +!.keyTrans: (defaultTranslations, see src/main.c) !.cacheOff: False !.cacheDir: /tmp !.cacheTTL: 14400 @@ -44,29 +53,40 @@ ! Set the following to empty to always get local directory listings. Set it ! to Welcome.html:welcome.html:index.html to emulate a CERN httpd. !.localIndexFiles: index.html -!.button1Box: BUTTON_LIST, see src/main.c !.statusUpdate: 10 !.inPort: 0 !.languageDB: !.maxColors: 256 !.gammaCorrect: 0 -!Fallbacks for the resources below are in src/fallback.c: +! Fallbacks for the resources below are in src/fallback.c: +*showGrip: False *background: moccasin -*showGrip: false +! Note that these are standard Xt resources, not chimera-defined ones. + +! Same goes for the following which get their defaults from libhtmlw/HTML.c . +! Note *font is overridden below in the Fonts section. +!*borderWidth: 0 +!*foreground: Black +!*font: -adobe-times-medium-r-normal-*-14-*-*-*-*-*-*-* +! And as usual, *geometry doesn't default to anything. +! More stuff from src/fallback.c : *Scrollbar.background: burlywood2 *Command.background: burlywood2 *Toggle.background: burlywood2 *Box.orientation: horizontal *Label.borderWidth: 0 -*Form.resizeable: true +*Form.resizeable: True *Form.borderWidth: 0 -*Viewport*allowHoriz: true -*Viewport*allowVert: true +*Viewport*allowHoriz: True +*Viewport*allowVert: True +! The following might be subject to language customization. (They ought to +! use the languageDB mechanism but don't, for efficiency --?) Also from +! src/fallback.c . *file.label: File *open.label: Open *bookmark.label: Bookmark @@ -80,18 +100,40 @@ *cancel.label: Cancel *deferpix.label: DeferPix +! Some resources from libhtmlw/HTML.h which you might wish to customize. +! Fallbacks are in libhtmlw/HTML.c, and some of them are different from +! the values here. *html.height: 600 *html.width: 600 +! I don't think the width has much to do with reality. The DeferPix button +! has made the HTML view widget wider... and it obliges happily. [GN] *html.horizontalScrollOnTop: True +*html.verticalScrollOnRight: False +! If you run chimera with a nonstd background you may want to change the +! following to match that color: *html.activeAnchorBG: moccasin *html.anchorUnderlines: 1 *html.visitedAnchorUnderlines: 1 -!Setting the following to false may significantly speed up things on slow -!ancient hardware -*html.dashedVisitedAnchorUnderlines: true -*html.autoSize: true +! Setting the following to False may significantly speed up things on slow +! ancient hardware +*html.dashedVisitedAnchorUnderlines: True +!*html.dashedAnchorUnderlines: False +!*html.anchorColor: blue2 +!*html.visitedAnchorColor: purple4 +!*html.activeAnchorFG: Red +!*html.fancySelections: False +!*html.imageBorders: False +!*html.delayedImageBorders: True +*html.useBodyColors: True +*html.delayImageLoads: False *html.htmlErrorMsgCutoff: 0 +*html.truncateALT: 60 +! You might want to change this if you've changed the default layout/geometry +! to produce an unusually wide, or narrow, window. A value of 0 will effec- +! tively disable truncation, anything else less than 7 will be replaced by 7. +! Some more room for language customization in the following. Again from +! src/fallback.c . *Bookmark*title: Bookmarks *Bookmark*Box.hSpace: 10 *Bookmark*markbox.hSpace: 20 @@ -104,7 +146,7 @@ *Bookmark*Viewport.width: 400 *Bookmark*Viewport.borderWidth: 1 *Bookmark*dismiss.label: Dismiss -*Bookmark*List.forceColumns: true +*Bookmark*List.forceColumns: True *Bookmark*List.defaultColumns: 1 *Bookmark*groupform.defaultDistance: 3 *Bookmark*markform.defaultDistance: 3 @@ -150,33 +192,50 @@ *search.title: Enter search *search.strreqMessage: Enter search -*urllabel.label: URL : -*urllabel.left: ChainLeft -*urllabel.right: ChainLeft -*urldisplay.left: ChainLeft -*urldisplay.right: ChainRight -*urldisplay.fromHoriz: urllabel -*urldisplay*sensitive: true -*urldisplay.width: 500 -*urldisplay*editType: edit - -*titlelabel.label: Title : +*titlelabel.label: Status/Title: *titlelabel.left: ChainLeft *titlelabel.right: ChainLeft *titledisplay.left: ChainLeft *titledisplay.right: ChainRight *titledisplay.fromHoriz: titlelabel -*titledisplay*sensitive: false +*titledisplay*sensitive: True *titledisplay.width: 500 *titledisplay*displayCaret: False *titledisplay*editType: read +*urllabel.label: Latest URL : +*urllabel.left: ChainLeft +*urllabel.right: ChainLeft +*urldisplay.left: ChainLeft +*urldisplay.right: ChainRight +*urldisplay.fromHoriz: urllabel +*urldisplay*sensitive: True +*urldisplay.width: 500 +*urldisplay*displayCaret: True +*urldisplay*editType: edit + +*hreflabel.label: ALT / HREF : +*hreflabel.left: ChainLeft +*hreflabel.right: ChainLeft +*hrefdisplay.left: ChainLeft +*hrefdisplay.right: ChainRight +*hrefdisplay.fromHoriz: hreflabel +*hrefdisplay*sensitive: False +*hrefdisplay.width: 500 +*hrefdisplay*displayCaret: False +*hrefdisplay*editType: read + +! Fonts, cf src/fallback.c . These are used in Chimera's decorations outside +! the document view area. *Label.font: -*-lucidatypewriter-medium-r-normal-*-*-120-*-*-*-*-iso8859-1 -*Command.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 -*Toggle.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 -*urldisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 -*titledisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +*Command.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +*Toggle.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +*titledisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +*urldisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +*hrefdisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1 +! More fonts, this time for HTML rendering. Really from libhtmlw/HTML.c +! but with (different) fallbacks in src/fallback.c . *header1Font: -*-helvetica-bold-r-normal-*-*-240-*-*-*-*-iso8859-1 *header2Font: -*-helvetica-bold-r-normal-*-*-180-*-*-*-*-iso8859-1 *header3Font: -*-helvetica-bold-r-normal-*-*-140-*-*-*-*-iso8859-1 @@ -187,3 +246,41 @@ *boldFont: -*-helvetica-bold-r-normal-*-*-120-*-*-*-*-iso8859-1 *italicFont: -*-helvetica-medium-o-normal-*-*-120-*-*-*-*-iso8859-1 *addressFont: -*-helvetica-medium-o-normal-*-*-140-*-*-*-*-iso8859-1 + +! The following are not mentioned in src/fallback.c so they get their default +! values from libhtmlw/HTML.c . Feel free to adjust them to taste. +!*fixedFont: -adobe-courier-medium-r-normal-*-14-*-*-*-*-*-*-* +!*fixedboldFont: -adobe-courier-bold-r-normal-*-14-*-*-*-*-*-*-* +!*fixeditalicFont: -adobe-courier-medium-o-normal-*-14-*-*-*-*-*-*-* +!*addressFont: -adobe-times-medium-i-normal-*-14-*-*-*-*-*-*-* +!*plainFont: -adobe-courier-medium-r-normal-*-14-*-*-*-*-*-*-* +!*plainboldFont: -adobe-courier-bold-r-normal-*-14-*-*-*-*-*-*-* +!*plainitalicFont: -adobe-courier-medium-o-normal-*-14-*-*-*-*-*-*-* +!*listingFont: -adobe-courier-medium-r-normal-*-12-*-*-*-*-*-*-* + +! Private resources from libhtmlw/HTML.h, with fallbacks in libhtmlw/HTML.c . +! Some of these may not even be used by Chimera, others are used for +! storing things in on the fly. +! Don't uncomment any of these unless you know what you're doing, and don't +! be tempted to actually use those cpp-#define'd constants here. They're +! merely listed here to help you find your way through the sources. +!*html.marginWidth: (MARGIN_DEFAULT #define'd as 20 in libhtmlw/HTML.c) +!*html.marginHeight: (MARGIN_DEFAULT) +!*html.text: (NULL) +!*html.headerText: (NULL) +!*html.footerText: (NULL) +!*html.titleText: (NULL) +!*html.isIndex: False +!*html.anchorCallback: (NULL) +!*html.linkCallback: (NULL) +!*html.submitFormCallback: (NULL) +!*html.previouslyVisitedTestFunction: (NULL) +!*html.resolveImageFunction: (NULL) +!*html.percentVerticalSpace: 90 +!*html.pointerMotionCallback: (NULL) +!*html.view: (NULL) +!*html.verticalScrollBar: (NULL) +!*html.horizontalScrollBar: (NULL) +!*html.verticalScrollBarPos: 0 +!*html.horizontalScrollBarPos: 0 +!*html.autoSize: True diff -u --recursive -N ../chimera-1.70p0/src/Imakefile ./src/Imakefile --- ../chimera-1.70p0/src/Imakefile Sat May 3 01:49:18 1997 +++ ./src/Imakefile Sat May 10 21:27:36 1997 @@ -2,8 +2,12 @@ #if NEED_STRSTR > 0 || NEED_GETCWD > 0 || NEED_STRTOL > 0 || NEED_STRCASECMP > 0 COMPATLIB = -L../compat -lxcompat +#ifdef __QNX__ +DEPCOMPAT = ../compat/xcompat3r.lib +#else DEPCOMPAT = ../compat/libxcompat.a #endif +#endif SRCS = main.c url.c net.c ftp.c convert.c gopher.c http.c \ util.c inline.c \ @@ -25,9 +29,15 @@ $(CSOCKSLIB) $(CTERMLIB) $(CEXTRA_LIBS) \ XawClientLibs -lm +#ifdef __QNX__ +LOCAL_DEPLIBS = ../common/common3r.lib ../mxw/mxw3r.lib \ + ../libhtmlw/htmlw3r.lib \ + ../xloadimage/xloadimage3r.lib $(DEPCOMPAT) +#else LOCAL_DEPLIBS = ../common/libcommon.a ../mxw/libmxw.a \ ../libhtmlw/libhtmlw.a \ ../xloadimage/libxloadimage.a $(DEPCOMPAT) +#endif AllTarget(chimera) diff -u --recursive -N ../chimera-1.70p0/src/document.c ./src/document.c --- ../chimera-1.70p0/src/document.c Sat May 3 08:35:13 1997 +++ ./src/document.c Tue May 20 15:24:15 1997 @@ -48,13 +48,13 @@ static struct name protocols[] = { - { "ftp", ftp, "ftp_proxy" }, - { "http", http, "http_proxy" }, - { "gopher", gopherplain, "gopher_proxy" }, - { "gopherp", gopherplus, "gopher_proxy" }, - { "file", file, NULL }, - { "telnet", telnet, NULL }, - { "tn3270", tn3270, NULL }, + { "ftp", &ftp, "ftp_proxy" }, + { "http", &http, "http_proxy" }, + { "gopher", &gopherplain, "gopher_proxy" }, + { "gopherp", &gopherplus, "gopher_proxy" }, + { "file", &file, NULL }, + { "telnet", &telnet, NULL }, + { "tn3270", &tn3270, NULL }, { "wais", NULL, "wais_proxy" }, { "news", NULL, "news_proxy" }, { "nntp", NULL, "nntp_proxy" }, @@ -62,6 +62,7 @@ { NULL, NULL, NULL }, }; +/* #define DEBUG_LOADDOCU */ /* * ReadProtocolFiles * @@ -79,6 +80,10 @@ char *f; char *filename; +#ifdef DEBUG_LOADDOCU + int i; +#endif + f = filelist; while ((filename = mystrtok(f, ':', &f)) != NULL) { @@ -106,7 +111,14 @@ fclose(fp); } - +#ifdef DEBUG_LOADDOCU + fprintf(stderr, "Initial protocols jump table:\n"); + for (i = 0; protocols[i].name != NULL; i++) + { + fprintf(stderr, "For %s use %08lx\n", + protocols[i].name, (long) protocols[i].func); + } +#endif return(plist); } @@ -286,6 +298,10 @@ if (protocols[i].func != NULL && strcasecmp(protocols[i].name, up->protocol) == 0) { +#ifdef DEBUG_LOADDOCU + fprintf(stderr, "Using %s at %08lx\n", + protocols[i].name, (long)protocols[i].func); +#endif d = (protocols[i].func)(up, mtlist); break; } @@ -324,6 +340,8 @@ d->status = DS_OK; + d->view_frag = 1; + d->auth_realm = NULL; d->auth_type = NULL; @@ -523,7 +541,7 @@ /* * ParseMIMEField * - * Picks out the fields that Chimera document's know about for speed. + * Picks out the fields that Chimera documents know about for speed. */ void ParseMIMEField(d, m) diff -u --recursive -N ../chimera-1.70p0/src/document.h ./src/document.h --- ../chimera-1.70p0/src/document.h Wed Mar 29 11:52:16 1995 +++ ./src/document.h Tue May 20 15:23:12 1997 @@ -24,6 +24,8 @@ int from_cache; /* 1 if fetched from the cache */ int cache; /* 1 if the document should be cached */ int status; /* document status */ + int view_frag; /* 1 initially to jump to an , 0 later + to honor remembered scrollbar positions */ char *auth_realm; /* authentication realm */ char *auth_type; /* authentication type */ MIMEField *mflist; /* list of MIME fields for document */ diff -u --recursive -N ../chimera-1.70p0/src/fallback.c ./src/fallback.c --- ../chimera-1.70p0/src/fallback.c Wed Apr 30 23:04:46 1997 +++ ./src/fallback.c Thu May 22 10:08:25 1997 @@ -16,7 +16,7 @@ { /* Resources for everything */ "*background: moccasin", - "*showGrip: false", + "*showGrip: False", /* resources for general widget types */ "*Scrollbar.background: burlywood2", @@ -25,11 +25,11 @@ "*Box.orientation: horizontal", "*Label.borderWidth: 0", - "*Form.resizeable: true", + "*Form.resizeable: True", "*Form.borderWidth: 0", - "*Viewport*allowHoriz: true", - "*Viewport*allowVert: true", + "*Viewport*allowHoriz: True", + "*Viewport*allowVert: True", /* Labels for main window commands */ "*file.label: File", @@ -52,8 +52,8 @@ "*html.activeAnchorBG: moccasin", "*html.anchorUnderlines: 1", "*html.visitedAnchorUnderlines: 1", - "*html.dashedVisitedAnchorUnderlines: true", - "*html.autoSize: true", + "*html.dashedVisitedAnchorUnderlines: True", + "*html.autoSize: True", "*html.htmlErrorMsgCutoff: 0", /* resources for bookmark widgets */ @@ -67,7 +67,7 @@ "*Bookmark*Viewport.width: 400", "*Bookmark*Viewport.borderWidth: 1", "*Bookmark*dismiss.label: Dismiss", - "*Bookmark*List.forceColumns: true", + "*Bookmark*List.forceColumns: True", "*Bookmark*List.defaultColumns: 1", "*Bookmark*groupform.defaultDistance: 3", "*Bookmark*markform.defaultDistance: 3", @@ -114,32 +114,45 @@ "*AuthReq*plabel.label: Password", "*AuthReq*title: Authentication", - "*urllabel.label: URL :", - "*urllabel.left: ChainLeft", - "*urllabel.right: ChainLeft", - "*urldisplay.left: ChainLeft", - "*urldisplay.right: ChainRight", - "*urldisplay.fromHoriz: urllabel", - "*urldisplay*sensitive: true", - "*urldisplay.width: 500", - "*urldisplay*editType: edit", - - "*titlelabel.label: Title :", + "*titlelabel.label: Status/Title:", "*titlelabel.left: ChainLeft", "*titlelabel.right: ChainLeft", "*titledisplay.left: ChainLeft", "*titledisplay.right: ChainRight", "*titledisplay.fromHoriz: titlelabel", - "*titledisplay*sensitive: false", + "*titledisplay*sensitive: True", "*titledisplay.width: 500", "*titledisplay*displayCaret: False", "*titledisplay*editType: read", + "*urllabel.label: Latest URL :", + "*urllabel.left: ChainLeft", + "*urllabel.right: ChainLeft", + "*urldisplay.left: ChainLeft", + "*urldisplay.right: ChainRight", + "*urldisplay.fromHoriz: urllabel", + "*urldisplay*sensitive: True", + "*urldisplay.width: 500", + "*urldisplay*displayCaret: True", + "*urldisplay*editType: edit", + + "*hreflabel.label: ALT / HREF :", + "*hreflabel.left: ChainLeft", + "*hreflabel.right: ChainLeft", + "*hrefdisplay.left: ChainLeft", + "*hrefdisplay.right: ChainRight", + "*hrefdisplay.fromHoriz: hreflabel", + "*hrefdisplay*sensitive: False", + "*hrefdisplay.width: 500", + "*hrefdisplay*displayCaret: False", + "*hrefdisplay*editType: read", + "*Label.font: -*-lucidatypewriter-medium-r-normal-*-*-120-*-*-*-*-iso8859-1", - "*Command.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", - "*Toggle.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", - "*urldisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", - "*titledisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", + "*Command.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", + "*Toggle.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", + "*titledisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", + "*urldisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", + "*hrefdisplay.font: -*-lucida-bold-r-normal-sans-*-120-*-*-*-*-iso8859-1", "*header1Font: -*-helvetica-bold-r-normal-*-*-240-*-*-*-*-iso8859-1", "*header2Font: -*-helvetica-bold-r-normal-*-*-180-*-*-*-*-iso8859-1", diff -u --recursive -N ../chimera-1.70p0/src/ftp.c ./src/ftp.c --- ../chimera-1.70p0/src/ftp.c Fri Apr 18 13:18:36 1997 +++ ./src/ftp.c Wed May 21 12:29:47 1997 @@ -4,6 +4,8 @@ * Copyright (C) 1993, 1994, 1995, John D. Kilburg (john@cs.unlv.edu) * * See copyright.h for details. + * See RFC959 for what we _really_ should be doing (and expecting). + * (The real world is even weirder, though.) --GN */ #include "copyright.h" #include "options.h" @@ -41,7 +43,9 @@ * ftp servers spew (not that it is bad to have nice long * informational messages its just that I hate them from my * programmer's point of view). + * Slightly modified and debugging hooks added --GN 1997May13 */ +/* #define DEBUG_FTP */ static int soak(s, msg, emsg) int s; @@ -57,12 +61,16 @@ if (msg != NULL) { if (WriteBuffer(s, msg, strlen(msg)) == -1) return(999); +#ifdef DEBUG_FTP + fprintf(stderr, "Send %s", msg); +#endif } t = NULL; tlen = 0; btlen = 0; code = -1; + buffer[0] = '\0'; while ((rval = ReadLine(s, buffer, sizeof(buffer))) == 0) { blen = strlen(buffer); @@ -72,9 +80,13 @@ memcpy(t + btlen, buffer, blen); t[tlen] = '\0'; btlen = tlen; - +#ifdef DEBUG_FTP + fprintf(stderr, "Read %s", t); +#endif if (code == -1) code = atoi(buffer); - if (buffer[3] == ' ' && buffer[0] > ' ') break; + if (*buffer && buffer[0] > ' ' && isspace(buffer[3])) + break; + buffer[0] = '\0'; } if (emsg != NULL) @@ -132,7 +144,9 @@ int h0, h1, h2, h3, p0, p1, reply, n; int data_port; int tlen = 0; - int size; + int flen; + int size = 0; + int status; char *hostname; char *content; static char *format = "PASS -%s@%s\r\n"; @@ -141,6 +155,8 @@ static char *format4 = "SIZE %s\r\n"; filename = up->filename; + flen = strlen(filename); + if (flen == 0) return(NULL); /* we want at least the leading slash */ /* * Contact the ftp server on the usualy port. Hardcoding ports is bad. @@ -169,46 +185,53 @@ /* * Send the user name */ - if (soak(s, "USER anonymous\r\n", &emsg) >= 400) + if ((status = soak(s, "USER anonymous\r\n", &emsg)) >= 400) { net_close(s); return(fixup_ftp_message(emsg)); } - free_mem(emsg); - domain = net_gethostname(); - if (domain == NULL) - { - net_close(s); - return(NULL); - } + if (status == 331) { /* remote: user ok, asking for password */ + free_mem(emsg); + domain = net_gethostname(); + if (domain == NULL) + { + net_close(s); + return(NULL); + } - /* - * Send the password - */ - if ((uname = NGetFromStringDB("email")) != NULL - || (uname = getenv("EMAIL")) != NULL) - { - query = alloc_mem(strlen(uname) + 9); - strcpy(query, "PASS -"); - strcat(query, uname); - strcat(query, "\r\n"); - } - else - { - if ((uname = getenv("USER")) == NULL) uname = "nobody"; - query = alloc_mem(strlen(uname) + - strlen(domain) + strlen(format) + 1); - sprintf(query, format, uname, domain); - } + /* + * Send the password + */ + if ((uname = NGetFromStringDB("email")) != NULL + || (uname = getenv("EMAIL")) != NULL) + { + query = alloc_mem(strlen(uname) + 9); + strcpy(query, "PASS -"); + strcat(query, uname); + strcat(query, "\r\n"); + } + else + { + if ((uname = getenv("USER")) == NULL) uname = "nobody"; + query = alloc_mem(strlen(uname) + + strlen(domain) + strlen(format) + 1); + sprintf(query, format, uname, domain); + } - if (soak(s, query, &emsg) >= 400) + if ((status = soak(s, query, &emsg)) >= 400) + { + net_close(s); + return(fixup_ftp_message(emsg)); + } + free_mem(query); + } + if (status != 230) /* are we logged on properly? */ { net_close(s); return(fixup_ftp_message(emsg)); } free_mem(emsg); - free_mem(query); /* * Set binary transfers @@ -228,7 +251,13 @@ return(fixup_ftp_message(emsg)); } - n = sscanf(emsg, "%d %*[^(] (%d,%d,%d,%d,%d,%d)", &reply, &h0, &h1, &h2, &h3, &p0, &p1); + n = sscanf(emsg, "%d %*[^(] (%d,%d,%d,%d,%d,%d)", &reply, + &h0, &h1, &h2, &h3, &p0, &p1); + if (n >= 1 && n < 7 && reply == 227) /* try shorthand format instead */ + { + n = sscanf(emsg, "%d %*[^0-9]%d,%d,%d,%d,%d,%d", &reply, + &h0, &h1, &h2, &h3, &p0, &p1); + } /* noticed by Hallvard B Furuseth, fix by GN 1997May13 */ if (n != 7 || reply != 227) { char *msg = GetFromStringDB("ftpweirdness"); @@ -252,81 +281,94 @@ return(NULL); } - query = alloc_mem(strlen(filename) + strlen(format4) + 1); - sprintf (query, format4, filename); - if (soak(s, query, &emsg) == 999) - { - net_close(s); - net_close(d); - free_mem(query); - return(fixup_ftp_message(emsg)); - } - sscanf(emsg, "%d %d", &reply, &size); - if (reply != 213) size = 0; - free_mem(query); - free_mem(emsg); - /* * Try to retrieve the file + * (But not if we know in advance it's a directory. GN 1997May09) */ - query = alloc_mem(strlen(filename) + strlen(format2) + 1); - sprintf(query, format2, filename); - if ((reply = soak(s, query, &emsg)) == 999) - { - net_close(s); - net_close(d); - free_mem(query); - return(fixup_ftp_message(emsg)); - } - free_mem(query); - free_mem(emsg); - - /* - * If the retrieve fails try to treat the file as a directory. - * If the file is a directory then ask for a listing. - */ - if (reply >= 400) + if (filename[flen - 1] != '/') { /* - * Try to read the file as a directory. + * ask for SIZE first */ - query = alloc_mem(strlen(filename) + strlen(format3) + 1); - sprintf (query, format3, filename); - if (soak(s, query, &emsg) >= 400) + query = alloc_mem(flen + strlen(format4) + 1); + sprintf (query, format4, filename); + if ((status = soak(s, query, &emsg)) == 999) { - net_close(d); net_close(s); + net_close(d); free_mem(query); return(fixup_ftp_message(emsg)); } + sscanf(emsg, "%*d %d", &size); + if (status != 213) size = 0; free_mem(query); free_mem(emsg); - - if (soak(s, "NLST\r\n", &emsg) >= 400) + /* + * If it's actually a directory, or if the filename is syntactically wrong, + * we'd be getting a 550 or 553 here, and don't proceed to RETR. + */ + if (status < 550) { - net_close(s); - net_close(d); - return(fixup_ftp_message(emsg)); + query = alloc_mem(flen + strlen(format2) + 1); + sprintf(query, format2, filename); + if ((reply = soak(s, query, &emsg)) == 999) + { + net_close(s); + net_close(d); + free_mem(query); + return(fixup_ftp_message(emsg)); + } + free_mem(query); + free_mem(emsg); } - free_mem(emsg); + if (status < 550 && reply < 400) + { + /* + * Read file from the FTP host + */ + t = ReadBuffer(d, &tlen, size, size); + if (t == NULL) return(NULL); - t = ftp_dir(d, hostname, (up->port == 0 ? DEFAULT_FTP_PORT:up->port), - filename); - if (t == NULL) return(NULL); - content = "text/html"; - tlen = strlen(t); - } - else - { + content = Ext2Content(mtlist, filename); + if (content == NULL) content = "text/plain"; + + net_close(d); + net_close(s); + + return(BuildDocument(t, tlen, content, 0, 1)); + } /* - * Read file from the FTP host + * If the retrieve fails try to treat the file as a directory. */ - t = ReadBuffer(d, &tlen, size, size); - if (t == NULL) return(NULL); - - content = Ext2Content(mtlist, filename); - if (content == NULL) content = "text/plain"; } + /* + * CWD and ask for a listing. + */ + query = alloc_mem(flen + strlen(format3) + 1); + sprintf (query, format3, filename); + if (soak(s, query, &emsg) >= 400) + { + net_close(d); + net_close(s); + free_mem(query); + return(fixup_ftp_message(emsg)); + } + free_mem(query); + free_mem(emsg); + + if (soak(s, "NLST\r\n", &emsg) >= 400) /* contemplate doing a LIST as well */ + { + net_close(s); + net_close(d); + return(fixup_ftp_message(emsg)); + } + free_mem(emsg); + + t = ftp_dir(d, hostname, (up->port == 0 ? DEFAULT_FTP_PORT:up->port), + filename); + if (t == NULL) return(NULL); + content = "text/html"; + tlen = strlen(t); net_close(d); net_close(s); @@ -334,17 +376,25 @@ return(BuildDocument(t, tlen, content, 0, 1)); } +/* + * ftp_strcmp + * + * Wrapper to match type requirements of qsort + * (changed upon advice by Nelson H F Beebe 1997May09) + */ static int ftp_strcmp(a, b) -char **a, **b; +const void *a, *b; { - return(strcmp(*a, *b)); + return(strcmp(*(const char **) a, *(const char **) b)); } /* * ftp_dir * * Read directory from FTP server, sort, and display. + * (The right thing to do might be to fetch and display 00-index.html + * instead if it exists... --GN) */ static char * ftp_dir(d, hostname, portno, filename) @@ -360,12 +410,18 @@ char buffer[BUFSIZ]; char *cp; char *f; + char *myfilename; int flen; int filelen; int entrylen; int i; char *header = GetFromStringDB("ftpheader"); - static char *entry = "
  • %s \n"; + static char *entry = "
  • %s\n"; + + myfilename = alloc_string(filename); + flen = strlen(filename); /* f, flen will be reused later */ + for (f = myfilename + flen - 1; f >= myfilename && *f == '/'; f--) + *f = '\0'; /* kill trailing slashes --GN 1997May09 */ count = 0; size = 15; @@ -379,9 +435,13 @@ } for (cp = buffer; *cp; cp++) { - if (isspace(*cp)) break; + if (*cp == '\n' || *cp == '\r') break; + /* if (isspace(*cp)) break; */ } *cp = '\0'; +#ifdef DEBUG_FTP + fprintf(stderr, "DirLine %s\n", buffer); +#endif sa[count] = alloc_string(buffer); count += 1; } @@ -389,28 +449,32 @@ if (count == 0) { free_mem((char *)sa); + free_mem(myfilename); return(NULL); } - qsort(sa, count, sizeof(char *), ftp_strcmp); + qsort(sa, count, sizeof(char *), &ftp_strcmp); - filelen = strlen(filename) + strlen(hostname) + 10; + filelen = strlen(myfilename) + strlen(hostname) + 10; entrylen = strlen(entry); flen = strlen(header) + 2 * filelen + 1; f = (char *)alloc_mem(flen); - sprintf (f, header, filename, hostname, filename); - - if (filename[0] != '\0' && filename[1] == '\0') filename = ""; + sprintf (f, header, myfilename, hostname, myfilename); + /* + if (myfilename[0] != '\0' && myfilename[1] == '\0') myfilename = ""; + * should no longer be necessary --GN 1997May09 + */ for (i = 0; i < count; i++) { flen += 2 * strlen(sa[i]) + filelen + entrylen; f = (char *)realloc_mem(f, flen); - sprintf(f + strlen(f), entry, hostname, portno, filename, sa[i], sa[i]); + sprintf(f + strlen(f), entry, hostname, portno, myfilename, sa[i], sa[i]); free_mem(sa[i]); } free_mem((char *)sa); + free_mem(myfilename); return(f); } diff -u --recursive -N ../chimera-1.70p0/src/gopher.c ./src/gopher.c --- ../chimera-1.70p0/src/gopher.c Fri Apr 18 13:18:36 1997 +++ ./src/gopher.c Tue May 13 19:25:29 1997 @@ -333,7 +333,9 @@ { case '8': /* telnet. */ case 'T': /* TN3270 */ +#ifdef VERBOSE fprintf (stderr, "Gopher telnet bug.\n"); +#endif free_mem(filename); return(NULL); break; diff -u --recursive -N ../chimera-1.70p0/src/http.c ./src/http.c --- ../chimera-1.70p0/src/http.c Sun May 4 21:56:06 1997 +++ ./src/http.c Sun May 11 17:52:58 1997 @@ -560,7 +560,7 @@ query = alloc_mem(strlen(filename) + strlen(format) + strlen(request_data) + - strlen(host_port) + + strlen(host_port) + strlen(extra_header) + strlen(auth_info) + strlen(USER_AGENT) + 1); @@ -568,7 +568,7 @@ format, filename, request_data, - host_port, + host_port, USER_AGENT, extra_header, auth_info); @@ -579,7 +579,7 @@ query = alloc_mem(strlen(filename) + strlen(format) + strlen(request_data) + - strlen(host_port) + + strlen(host_port) + strlen(data_type) + strlen(extra_header) + strlen(auth_info) + @@ -587,7 +587,7 @@ sprintf (query, format, filename, - host_port, + host_port, USER_AGENT, strlen(request_data), data_type, @@ -604,14 +604,14 @@ format = crlf == 1 ? format_get_crlf:format_get; query = alloc_mem(strlen(filename) + strlen(format) + - strlen(host_port) + + strlen(host_port) + strlen(extra_header) + strlen(auth_info) + strlen(USER_AGENT) + 1); sprintf (query, format, filename, - host_port, + host_port, USER_AGENT, extra_header, auth_info); diff -u --recursive -N ../chimera-1.70p0/src/input.c ./src/input.c --- ../chimera-1.70p0/src/input.c Fri May 2 18:01:17 1997 +++ ./src/input.c Tue May 20 10:56:09 1997 @@ -29,8 +29,11 @@ #include #include -#ifndef sco -#if defined(SYSV) || defined(SVR4) +/* QNX support added by Frank G Liu 1997May09 */ +/* HP-UX support by Nelson H F Beebe 1997May09 */ + +#if !defined(sco) && !defined(__hpux) +#if defined(SYSV) || defined(SVR4) || defined(__QNX__) #include #endif #endif @@ -47,6 +50,52 @@ int response_bytecnt = 0; /* used by back-to-back ReadLine calls */ +#define C_SEL_READ 5001 +#define C_SEL_WRITE 5002 +/* + * c_select + * return values: + * -1 system error, errno has been set + * 0 timeout, file descriptor not ready for I/O + * 1 file descriptor ready for use + */ +int c_select(d,rw) +int d; +int rw; +{ + int r; + extern int errno; + struct timeval to; + fd_set rwfds, exceptfds; + + FD_ZERO(&rwfds); FD_SET(d, &rwfds); + FD_ZERO(&exceptfds); FD_SET(d, &exceptfds); + to.tv_sec = NET_WAIT_TO_SECS; + to.tv_usec = NET_WAIT_TO_USECS; + + if (rw == C_SEL_READ) + { + r = select(d+1, &rwfds, (fd_set *)0, &exceptfds, &to); + } + else if (rw == C_SEL_WRITE) + { + r = select(d+1, (fd_set *)0, &rwfds, &exceptfds, &to); + } + else + { +#ifdef VERBOSE + fprintf(stderr,"internal error\n"); +#endif + r = 0; + } +#if 0 /* Old code checked, but I don't know any OS buggy enough to need it */ + if (r>0 && !FD_ISSET(d,&rwfds) && !FD_ISSET(d,&exceptfds)) r = 0; +#endif + /* We're not picky, treat EINTR the same as a timeout */ + if (r<0 && errno==EINTR) r=0; + return r; +} + /* * WaitForConnect */ @@ -55,22 +104,12 @@ int d; { int rval; - fd_set writefds; - struct timeval to; - extern int errno; while (1) { - FD_ZERO(&writefds); - FD_SET(d, &writefds); - to.tv_sec = NET_WAIT_TO_SECS; - to.tv_usec = NET_WAIT_TO_USECS; - - if ((rval = select(d + 1, (fd_set *)0, &writefds, (fd_set *)0, &to)) > 0) - { - if (FD_ISSET(d, &writefds)) break; - } - else if (rval < 0 && errno != EINTR) return(-1); + rval = c_select (d, C_SEL_WRITE); + if (rval > 0) break; + else if (rval < 0) return(-1); /* following says "Connecting..."--GN */ if (DisplayConnectStatus(1, NULL) == 1) return(-1); } @@ -90,8 +129,6 @@ { int rval; int writelen; - fd_set writefds; - struct timeval to; int i; extern int errno; @@ -99,23 +136,18 @@ for (i = 0; i < bufferlen; i += writelen) { - FD_ZERO(&writefds); - FD_SET(d, &writefds); - to.tv_sec = NET_WAIT_TO_SECS; - to.tv_usec = NET_WAIT_TO_USECS; - - if ((rval = select(d + 1, (fd_set *)0, &writefds, (fd_set *)0, &to)) > 0) - { - if (FD_ISSET(d, &writefds)) + rval = c_select (d, C_SEL_WRITE); + if (rval > 0) + { + writelen = write (d, buffer + i, bufferlen - i); + if (writelen < 0) { - writelen = write(d, buffer + i, bufferlen - i); - if (writelen < 0) - { - if (errno != EAGAIN) break; - } + if (errno != EAGAIN) return(-1); + writelen=0; } } - else if (rval < 0 && errno != EINTR) return(-1); + else if (rval < 0) return(-1); + else writelen = 0; /* and this says "Connected, sending req..." */ if (DisplayConnectStatus(3, NULL) == 1) return(-1); } @@ -137,8 +169,6 @@ char *buffer; int bufferlen; { - fd_set readfds; - struct timeval to; int i = 0; int rval; extern int errno; @@ -153,33 +183,27 @@ return(0); } - FD_ZERO(&readfds); - FD_SET(d, &readfds); - to.tv_sec = NET_WAIT_TO_SECS; - to.tv_usec = NET_WAIT_TO_USECS; - - if ((rval = select(d + 1, &readfds, (fd_set *)0, (fd_set *)0, &to)) > 0) - { - if (FD_ISSET(d, &readfds)) + rval = c_select (d, C_SEL_READ); + if (rval > 0) + { + rval = read(d, buffer + i, 1); + if (rval == -1 && errno == EINTR) continue; + if (rval == -1) return(-1); + else if (rval > 0) { - rval = read(d, buffer + i, 1); - if (rval == -1) return(-1); - else if (rval > 0) + if (buffer[i] == '\n') { - if (buffer[i] == '\n') - { - buffer[i + 1] = '\0'; - if (DisplayTransferStatus(response_bytecnt, -1, 1) == 1) - return(-1); - return(0); - } + buffer[i + 1] = '\0'; + if (DisplayTransferStatus(response_bytecnt, -1, 1) == 1) + return(-1); + return(0); } - else return(-1); - i++; - response_bytecnt++; } + else return(-1); + i++; + response_bytecnt++; } - else if (rval < 0 && errno != EINTR) break; + else if (rval < 0) break; /* always say "Reading response...": --GN */ if (DisplayTransferStatus(response_bytecnt, -1, 0) == 1) break; } @@ -218,33 +242,25 @@ char *t = NULL; int rval; int readlen; - fd_set readfds; - struct timeval to; for (readlen = max; max == 0 || readlen > 0; readlen -= blen) { - FD_ZERO(&readfds); - FD_SET(d, &readfds); - to.tv_sec = NET_WAIT_TO_SECS; - to.tv_usec = NET_WAIT_TO_USECS; blen = 0; - if ((rval = select(d + 1, &readfds, (fd_set *)0, (fd_set *)0, &to)) > 0) + rval = c_select (d, C_SEL_READ); + if (rval > 0) { - if (FD_ISSET(d, &readfds)) - { - barp = (readlen > sizeof(buffer) || max == 0 - ? sizeof(buffer):readlen); - blen = read(d, buffer, barp); - if (blen <= 0) break; - tlen += blen; - if (t) t = (char *)realloc_mem(t, tlen + 1); - else t = (char *)alloc_mem(tlen + 1); - memcpy(t + btlen, buffer, blen); - btlen = tlen; - } + barp = (readlen > sizeof(buffer) || max == 0 + ? sizeof(buffer):readlen); + blen = read(d, buffer, barp); + if (blen <= 0) break; + tlen += blen; + if (t) t = (char *)realloc_mem(t, tlen + 1); + else t = (char *)alloc_mem(tlen + 1); + memcpy(t + btlen, buffer, blen); + btlen = tlen; } - else if (rval < 0 && errno != EINTR) + else if (rval < 0) { if (t != NULL) free_mem(t); return(NULL); diff -u --recursive -N ../chimera-1.70p0/src/local.c ./src/local.c --- ../chimera-1.70p0/src/local.c Tue May 6 00:50:38 1997 +++ ./src/local.c Sun May 18 20:12:13 1997 @@ -149,11 +149,17 @@ return(d); } +/* + * local_strcmp + * + * Wrapper to match type requirements of qsort + * (changed upon advice by Nelson H F Beebe 1997May09) + */ static int local_strcmp(a, b) -char **a, **b; +const void *a, *b; { - return(strcmp(*a, *b)); + return(strcmp(*(const char **)a, *(const char **)b)); } /* @@ -176,8 +182,8 @@ int count, size; int i; char *f; - static char *format = "
  • %s \n"; - static char *rformat = "
  • %s \n"; + static char *format = "
  • %s\n"; + static char *rformat = "
  • %s\n"; char *header = GetFromStringDB("localheader"); char *useformat = (filename[strlen(filename) - 1] == '/')? rformat: format; char *useshtfmt = (filename[strlen(filename) - 1] == '/')? "%s%s": "%s/%s"; @@ -244,7 +250,7 @@ return(d); } - qsort(sa, count, sizeof(char *), local_strcmp); + qsort(sa, count, sizeof(char *), &local_strcmp); filelen = strlen(filename); formlen = strlen(useformat); @@ -272,6 +278,8 @@ * is not localhost). * [One might try an rcp as an intermediate approach, using the username * supplied with the hostname if present... GN 1997May06, just musing] + * Empty (or NULL) hostnames should be treated as equivalent to localhost. + * GN 1997May18 */ Document * file(up, mtlist) @@ -284,7 +292,8 @@ Document *d; char *hostname; - hostname = up->hostname != NULL ? up->hostname:"localhost"; + hostname = ((up->hostname != NULL && up->hostname[0] != '\0') ? + up->hostname : "localhost"); if (strcasecmp(hostname, "localhost") != 0) { domain = net_gethostname(); /* gets the full domain name */ diff -u --recursive -N ../chimera-1.70p0/src/main.c ./src/main.c --- ../chimera-1.70p0/src/main.c Wed May 7 14:48:18 1997 +++ ./src/main.c Thu May 22 13:10:34 1997 @@ -125,8 +125,8 @@ offset(showURL), XtRImmediate, (XtPointer)True }, { "showTitle", XtCBoolean, XtRBoolean, sizeof(Boolean), offset(showTitle), XtRImmediate, (XtPointer)True }, - { "anchorDisplay", XtCBoolean, XtRBoolean, sizeof(Boolean), - offset(anchorDisplay), XtRImmediate, (XtPointer)False }, + { "showLiveAnchors", XtCBoolean, XtRBoolean, sizeof(Boolean), + offset(showLiveAnchors), XtRImmediate, (XtPointer)True }, { "button1Box", "BoxList", XtRString, sizeof(char *), offset(button1Box), XtRString, (XtPointer)BUTTON_LIST }, { "button2Box", "BoxList", XtRString, sizeof(char *), @@ -223,7 +223,6 @@ int argc; char **argv; { - Arg args[2]; char *first; Document *d; URLParts *up, *tup; @@ -231,7 +230,7 @@ char *msg; XtPointer inputmask; int netfd; - Colormap cmap; + /* Colormap cmap; /* removed this - djhjr - May 12 97 */ char *base_url; char path[MAXPATHLEN + 1]; char *cwd; @@ -307,10 +306,7 @@ XSetWMProtocols (XtDisplay(root.toplevel), XtWindow(root.toplevel), &delete, 1); - XtSetArg(args[0], XtNbackground, &root.bgcolor.pixel); - XtSetArg(args[1], XtNcolormap, &cmap); - XtGetValues(root.w, args, 2); - XQueryColor(XtDisplay(root.w), cmap, &root.bgcolor); + /* bgcolor now set by libhtmlw's initialization - djhjr - May 12 97 */ /* * Initialize AppResources @@ -380,6 +376,7 @@ if (default_url == NULL) { + /* panicking */ fprintf (stderr, GetFromStringDB("crash")); exit(1); } @@ -546,6 +543,12 @@ if (up == NULL) url = ""; else t = url = MakeURL(up, 1); + /* + * Wanna hear something weird? I'm getting segfaults without the following + * line. Possibly this exercises some optimization bug in gcc. The SIGSEGV + * arrives in the call chain underneath XtVaSetValues. --GN 1997May21 + */ + if (0) fprintf(stderr, "%s\n", url); XtVaSetValues(root.urldisplay, XtNstring, url, NULL); if (t != NULL) free_mem(t); @@ -556,6 +559,44 @@ } /* + * LiveAnchorCallback + * + * Called (from TrackMotion in libhtmlw/HTML.c) + * when the mouse moves over an anchor + * rwmcm / GN 1997May12, May15 + */ +void +LiveAnchorCallback(w, c) +Widget w; /* not used */ +char *c; +{ + char *href, *t; + int len; + + if (c != (char *) NULL && (len = strlen(c)) > 0) + { + href = alloc_mem(len + 1); + for(t = href; *c; *c++) + { + if ((*c != '\r') && (*c != '\f')) + { + if ((*c == '\t') || (*c == '\n')) + *t++ = ' '; + else + *t++ = *c; + } + } + *t = '\0'; + XtVaSetValues(root.anchordisplay, XtNstring, href, NULL); + if (href != NULL) free_mem(href); + } + else + XtVaSetValues(root.anchordisplay, XtNstring, "", NULL); + + XFlush(XtDisplay(root.w)); +} + +/* * DisplayCurrent * * Displays the current HTML screen. It also changes the title display @@ -629,12 +670,13 @@ HTMLSetText(root.w, d->text, NULL, NULL); } - if (d->up != NULL && d->up->anchor != NULL) + if (d->view_frag && d->up != NULL && d->up->anchor != NULL) { int id; id = HTMLAnchorToId(root.w, d->up->anchor); if (id > 0) HTMLGotoId(root.w, id); + d->view_frag = 0; /* use remembered scrollbar pos'n henceforth */ } root.cancelop = False; @@ -667,6 +709,9 @@ /* * LoadDoc + * + * Always pass up through MakeURLParts to ensure some degree of sanity + * --GN 1997May18 */ static Document * LoadDoc(up, reload, localonly) @@ -675,7 +720,7 @@ int localonly; /* boolean; in cache or on localhost */ { Document *d; - URLParts *tup = NULL, *nup = NULL; + URLParts *nup = NULL; static char *download = NULL; /* as in DisplayTransferStatus --GN */ if (root.dlist != NULL && reload == 0) @@ -687,18 +732,18 @@ kup = ParseURL(root.dlist->base); if (kup != NULL) { - tup = nup = MakeURLParts(up, kup); + nup = MakeURLParts(up, kup); DestroyURLParts(kup); } - else nup = up; + else nup = MakeURLParts(up, (URLParts *) NULL); } else if (root.dlist->up != NULL) { - tup = nup = MakeURLParts(up, root.dlist->up); + nup = MakeURLParts(up, root.dlist->up); } - else nup = up; + else nup = MakeURLParts(up, (URLParts *) NULL); } - else nup = up; + else nup = MakeURLParts(up, (URLParts *) NULL); d = (root.cacheOff || reload) ? NULL : ReadCache (nup); @@ -718,18 +763,57 @@ { if (!localonly) { - XDefineCursor(XtDisplay(root.toplevel), XtWindow(root.toplevel), - root.watch); + /* + * Prepare for a potentially lengthy document load. While we're busy + * with this, the event loop is (not yet running or) stalled waiting + * for us to return from a callback. So we'll be polling the Cancel + * button (this is actually done from within the DisplayConnectStatus + * and DisplayTransferStatus routines below, and these will be exercised + * regularly at short intervals _except_ during a blocking connect. + * Sorry, nothing we can do about that latter case). -- Modified by + * GN 1997May11 + */ SetURL(nup); if (download == NULL) download = GetFromStringDB("download"); SetTitle(download); + + XDefineCursor(XtDisplay(root.toplevel), XtWindow(root.toplevel), + root.watch); + if (root.cancel != 0) XtSetSensitive(root.cancel, True); + /* This doesn't redraw the button label, but we'll handle this later */ + if (root.home != 0) XtSetSensitive(root.home, False); + if (root.back != 0) XtSetSensitive(root.back, False); + if (root.load != 0) XtSetSensitive(root.load, False); + if (root.source != 0) XtSetSensitive(root.source, False); + if (root.reload != 0) XtSetSensitive(root.reload, False); + if (root.file != 0) XtSetSensitive(root.file, False); + if (root.help != 0) XtSetSensitive(root.help, False); + if (root.bookmark != 0) XtSetSensitive(root.bookmark, False); + if (root.search != 0) XtSetSensitive(root.search, False); + if (root.quit != 0) XtSetSensitive(root.quit, False); + if (root.deferpix != 0) XtSetSensitive(root.deferpix, False); } d = LoadDocument(nup, root.plist, root.mtlist, reload); if (!localonly) { + /* + * Thank goodness it's over, and we can return control to the event + * loop. Restore general conditions accordingly. The Home and Back + * buttons will be re-activated (or not) by DisplayCurrent. + */ + if (root.cancel != 0) XtSetSensitive(root.cancel, True); + if (root.load != 0) XtSetSensitive(root.load, True); + if (root.source != 0) XtSetSensitive(root.source, True); + if (root.reload != 0) XtSetSensitive(root.reload, True); + if (root.file != 0) XtSetSensitive(root.file, True); + if (root.help != 0) XtSetSensitive(root.help, True); + if (root.bookmark != 0) XtSetSensitive(root.bookmark, True); + if (root.search != 0) XtSetSensitive(root.search, True); + if (root.quit != 0) XtSetSensitive(root.quit, True); + if (root.deferpix != 0) XtSetSensitive(root.deferpix, True); XDefineCursor(XtDisplay(root.toplevel), XtWindow(root.toplevel), root.left_ptr); } @@ -737,7 +821,7 @@ if (d == NULL || d->status != DS_ERROR) /* take care --GN */ SetTitle(""); - if (tup != NULL) DestroyURLParts (tup); + DestroyURLParts (nup); return (d); } @@ -750,11 +834,22 @@ Widget w; XtPointer cldata, cbdata; { - DestroyDocument((Document *)cldata); - XtDestroyWidget(w); - SetTitle(NULL); /* restore title */ - SetURL(root.dlist ? root.dlist->up : NULL); /* restore URL */ + /* + * added the following - djhjr - May 13 97, modified by GN 1997May14 + * When this is called, cldata points at a document with + * d->status == DS_NEEDS>AUTH which HandleDoc knew nothing better to + * do with. It might contain some information useful to the user. + * We get here when the user has given up trying to remember the + * proper password. + */ + Document *d = (Document *)cldata; + d->status = DS_OK; + HandleDoc(d, 0); /* this will destroy d */ + XtDestroyWidget(w); + /* SetTitle(NULL); /* restore title */ + /* SetURL(root.dlist ? root.dlist->up : NULL); /* restore URL */ + /* no longer needed -- HandleDoc will look after these */ return; } @@ -762,6 +857,7 @@ * AuthOKCallback * * Called when the user enters username/password in the auth widget + * Marginally streamlined -- GN 1997May11 */ static void AuthOKCallback(w, cldata, cbdata) @@ -770,7 +866,6 @@ { AuthReqReturnStruct *ar = (AuthReqReturnStruct *)cbdata; Document *d = (Document *)cldata; - Document *t; RealmInfo *r; root.rflag = True; @@ -806,12 +901,8 @@ root.rlist = r; } - t = LoadDoc(d->up, 1, 0); - HandleDoc(t, 0); - - DestroyDocument(d); - XtDestroyWidget(w); + HandleDoc(d, 0); /* will destroy d when we're done */ return; } @@ -1042,6 +1133,7 @@ DestroyDocument(d); SetTitle(NULL); /* one of those cases where the Title used to be lost... --GN */ + SetURL(root.dlist ? root.dlist->up : NULL); /* restore URL, too */ return; } } @@ -1129,23 +1221,6 @@ return; } -/* rwmcm */ -/* - * AnchorURLDisplay - * - * Called when the mouse moves over an anchor - */ -void -AnchorURLDisplay(w, c) -Widget w; -char *c; -{ - Arg args[5]; - - XtSetArg(args[0], XtNlabel, c); - XtSetValues(root.anchordisplay,args,1); -} - /* * OpenDocument * @@ -1435,13 +1510,13 @@ root.dlist = root.dlist->next; d = LoadDoc(t->up, 1, 0); - HandleDoc(d, 0); if (t->doc != NULL) DestroyDocument(t->doc); if (t->up != NULL) DestroyURLParts(t->up); if (t->base != NULL) free_mem(t->base); free_mem((char *)t); + HandleDoc(d, 0); root.rflag = False; return; @@ -1459,6 +1534,11 @@ /* * Cancel + * + * Neither does this do anything, nor does it need to. We'll be polling + * Cancel at times when the event loop isn't running coz we haven't yet + * started it or we're in the middle of a lengthy callback.-- In fact, this + * thing should never get called at all. [GN] */ void Cancel(w, cldata, cbdata) @@ -1860,6 +1940,7 @@ { d->up = DupURLParts(root.dlist->doc->up); } + HandleDoc(d, 0); } } @@ -1902,11 +1983,13 @@ * * Called by the HTML widget to turn an image into something the widget * understands. This treats images like documents. + * Background arg added - djhjr - May 12 97 */ ImageInfo * -ImageResolve(w, url, delay) +ImageResolve(w, url, bg, delay) Widget w; char *url; +Pixel bg; int delay; /* boolean; if true, only if in cache or on localhost */ { Document *d, *x; @@ -1919,8 +2002,8 @@ int stype; RealmInfo *r; - if (root.cancelop || url == NULL) - { + if (root.cancelop || url == NULL) /* honor click-ahead cancel */ + { /* (doesn't actually do that though ;) [GN] */ root.cancelop = False; return(NULL); } @@ -1929,16 +2012,57 @@ if (tup == NULL) return(NULL); d = LoadDoc (tup, 0, delay); + /* following needed since LoadDoc may have + * set these insensitive -- GN1997May19 */ + if (root.dlist->next == NULL) + { + if (root.home != 0) XtSetSensitive(root.home, False); + if (root.back != 0) XtSetSensitive(root.back, False); + } + else + { + if (root.home != 0) XtSetSensitive(root.home, True); + if (root.back != 0) XtSetSensitive(root.back, True); + } DestroyURLParts(tup); if (d == NULL) return(NULL); - if (d->status == DS_NEEDS_AUTH && (r = CheckRealm(d)) != NULL) + if (d->status == DS_NEEDS_AUTH) { - x = LoadDoc(d->up, 0, 0); - DestroyDocument(d); - d = x; + if ((r = CheckRealm(d)) != NULL) /* anything useful in the Realm cache? */ + { + x = LoadDoc(d->up, 1, 0); + + if (root.dlist->next == NULL) /* again */ + { + if (root.home != 0) XtSetSensitive(root.home, False); + if (root.back != 0) XtSetSensitive(root.back, False); + } + else + { + if (root.home != 0) XtSetSensitive(root.home, True); + if (root.back != 0) XtSetSensitive(root.back, True); + } + + if (x->status == DS_NEEDS_AUTH) + { /* too bad, didn't work. */ + DestroyDocument(x); + DestroyDocument(d); + return (NULL); /* this isn't the time to pop up an auth box */ + } + else + { + DestroyDocument(d); + d = x; + } + } + else /* nothing found, give up on this one */ + { + DestroyDocument(d); + return (NULL); + } } if (!root.cacheOff) WriteCache(d); @@ -1975,9 +2099,28 @@ stype = MONO_DISPLAY; } - i = CreateImageInfo(root.toplevel, d, root.clist, root.path, - stype, root.maxColors, &root.bgcolor, - (double)root.gamma); + /* added this - djhjr - May 12 97 */ + { + Arg arg[1]; + XColor xcolor; + Colormap cmap; + + xcolor.pixel = bg; + XtSetArg(arg[0], XtNcolormap, &cmap); + XtGetValues(root.w, arg, 1); + +#ifdef DEBUG_BGCOLOR + fprintf (stderr, "Image resolver calling XQueryColor\n"); +#endif + XQueryColor(XtDisplay(root.w), cmap, &xcolor); +#ifdef DEBUG_BGCOLOR + fprintf (stderr, "Returned ok\n"); +#endif + /* changed this - djhjr - May 12 97 */ + i = CreateImageInfo(root.toplevel, d, root.clist, root.path, + stype, root.maxColors, &xcolor, + (double)root.gamma); + } DestroyDocument(d); @@ -2083,8 +2226,8 @@ if ((t = MakeURL(root.dlist->up, 1)) != NULL) { - *display = XtNewString(GetTitle(root.w)); - *url = XtNewString(t); + *display = alloc_string (GetTitle(root.w)); + *url = alloc_string (t); free_mem(t); } } @@ -2105,7 +2248,7 @@ XtVaGetValues(w, XtNcurrentGroup, &g, NULL); if (g != NULL) { - if (root.group != NULL) XtFree(root.group); + if (root.group != NULL) free_mem (root.group); root.group = alloc_string(g); } @@ -2216,7 +2359,10 @@ * the status of a DNS lookup, a socket being connected, or an outbound * request, and to poll the Cancel button. * - * First arg tells us which message to show, second is a hostname or IP + * Also poll the XEvent queue for Expose events. Not for anything else -- + * we sure don't want no re-entrant calls to LoadDoc... --GN 1997May11 + * + * First arg tells us which message to show, second is a hostname and/or IP * address (as a dotted quad string) or NULL. * --GN 1997Apr30 */ @@ -2291,6 +2437,13 @@ root.cancelop = True; return(1); } + else + { /* redraw exposures --GN 1997May11 */ + while (XCheckMaskEvent(XtDisplay(root.toplevel), ExposureMask, &xe)) + { + XtDispatchEvent(&xe); + } + } } return(0); @@ -2302,6 +2455,9 @@ * This is called by the data transfer functions to display the status of * an inbound transfer, and to poll the Cancel button. * + * Also poll the XEvent queue for Expose events. Not for anything else -- + * we sure don't want no re-entrant calls to LoadDoc... --GN 1997May11 + * * When max < 0, we're reading HTTP response headers or Gopher menus or * FTP control channel chats, so we say "Reading response: mumble bytes". * When max == 0, we're reading data but don't know how much to expect, @@ -2367,6 +2523,13 @@ root.cancelop = True; return(1); } + else + { /* redraw exposures --GN 1997May11 */ + while (XCheckMaskEvent(XtDisplay(root.toplevel), ExposureMask, &xe)) + { + XtDispatchEvent(&xe); + } + } } return(0); @@ -2436,6 +2599,7 @@ ErrorHandler(msg) String msg; { + /* panicking */ fprintf (stderr, "Xt Error: %s\n", msg); abort(); Quit(root.quit, &root, NULL); diff -u --recursive -N ../chimera-1.70p0/src/net.c ./src/net.c --- ../chimera-1.70p0/src/net.c Sat May 3 19:09:45 1997 +++ ./src/net.c Sun May 11 10:17:56 1997 @@ -15,7 +15,8 @@ #include #include -#if ((defined(SYSV) || defined(SVR4)) && defined(sun)) +/* HP-UX support by Nelson H F Beebe 1997May09 */ +#if ((defined(SYSV) || defined(SVR4)) && (defined(sun) || defined(__hpux))) #include #endif @@ -50,6 +51,11 @@ # define bzero(dst,len) memset(dst,0,len) # define bcopy(src,dst,len) memcpy(dst,src,len) #endif /*SYSV*/ + +/* QNX support added by Frank G Liu 1997May09 */ +#ifdef __QNX__ +#define FNDELAY O_NONBLOCK +#endif /*QNX*/ #ifdef TERM #include "termnet.h" diff -u --recursive -N ../chimera-1.70p0/src/url.c ./src/url.c --- ../chimera-1.70p0/src/url.c Sat May 3 08:45:54 1997 +++ ./src/url.c Thu May 22 13:11:18 1997 @@ -190,7 +190,7 @@ { /* * max 10 digits for the port #... - * sprintf doesn't let us to specify a maximum field width (GN 97Apr30) + * sprintf doesn't let us specify a maximum field width (GN 97Apr30) */ sprintf (u, "%s:%s%s:%d%s%s%s%s", protocol, delim, hostname, up->port, delim2, filename, delim3, anchor); @@ -260,13 +260,20 @@ /* * MakeURLParts + * + * Changed to have it accept NULL for the context upc, so we can use it + * to canonicalize weird stuff passed via up1 (coming from user's input + * or wherever through ParseURL, which doesn't initialize fields not + * explicitly mentioned in its input). --GN 1997May18 */ URLParts * -MakeURLParts(up1, up2) -URLParts *up1, *up2; +MakeURLParts(up1, upc) +URLParts *up1, *upc; { URLParts *r; char *filename; + int inherit_auth = 1; + URLParts *up2; /* * Special case for URNs. Sucks. @@ -278,6 +285,11 @@ r = CreateURLParts(); + if (upc == (URLParts *) NULL) + up2 = CreateURLParts(); + else + up2 = upc; + /* * Deal with the protocol. If it has a protocol then use it, otherwise * use the parent's protocol. If the parent doesn't have a protocol for @@ -288,32 +300,57 @@ if (up2->protocol != NULL) r->protocol = alloc_string(up2->protocol); else r->protocol = alloc_string("file"); } - else r->protocol = alloc_string(up1->protocol); + else + { + r->protocol = alloc_string(up1->protocol); + /* + * r is used here because up1->protocol can be NULL but r->protocol + * will always have the right thing. + */ + if (up2->protocol == NULL || strcasecmp(r->protocol, up2->protocol) != 0) + inherit_auth = 0; + } /* * Deal with the hostname. If it has a hostname then use it, otherwise * if the protocol used by the parent is the same then use the parent's * hostname. * - * The port goes along with the hostname. + * The port goes along with the hostname. We save a strcasecmp here by + * peeking into inherit_auth [GN]. */ if (up1->hostname == NULL) { - /* - * r is used here because up1->protocol can be NULL but r->protocol - * will always have the right thing. - */ - if (up2->hostname != NULL && up2->protocol != NULL && - strcasecmp(r->protocol, up2->protocol) == 0) + if (up2->hostname != NULL && inherit_auth) { r->hostname = alloc_string(up2->hostname); r->port = up2->port; } + else + { + /* + * This sucks, but we used to get a segfault at the DNS phase when + * asked to open a URL of "http:". Found by Hallvard B. Furuseth + * , fix by GN 1997May10. + * NB It's ok to leave r->port == 0. + * NB Can't use "localhost" here or it will happily put that into + * mailto URLs... GN 1997May18 + */ + r->hostname = alloc_string(""); + inherit_auth = 0; + } } else { r->hostname = alloc_string(up1->hostname); r->port = up1->port; + if (inherit_auth) + { + if (up2->hostname == NULL || strcasecmp(r->hostname, up2->hostname) != 0) + inherit_auth = 0; + else if (r->port != up2->port) + inherit_auth = 0; + } } /* @@ -346,6 +383,10 @@ r->filename[0] = '/'; strcpy(r->filename + 1, up1->filename); } + else if (up2->filename == NULL || up2->filename[0] == '\0') + { + r->filename = alloc_string (up1->filename); + } else { /* @@ -450,15 +491,42 @@ } /* - * Copy misc. fields. + * Copy misc. fields. If the parent URL was sufficiently similar to the + * current one (i.e., up1 sufficiently relative), we might as well try + * to use the parent's auth info if any. This costs just a few extra + * bytes if the new doc isn't auth-protected or turns out to live in a + * different realm, but saves an entire 401 transaction if the auth info + * is in fact correct. --GN 1997May15 */ MYDUP(r->method, up1->method); MYDUP(r->data_type, up1->data_type); - MYDUP(r->auth_type, up1->auth_type); - MYDUP(r->username, up1->username); - MYDUP(r->password, up1->password); + if (inherit_auth && up1->auth_type == NULL && + up1->username == 0 && up1->password == NULL) + { + MYDUP(r->auth_type, up2->auth_type); + MYDUP(r->username, up2->username); + MYDUP(r->password, up2->password); + } + else + { + MYDUP(r->auth_type, up1->auth_type); + MYDUP(r->username, up1->username); + MYDUP(r->password, up1->password); + } MYDUP(r->anchor, up1->anchor); CopyURLAttributes(r, up1); + +#ifdef DEBUG_MAKEUP + { + char *ut; + ut = MakeURL(r, 1); + fprintf(stderr, "Built URL %s\n", ut); + free_mem (ut); + } +#endif + + if (upc == (URLParts *) NULL) + DestroyURLParts(up2); return(r); } diff -u --recursive -N ../chimera-1.70p0/src/util.c ./src/util.c --- ../chimera-1.70p0/src/util.c Wed Apr 30 17:48:13 1997 +++ ./src/util.c Wed May 21 18:02:02 1997 @@ -26,7 +26,12 @@ #endif #include +/* QNX support added by D J Hawkey Jr 1997May16 */ +#ifdef __QNX__ +#include +#else #include +#endif #include #include @@ -132,7 +137,8 @@ static void ReapChild() { -#if defined(WNOHANG) && !defined(SYSV) && !defined(SVR4) +/* QNX support added by D J Hawkey Jr 1997May16 */ +#if defined(WNOHANG) && !defined(SYSV) && !defined(SVR4) && !defined(__QNX__) int pid; #endif extern int errno; @@ -141,8 +147,9 @@ /* * It would probably be better to use the POSIX mechanism here,but I have not * checked into it. This gets us off the ground with SYSV. RSE@GMI + * QNX support added by Frank G Liu 1997May09 */ -#if defined(WNOHANG) && !defined(SYSV) && !defined(SVR4) +#if defined(WNOHANG) && !defined(SYSV) && !defined(SVR4) && !defined(__QNX__) union wait st; do diff -u --recursive -N ../chimera-1.70p0/src/widget.c ./src/widget.c --- ../chimera-1.70p0/src/widget.c Sun May 4 19:39:53 1997 +++ ./src/widget.c Thu May 22 10:14:53 1997 @@ -225,28 +225,40 @@ } /* - * rwmcm: Sixth pane, the URL anchor display + * [rwmcm,GN] `Sixth' (really Fifth) pane, the live anchor display + * External name changed to `hrefdisplay' so 1.70p0 resources won't + * interfere with 1.70p1 ones --GN 1997May22 */ - if (r->anchorDisplay) + if (r->showLiveAnchors) { - XtSetArg(args[0], XtNjustify, XtJustifyLeft); - XtSetArg(args[1], XtNlabel, " "); - XtSetArg(args[2], XtNskipAdjust, True); - r->anchordisplay=XtCreateManagedWidget("anchordisplay", - labelWidgetClass, paned, - args, 3); + form = XtCreateManagedWidget("box6", + formWidgetClass, paned, + NULL, ZERO); + + XtCreateManagedWidget("hreflabel", + labelWidgetClass, form, + NULL, ZERO); + + r->anchordisplay = XtCreateManagedWidget("hrefdisplay", + scrollingTextWidgetClass, form, + NULL, ZERO); + r->anchordisplay = XtNameToWidget(r->anchordisplay, "text"); + } + else + { + r->anchordisplay = 0; } /* - * Fifth pane, the HTML viewing area + * `Fifth' (really Sixth) pane, the HTML viewing area */ r->w = XtCreateManagedWidget("html", htmlWidgetClass, paned, NULL, ZERO); XtAddCallback(r->w, WbNanchorCallback, Anchor, r); - if (r->anchorDisplay) + if (r->showLiveAnchors) { - XtSetArg(args[0], WbNpointerMotionCallback, AnchorURLDisplay); + XtSetArg(args[0], WbNpointerMotionCallback, LiveAnchorCallback); XtSetValues(r->w, args, 1); } diff -u --recursive -N ../chimera-1.70p0/src/widget.h ./src/widget.h --- ../chimera-1.70p0/src/widget.h Fri Apr 18 13:18:38 1997 +++ ./src/widget.h Thu May 22 10:12:47 1997 @@ -50,7 +50,7 @@ char *printerName; /* default printer */ Boolean showURL; /* switch for the display of the current URL */ Boolean showTitle; /* switch for the display of the current title */ - Boolean anchorDisplay; /* display URL of current hyperlink */ + Boolean showLiveAnchors; /* display HREF (and ALT) of current hyperlink */ int statusUpdate; /* frequency of download status update */ int inPort; /* the port that chimera listens on for data */ char *httpProxy; @@ -74,7 +74,7 @@ */ Boolean rflag; /* reload flag */ RealmInfo *rlist; /* list of realm authentication info */ - XColor bgcolor; /* background color */ + /* XColor bgcolor; /* background color - removed by djhjr May 12 97 */ XtAppContext appcon; Widget file; Widget toplevel; @@ -84,16 +84,16 @@ Widget view; Widget help; Widget source; - Widget urldisplay; Widget titledisplay; + Widget urldisplay; + Widget anchordisplay; /* rwmcm */ Widget bookmark; Widget reload; Widget home; Widget search; Widget cancel; Widget quit; - Widget deferpix; /* WBE */ - Widget anchordisplay; /* rwmcm */ + Widget deferpix; /* WBE */ char *savestr; char *loadstr; char *printstr; @@ -122,7 +122,7 @@ void Quit(); void OpenDocument(); void Anchor(); -void AnchorURLDisplay(); +void LiveAnchorCallback(); void Home(); void Back(); void Help(); diff -u --recursive -N ../chimera-1.70p0/util/chimera-frontend.script ./util/chimera-frontend.script --- ../chimera-1.70p0/util/chimera-frontend.script Sat Mar 4 08:55:08 1995 +++ ./util/chimera-frontend.script Fri May 9 17:52:06 1997 @@ -18,4 +18,4 @@ # environment variables or X resources. # -exec /local/infosys/bin/chimera-1.55 "$@" +exec /local/infosys/bin/chimera-1.70 ${1+"$@"} diff -u --recursive -N ../chimera-1.70p0/xloadimage/image.h ./xloadimage/image.h --- ../chimera-1.70p0/xloadimage/image.h Fri Mar 24 11:48:03 1995 +++ ./xloadimage/image.h Thu May 15 11:13:14 1997 @@ -211,9 +211,11 @@ void freeImageData _ArgProto((Image *image)); void newRGBMapData _ArgProto((RGBMap *rgb, unsigned int size)); void freeRGBMapData _ArgProto((RGBMap *rgb)); +#if 0 /* never used --GN 1997May15 */ byte *lcalloc _ArgProto((unsigned int size)); byte *lmalloc _ArgProto((unsigned int size)); void lfree _ArgProto((byte *area)); +#endif #define depthToColors(n) DepthToColorsTable[((n) < 32 ? (n) : 32)] diff -u --recursive -N ../chimera-1.70p0/xloadimage/new.c ./xloadimage/new.c --- ../chimera-1.70p0/xloadimage/new.c Thu Mar 23 07:50:59 1995 +++ ./xloadimage/new.c Tue May 13 19:29:28 1997 @@ -49,8 +49,8 @@ /* 28 */ 268435456, /* 29 */ 536870912, /* 30 */ 1073741824, - /* 31 */ 2147483648, - /* 32 */ 2147483648 /* bigger than unsigned int; this is good enough */ + /* 31 */ 2147483648ul, + /* 32 */ 2147483648ul /* bigger than unsigned int; this is good enough */ }; unsigned long colorsToDepth(ncolors) @@ -69,7 +69,9 @@ char *func; { if (!image) { +#ifdef VERBOSE printf("%s: nil image\n", func); +#endif exit(0); } switch (image->type) { @@ -78,7 +80,9 @@ case ITRUE: break; default: +#ifdef VERBOSE printf("%s: bad destination image\n", func); +#endif exit(0); } } diff -u --recursive -N ../chimera-1.70p0/xloadimage/reduce.c ./xloadimage/reduce.c --- ../chimera-1.70p0/xloadimage/reduce.c Fri Mar 24 11:43:17 1995 +++ ./xloadimage/reduce.c Tue May 13 19:28:36 1997 @@ -416,7 +416,9 @@ case ITRUE: if (image->pixlen != 3) { +#ifdef VERBOSE fprintf(stderr, "reduce: true color image has strange pixel length?\n"); +#endif return(image); } if (verbose) {