*** src/document.c.orig	Thu May 19 15:37:19 1994
--- src/document.c	Thu May 19 15:39:31 1994
***************
*** 70,75 ****
--- 70,76 ----
    d = (Document *)malloc(sizeof(Document));
    if (d)
    {
+     d->title = NULL;
      d->url = NULL;
      d->text = NULL;
      d->otext = NULL;
***************
*** 94,105 ****
--- 95,108 ----
  TransferDocument(dest, src)
  Document *dest, *src;
  {
+   if (dest->title) free(dest->title);
    if (dest->url) free(dest->url);
    if (dest->text) free(dest->text);
    if (dest->content) free(dest->content);
    if (dest->ext) free(dest->ext);
    if (dest->otext) free(dest->otext);
  
+   dest->title = src->title;
    dest->ext = src->ext;
    dest->text = src->text;
    dest->otext = src->otext;
***************
*** 122,127 ****
--- 125,131 ----
  DestroyDocument(d)
  Document *d;
  {
+   if (d->title) free(d->title);
    if (d->text) free(d->text);
    if (d->content) free(d->content);
    if (d->url) free(d->url);
***************
*** 496,501 ****
--- 500,511 ----
        }
      }
    }
+ 
+   if (c != NULL && c->type == DocInternal
+       && strcmp(c->text, "<h1>Info</h1>Transfer cancelled.") == 0)
+   {
+     c = NULL;
+   }
  
    /*
     * If the document is in the cache then increment the reference count
*** src/document.h.orig	Thu May 19 15:37:19 1994
--- src/document.h	Thu May 19 15:37:55 1994
***************
*** 44,49 ****
--- 44,50 ----
    char *text;           /* the stuff in the document */
    char *otext;          /* data processed by a pipe goes here */
    char *url;            /* the address of the document */
+   char *title;		/* the title of the document */
    char *content;        /* content-type might be NULL */
    char *ext;            /* extra garbage like '#' or '?' */
    int len;              /* the len of the data */
*** src/main.c.orig	Thu May 19 15:37:21 1994
--- src/main.c	Thu May 19 15:40:54 1994
***************
*** 109,114 ****
--- 109,115 ----
  static void CancelLister();
  #endif
  
+ static void	      HistoryAction();
  static void           HomeAction();
  static void           BackAction();
  static void           ReloadAction();
***************
*** 135,140 ****
--- 136,142 ----
  
  static char defaultTranslations[] =
  "\
+ <Key>i: history()\n\
  <Key>h: home()\n\
  <Key>u: back()\n\
  <Key>l: reload()\n\
***************
*** 171,177 ****
    { "button1Box", "Button1Box", XtRString, sizeof(char *),
  	offset(button1Box), XtRImmediate, "quit, open, home, back, source, reload, save, help, bookmark, print, search" },
    { "button2Box", "Button2Box", XtRString, sizeof(char *),
! 	offset(button2Box), XtRImmediate, NULL },
    { "printerName", "PrinterName", XtRString, sizeof(char *),
  	offset(printerName), XtRImmediate, PRINTER_NAME },
    { "keyTrans", "KeyTrans", XtRString, sizeof(char *),
--- 173,179 ----
    { "button1Box", "Button1Box", XtRString, sizeof(char *),
  	offset(button1Box), XtRImmediate, "quit, open, home, back, source, reload, save, help, bookmark, print, search" },
    { "button2Box", "Button2Box", XtRString, sizeof(char *),
! 	offset(button2Box), XtRImmediate, "history, cancel" },
    { "printerName", "PrinterName", XtRString, sizeof(char *),
  	offset(printerName), XtRImmediate, PRINTER_NAME },
    { "keyTrans", "KeyTrans", XtRString, sizeof(char *),
***************
*** 191,196 ****
--- 193,199 ----
    "*Label.borderWidth:         0",
  
    /* Labels for main window commands */
+   "*history.lable:             History",
    "*save.label:                Save",
    "*open.label:                Open",
    "*bookmark.label:            Bookmark",
***************
*** 273,278 ****
--- 276,282 ----
  
  static XtActionsRec actionsList[] =
  {
+   { "history",  (XtActionProc) HistoryAction },
    { "home",     (XtActionProc) HomeAction },
    { "back",     (XtActionProc) BackAction },
    { "reload",   (XtActionProc) ReloadAction },
***************
*** 398,405 ****
        if (t == NULL)
        {
  	t = "";
        }
-       
        XtSetArg(args[0], XtNstring, t);
      }
      else
--- 402,411 ----
        if (t == NULL)
        {
  	t = "";
+       } else if (r->dlist->doc->title == NULL)
+       {
+ 	r->dlist->doc->title = alloc_string(t);
        }
        XtSetArg(args[0], XtNstring, t);
      }
      else
***************
*** 454,459 ****
--- 460,474 ----
    Arg args[2];
    Widget view;
  
+ #ifdef XYZ
+   if (r->dlist->next != NULL && r->dlist->next->doc->url == NULL) {
+     DocNode *t = r->dlist->next;
+     r->dlist->next = t->next;
+     ReleaseDocument(t->doc);
+     free(t);
+   }
+ #endif
+ 
    /*
     * Give the new scrollbar position.
     */
***************
*** 644,649 ****
--- 659,665 ----
      SetURL(r, nurl);
      XFlush(XtDisplay(r->w));
      
+     r->cancelop = False;
      d = LoadDocument(nurl);
  
      if (d)
***************
*** 1050,1055 ****
--- 1066,1072 ----
  HTMLRoot *r;
  XtPointer cbdata;
  {
+   r->cancelop = False;
    ReloadDocument(r->dlist->doc);
    DisplayCurrent(r);
  
***************
*** 1389,1394 ****
--- 1406,1447 ----
    Source(root.source, &root, NULL);
    return;
  }
+ /*
+  * History
+  */
+ void
+ History(w, r, cbdata)
+ Widget w;
+ HTMLRoot *r;
+ XtPointer cbdata;
+ {
+   DocNode *d;
+   char *t;
+   int len;
+ 
+   t = alloc_string("<H1>History</H1><UL>\n");
+ 
+   for (d = r->dlist; d != NULL; d = d->next)
+   {
+     if (d->doc->type == DocInternal && d->doc->title && d->doc->url)
+     {
+       len = strlen(t);
+       t = realloc(t, len + strlen(d->doc->url) + strlen(d->doc->title) + 80);
+       sprintf(t + len, "<LI><A HREF=\042%s\042>%s</A>\n",
+ 	      d->doc->url, d->doc->title);
+     }
+   }
+   AddDocNode(r, t, DN_ISHTML);
+   free(t);
+   return;
+ }
+ 
+ static void
+ HistoryAction()
+ {
+   History(root.source, &root, NULL);
+   return;
+ }
  
  /*
   * CancelRequester
***************
*** 1804,1809 ****
--- 1857,1867 ----
      return(NULL);
    }
  
+   if (root.cancelop)
+   {
+     return (NULL);
+   }
+ 
    SetTitle(&root, "Downloading inline image...");
    XFlush(XtDisplay(root.w));
  
***************
*** 1901,1906 ****
--- 1959,1967 ----
      free(d->otext);
      d->otext = (char *)i;
      d->otype = DocImage;
+   } else {
+     ReleaseDocument(d);
+     i = NULL;
    }
  
    SetTitle(&root, NULL);
***************
*** 2244,2249 ****
--- 2305,2353 ----
  }
  
  /*
+  * CheckEventCallbak
+  */
+ 
+ Bool
+ CheckEventCallbak(disp, event)
+ Display *disp;
+ XAnyEvent *event;
+ {
+     return event->type == Expose || event->window == XtWindow(root.cancel);
+ }
+ 
+ /*
+  * PointerMotion
+  */
+ int
+ PointerMotion(w, url)
+ Widget w;
+ char *url;
+ {
+   char *nurl, *context;
+ 
+   if (*url == '\0')
+   {
+     SetURL(&root, root.dlist->doc->url);
+     return 0;
+   }
+ 
+   if (root.dlist->doc->url != NULL)
+   {
+     context = root.dlist->doc->url;
+   }
+   else
+   {
+     context = NULL;
+   }
+ 
+   nurl = MakeURL(url, context, NULL, 0);
+   SetURL(&root, nurl);
+   free(nurl);
+   return 0;
+ }
+ 
+ /*
   * DisplayTransferStatus
   *
   * This is called by the data transfer functions to display the status of
***************
*** 2255,2265 ****
--- 2359,2377 ----
  DisplayTransferStatus(s)
  char *s;
  {
+   XEvent event;
+   int mask;
+ 
    if (root.titledisplay != 0)
    {
      SetTitle(&root, s);
      XFlush(XtDisplay(root.w));
    }
+ 
+   while (XCheckIfEvent(XtDisplay(root.w), &event, CheckEventCallbak, NULL))
+   {
+     XtDispatchEvent(&event);
+   }
  
    if (root.cancelop == True)
    {
*** src/widget.c.orig	Thu May 19 15:37:22 1994
--- src/widget.c	Thu May 19 15:41:33 1994
***************
*** 74,79 ****
--- 74,80 ----
    Widget w;
    void (*cb)();
  } ButtonTable[] = {
+   {"history",   NULL, History},
    {"quit",      NULL, Quit},
    {"open",	NULL, DoRequester},
    {"home",	NULL, Home},
***************
*** 145,150 ****
--- 146,153 ----
        r->search = btp->w;
      else if (!mystrcmp(name, "quit"))
        r->quit = btp->w;
+     else if (!mystrcmp(name, "history"))
+       r->history = btp->w;
  
      /*
       * Skip to the next comma-delimited item in the list
***************
*** 168,174 ****
  HTMLRoot *r;
  {
    Widget paned, box, form;
!   Arg args[3];
    XtCallbackRec cbrec[2];
  
    /*
--- 171,177 ----
  HTMLRoot *r;
  {
    Widget paned, box, form;
!   Arg args[4];
    XtCallbackRec cbrec[2];
  
    /*
***************
*** 246,259 ****
     */
    XtSetArg(args[0], WbNresolveImageFunction, ImageResolve);
    XtSetArg(args[1], WbNpreviouslyVisitedTestFunction, VisitTest);
  
    cbrec[0].callback = SubmitForm;
    cbrec[0].closure = (XtPointer)r;
    cbrec[1].callback = 0;
    cbrec[1].closure = 0;
!   XtSetArg(args[2], WbNsubmitFormCallback, cbrec);
  
!   XtSetValues(r->w, args, 3);
  
    return;
  }
--- 249,263 ----
     */
    XtSetArg(args[0], WbNresolveImageFunction, ImageResolve);
    XtSetArg(args[1], WbNpreviouslyVisitedTestFunction, VisitTest);
+   XtSetArg(args[2], WbNpointerMotionCallback, PointerMotion);
  
    cbrec[0].callback = SubmitForm;
    cbrec[0].closure = (XtPointer)r;
    cbrec[1].callback = 0;
    cbrec[1].closure = 0;
!   XtSetArg(args[3], WbNsubmitFormCallback, cbrec);
  
!   XtSetValues(r->w, args, 4);
  
    return;
  }
*** src/widget.h.orig	Thu May 19 15:37:22 1994
--- src/widget.h	Thu May 19 15:37:56 1994
***************
*** 67,72 ****
--- 67,73 ----
    Widget search;
    Widget cancel;
    Widget quit;
+   Widget history;
    XtTranslations trans;
    Boolean cancelop;
    Bookmark *blist;
***************
*** 102,107 ****
--- 103,109 ----
   * It would be a pain to put args for these guys because I would
   * have to do funky things with the middle argument.
   */
+ void History();
  void Quit();
  void OpenDocument();
  void Save();
***************
*** 117,122 ****
--- 119,125 ----
  void Cancel();
  ImageInfo *ImageResolve();
  int VisitTest();
+ int PointerMotion();
  void SubmitForm();
  
  #if NeedFunctionPrototypes
