diff -urN -x gc w3m-0.2.1/XMakefile w3m-0.2.1-img-1.10/XMakefile
--- w3m-0.2.1/XMakefile	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/XMakefile	Thu Aug  2 00:43:04 2001
@@ -16,7 +16,9 @@
 TARGET=w3m$(EXT)
 BOOKMARKER=w3mbookmark$(EXT)
 HELPER=w3mhelperpanel$(EXT)
-TARGETS=$(TARGET) $(BOOKMARKER) $(HELPER)
+IMGDISPLAY=w3mimgdisplay$(EXT)
+IMGSIZE=w3mimgsize$(EXT)
+TARGETS=$(TARGET) $(BOOKMARKER) $(HELPER) $(IMGTARGET)
 
 INCLUDES=-I.
 
@@ -64,6 +66,20 @@
 $(HELPER): w3mhelperpanel.o $(ALIB) $(GCTARGET)
 	$(CC) $(CFLAGS) -o $(HELPER) w3mhelperpanel.o  $(LIBS)
 
+$(IMGDISPLAY): w3mimgdisplay.o
+	$(CC) $(CFLAGS) `imlib-config --cflags` -o $(IMGDISPLAY) \
+		w3mimgdisplay.o `imlib-config --libs`
+
+$(IMGSIZE): w3mimgsize.o
+	$(CC) $(CFLAGS) `imlib-config --cflags` -o $(IMGSIZE) \
+		w3mimgsize.o `imlib-config --libs`
+
+w3mimgdisplay.o: w3mimgdisplay.c
+	$(CC) $(CFLAGS) `imlib-config --cflags` -c w3mimgdisplay.c
+
+w3mimgsize.o: w3mimgsize.c
+	$(CC) $(CFLAGS) `imlib-config --cflags` -c w3mimgsize.c
+
 gc/gc.a:
 	cd gc; make CC='$(CC)' CFLAGS='$(GCCFLAGS)'
 
@@ -77,7 +93,8 @@
 	$(INSTALL) -m 644 w3mhelp-lynx_en.html $(DESTDIR)$(HELP_DIR)/w3mhelp-lynx_en.html
 	$(INSTALL) -m 644 w3mhelp-lynx_ja.html $(DESTDIR)$(HELP_DIR)/w3mhelp-lynx_ja.html
 	$(INSTALL) -m 644 $(HELP_FILE) $(DESTDIR)$(HELP_DIR)/w3mhelp.html
-	for d in $(BOOKMARKER) $(HELPER); do $(INSTALL) -m 755 $$d $(DESTDIR)$(LIB_DIR)/$$d; done
+	for d in $(BOOKMARKER) $(HELPER) $(IMGTARGET); \
+		do $(INSTALL) -m 755 $$d $(DESTDIR)$(LIB_DIR)/$$d; done
 	(cd scripts; for i in *.cgi; do $(INSTALL2) -m 755 $$i $(DESTDIR)$(LIB_DIR)/$$i; done)
 
 uninstall:
diff -urN -x gc w3m-0.2.1/anchor.c w3m-0.2.1-img-1.10/anchor.c
--- w3m-0.2.1/anchor.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/anchor.c	Thu Aug  2 00:43:04 2001
@@ -418,3 +418,69 @@
     }
     return an;
 }
+
+#ifdef USE_IMAGE
+void
+addMultirowsImg(Buffer *buf, AnchorList *al)
+{
+    int i, j, k, col, ecol, pos;
+    Image *img;
+    Anchor a_img, a_href, a_form, *a;
+    Line *l;
+
+    if (al == NULL || al->nanchor == 0)
+	return;
+    for (i = 0; i < al->nanchor; i++) {
+	a_img = al->anchors[i];
+	img = a_img.image;
+	if (a_img.hseq < 0 || ! img || img->rows <= 1)
+	    continue;
+	for (l = buf->firstLine; l != NULL; l = l->next) {
+	    if (l->linenumber == img->y)
+		break;
+	}
+	if (! l)
+	    continue;
+	a = retrieveAnchor(buf->href, a_img.start.line, a_img.start.pos);
+	if (a)
+	    a_href = *a;
+	else
+	    a_href.url = NULL;
+	a = retrieveAnchor(buf->formitem, a_img.start.line, a_img.start.pos);
+	if (a)
+	    a_form = *a;
+	else
+	    a_form.url = NULL;
+	col = COLPOS(l, a_img.start.pos);
+	ecol = COLPOS(l, a_img.end.pos);
+	for (j = 0; l && j < img->rows; l = l->next, j++) {
+	    if (a_img.start.line == l->linenumber)
+		continue;
+	    pos = columnPos(l, col);
+	    a = registerImg(buf, a_img.url, l->linenumber, pos);
+	    a->hseq = - a_img.hseq;
+	    a->image = img;
+	    a->end.pos = pos + ecol - col;
+	    for (k = pos; k < a->end.pos; k++)
+		l->propBuf[k] |= PE_IMAGE;
+	    if (a_href.url) {
+		a = registerHref(buf, a_href.url, a_href.target,
+			a_href.referer, l->linenumber, pos);
+		a->hseq = a_href.hseq;
+		a->end.pos = pos + ecol - col;
+		for (k = pos; k < a->end.pos; k++)
+		     l->propBuf[k] |= PE_ANCHOR;
+	    }
+	    if (a_form.url) {
+		FormItemList *fi = (FormItemList *) a_form.url;
+		buf->formitem = putAnchor(buf->formitem, a_form.url,
+			a_form.target, &a, NULL, l->linenumber, pos);
+		fi->anchor_num = buf->formitem->nanchor - 1;
+		a->hseq = a_form.hseq;
+		a->end.pos = pos + ecol - col;
+	    }
+	}
+	img->rows = 0;
+    }
+}
+#endif
diff -urN -x gc w3m-0.2.1/backend.c w3m-0.2.1-img-1.10/backend.c
--- w3m-0.2.1/backend.c	Fri Mar 23 10:49:54 2001
+++ w3m-0.2.1-img-1.10/backend.c	Thu Aug  2 00:43:05 2001
@@ -203,7 +203,7 @@
 	    url = p;
     }
     if( url ){
-	request = newFormList( NULL, "post", charset, enctype, target, NULL );
+	request = newFormList( NULL, "post", charset, enctype, target, NULL, NULL );
 	request->body = body;
 	request->boundary = boundary;
 	request->length = ( length > 0 )? length : ( body ? strlen(body) : 0 );
diff -urN -x gc w3m-0.2.1/buffer.c w3m-0.2.1-img-1.10/buffer.c
--- w3m-0.2.1/buffer.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/buffer.c	Thu Aug  2 00:43:06 2001
@@ -79,6 +79,9 @@
     int i;
     Buffer *b;
 
+#ifdef USE_IMAGE
+    deleteImage(buf);
+#endif
     clearBuffer(buf);
     for (i = 0; i < MAX_LB; i++) {
 	b = buf->linkBuffer[i];
@@ -486,7 +489,11 @@
     URLFile f;
     int top, linenum, cursorY, pos, currentColumn;
     AnchorList *formitem;
+    extern int in_check_url;
 
+    if (! buf->need_reshape)
+	return;
+    buf->need_reshape = FALSE;
     init_stream(&f, SCM_LOCAL, NULL);
     examineFile(buf->sourcefile, &f);
     if (f.stream == NULL)
@@ -527,6 +534,7 @@
     buf->pos = pos;
     buf->currentColumn = currentColumn;
     arrangeCursor(buf);
+    in_check_url = TRUE;
     if (buf->check_url & CHK_URL)
 	chkURL();
 #ifdef USE_NNTP
@@ -534,6 +542,7 @@
 	chkNMID();
 #endif
     formResetBuffer(buf, formitem);
+    in_check_url = FALSE;
 }
 
 /* shallow copy */
diff -urN -x gc w3m-0.2.1/config.h w3m-0.2.1-img-1.10/config.h
--- w3m-0.2.1/config.h	Fri Mar 23 11:49:44 2001
+++ w3m-0.2.1-img-1.10/config.h	Wed Aug  1 22:08:48 2001
@@ -62,6 +62,11 @@
 #define ANSI_COLOR
 
 /*
+ * Support inline image
+ */
+#define USE_IMAGE
+
+/*
  * Enable id attribute
  */
 #define ID_EXT
@@ -109,9 +114,10 @@
 MATHLIB=-lm
 GCLIB=gc/gc.a
 GCTARGET=gc/gc.a
+IMGTARGET=$(IMGDISPLAY) $(IMGSIZE)
 RANLIB=ranlib
 MKDIR=mkdir -p
-VERSION=0.2.1
+VERSION=0.2.1-img-1.10
 MODEL=Linux.i686-monster-ja
 #else
 
diff -urN -x gc w3m-0.2.1/configure w3m-0.2.1-img-1.10/configure
--- w3m-0.2.1/configure	Fri Mar 23 11:18:40 2001
+++ w3m-0.2.1-img-1.10/configure	Thu Aug  2 00:43:06 2001
@@ -231,6 +231,30 @@
   fi
 }
 
+find_imlib() {
+  imlib_major=1
+  imlib_minor=9
+  imlib_micro=8
+  imlib_version=$imlib_major.$imlib_minor.$imlib_micro
+  echo "Checking Imlib."
+  if [ "x$IMLIB_CONFIG" = x ]; then
+    IMLIB_CONFIG=imlib-config
+  fi
+  version=`$IMLIB_CONFIG --version`
+  if [ "x$version" = x ]; then
+    echo "You don't have Imlib. Install Imlib (version >= $imlib_version)."
+    exit 1
+  fi
+  major=`echo "$version" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'`
+  minor=`echo "$version" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'`
+  micro=`echo "$version" | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*/\3/'`
+  echo "The version of Imlib is $version."
+  if [ "$major" -ne $imlib_major -o "$minor" -ne $imlib_minor -o "$micro" -lt $imlib_micro ]; then
+    echo "Imlib is too old. Install Imlib (version >= $imlib_version)."
+    exit 1
+  fi
+}
+
 #--------------------------------------------------------------
 if [ -n "$USER" ]; then
 	user=$USER
@@ -435,7 +459,7 @@
   def_use_nntp="#undef USE_NNTP"
 fi
 
-echo "Do you want ANSI color escape sequences supprot?"
+echo "Do you want ANSI color escape sequences support?"
 yesno ansi_color "$ansi_color" n
 echo "ansi_color=$ansi_color" >> config.param
 if [ "$ansi_color" = y ]; then
@@ -444,6 +468,17 @@
   def_ansi_color="#undef ANSI_COLOR"
 fi
 
+echo "Do you want inline image support? (you need Imlib)"
+yesno use_image "$use_image" y
+echo "use_image=$use_image" >> config.param
+if [ "$use_image" = y ]; then
+  def_use_image="#define USE_IMAGE"
+  imgtarget='$(IMGDISPLAY) $(IMGSIZE)'
+else
+  def_use_image="#undef USE_IMAGE"
+  imgtarget=''
+fi
+
 echo ""
 echo "Let's do some configurations. Choose config option among the list."
 echo ""
@@ -1452,7 +1487,9 @@
   echo "You have IPv6 support."
 fi
 
-
+if [ "$use_image" = y ]; then
+  find_imlib
+fi
 
 rm -f _zmachdep$extension _zmachdep.c _zmachdep.o
 echo "------------ Configuration done ------------"
@@ -1551,6 +1588,11 @@
 $def_ansi_color
 
 /*
+ * Support inline image
+ */
+$def_use_image
+
+/*
  * Enable id attribute
  */
 #define ID_EXT
@@ -1598,6 +1640,7 @@
 MATHLIB=$mathlib
 GCLIB=$gclib
 GCTARGET=$gctarget
+IMGTARGET=$imgtarget
 RANLIB=$ranlib_cmd
 MKDIR=$MKDIR
 VERSION=$w3mversion
@@ -1625,6 +1668,9 @@
 #define DEF_EDITOR "$editor"
 #define DEF_MAILER "$mailer"
 #define DEF_EXT_BROWSER "$brz"
+
+#define IMGSIZE "w3mimgsize"
+#define IMGDISPLAY "w3mimgdisplay"
 
 #define LIB_DIR      "$suplibdir"
 #define HELP_DIR     "$helpdir"
diff -urN -x gc w3m-0.2.1/display.c w3m-0.2.1-img-1.10/display.c
--- w3m-0.2.1/display.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/display.c	Thu Aug  2 00:43:06 2001
@@ -139,6 +139,10 @@
 	move(LASTLINE, 0);
 	clrtoeolx();
 	refresh();
+#ifdef USE_IMAGE
+	if (activeImage)
+	    loadImage(IMG_FLAG_STOP);
+#endif
 #ifdef MOUSE
 	if (use_mouse)
 	    mouse_end();
@@ -173,6 +177,9 @@
 	initscr();
 	term_raw();
 	term_noecho();
+#ifdef USE_IMAGE
+	initImage();
+#endif
 #ifdef MOUSE
 	if (use_mouse)
 	    mouse_init();
@@ -197,11 +204,13 @@
 static Linecolor color_mode = 0;
 #endif
 
-#ifdef BUFINFO
 static Buffer *save_current_buf = NULL;
-#endif
 
-static int in_check_url = FALSE;
+int in_check_url = FALSE;
+#ifdef USE_IMAGE
+static int image_touch = 0;
+static Line *redrawLineImage(Buffer * buf, Line * l, int i);
+#endif
 
 void
 displayBuffer(Buffer * buf, int mode)
@@ -219,16 +228,23 @@
 	buf->width = COLS;
     if (buf->height == 0)
 	buf->height = LASTLINE + 1;
-    if (buf->width != INIT_BUFFER_WIDTH && buf->type && !strcmp(buf->type, "text/html")) {
-	in_check_url = TRUE;
+    if ((buf->width != INIT_BUFFER_WIDTH && buf->type &&
+	 !strcmp(buf->type, "text/html")) || buf->need_reshape) {
+	buf->need_reshape = TRUE;
 	reshapeBuffer(buf);
-	in_check_url = FALSE;
     }
     if (mode == B_FORCE_REDRAW ||
 	mode == B_SCROLL ||
+#ifdef USE_IMAGE
+	mode == B_REDRAW_IMAGE ||
+#endif
 	cline != buf->topLine ||
 	ccolumn != buf->currentColumn) {
-	if (mode == B_SCROLL && cline && buf->currentColumn == ccolumn) {
+	if (
+#ifdef USE_IMAGE
+	    ! (activeImage && displayImage) &&
+#endif
+	    mode == B_SCROLL && cline && buf->currentColumn == ccolumn) {
 	    int n = buf->topLine->linenumber - cline->linenumber;
 	    if (n > 0 && n < LASTLINE) {
 		move(LASTLINE, 0);
@@ -240,15 +256,40 @@
 		rscroll(-n);
 	    }
 	    redrawNLine(buf, n);
-	}
-	else
+	} else {
+#ifdef USE_IMAGE
+	    if (activeImage && displayImage &&
+		(mode == B_REDRAW_IMAGE ||
+		 cline != buf->topLine ||
+		 ccolumn != buf->currentColumn)) {
+		if (mode == B_FORCE_REDRAW ||
+		    mode == B_REDRAW_IMAGE ||
+/*
+		    ! Do_not_use_ti_te ||
+*/
+		    cline != buf->topLine ||
+		    ccolumn != buf->currentColumn)
+		    clear();
+		clearImage();
+		loadImage(IMG_FLAG_STOP);
+		image_touch++;
+	    }
+#endif
 	    redrawBuffer(buf);
+	}
 	cline = buf->topLine;
 	ccolumn = buf->currentColumn;
     }
     if (buf->topLine == NULL)
 	buf->topLine = buf->firstLine;
 
+#ifdef USE_IMAGE
+    if (buf->need_reshape) {
+	displayBuffer(buf, B_FORCE_REDRAW);
+	return;
+    }
+#endif
+
 #ifdef MOUSE
     if (use_mouse)
 #if LANG == JA
@@ -312,12 +353,20 @@
     message(msg->ptr, buf->cursorX, buf->cursorY);
     standend();
     refresh();
+#ifdef USE_IMAGE
+    if (activeImage && displayImage) {
+/*
+	loadImage(IMG_FLAG_START);
+*/
+	drawImage();
+    }
+#endif
+    if (buf != save_current_buf) {
 #ifdef BUFINFO
-    if (Currentbuf != save_current_buf) {
 	saveBufferInfo();
-	save_current_buf = Currentbuf;
-    }
+	save_current_buf = buf;
 #endif
+    }
 }
 
 void
@@ -352,6 +401,23 @@
     }
     if (n > 0)
 	clrtobotx();
+
+#ifdef USE_IMAGE
+    if (! (activeImage && displayImage))
+	return;
+    move(buf->cursorY, buf->cursorX);
+    for (i = 0, l = buf->topLine; i < LASTLINE; i++) {
+	if (i >= LASTLINE - n || i < -n)
+	    l0 = redrawLineImage(buf, l, i);
+	else {
+	    l0 = (l) ? l->next : NULL;
+	}
+	if (l0 == NULL && l == NULL)
+	    break;
+	l = l0;
+    }
+    getAllImage(buf);
+#endif
 }
 
 #define addKanji(pc,pr) (addChar((pc)[0],(pr)[0]),addChar((pc)[1],(pr)[1]))
@@ -501,6 +567,72 @@
     return l->next;
 }
 
+#ifdef USE_IMAGE
+Line *
+redrawLineImage(Buffer * buf, Line * l, int i)
+{
+    int j, pos, rcol, ncol;
+    int column = buf->currentColumn;
+    Anchor *a;
+    int x, y, sx, sy, w, h;
+
+    if (l == NULL)
+	return NULL;
+    if (l->width < 0)
+	l->width = COLPOS(l, l->len);
+    if (l->len == 0 || l->width - 1 < column)
+	return l->next;
+    pos = columnPos(l, column);
+    rcol = COLPOS(l, pos);
+    for (j = 0; rcol - column < COLS && pos + j < l->len; j++) {
+	a = retrieveAnchor(buf->img, l->linenumber, pos + j);
+	if (a && a->image && a->image->touch < image_touch) {
+	    Image *image = a->image;
+	    ImageCache *cache;
+
+	    cache = image->cache = getImage(image, baseURL(buf),
+		buf->image_flag);
+	if (cache) {
+	    if ((image->width < 0 && cache->width > 0) ||
+		(image->height < 0 && cache->height > 0)) {
+	        image->width = cache->width;
+		image->height = cache->height;
+		buf->need_reshape = TRUE;
+	    }
+	    x = (int)((rcol - column) * pixel_per_char);
+	    y = (int)(i * pixel_per_line);
+	    sx = (int)((rcol - COLPOS(l, a->start.pos)) * pixel_per_char);
+	    sy = (int)((l->linenumber - image->y) * pixel_per_line);
+	    if (sx == 0 && x + image->xoffset >= 0)
+		x += image->xoffset;
+	    else
+		sx -= image->xoffset;
+	    if (sy == 0 && y + image->yoffset >= 0)
+		y += image->yoffset;
+	    else
+		sy -= image->yoffset;
+	    if (image->width > 0)
+		w = image->width - sx;
+	    else
+		w = (int)(8 * pixel_per_char - sx);
+	    if (image->height > 0)
+		h = image->height - sy;
+	    else
+		h = (int)(pixel_per_line - sy);
+	    if (w > (int)((COLS - rcol + column) * pixel_per_char))
+		w = (int)((COLS - rcol + column) * pixel_per_char);
+	    if (h > (int)(LASTLINE * pixel_per_line - y))
+		h = (int)(LASTLINE * pixel_per_line - y);
+	    addImage(cache, x, y, sx, sy, w, h);
+	    image->touch = image_touch;
+	}
+	}
+	rcol = COLPOS(l, pos + j + 1);
+    }
+    return l->next;
+}
+#endif
+
 int
 redrawLineRegion(Buffer * buf, Line * l, int i, int bpos, int epos)
 {
@@ -792,6 +924,8 @@
 void
 disp_message_nsec(char *s, int redraw_current, int sec, int purge, int mouse)
 {
+    if (QuietMessage)
+	return;
     if (!fmInitialized) {
 	fprintf(stderr, "%s\n", s);
 	return;
diff -urN -x gc w3m-0.2.1/doc/README.img w3m-0.2.1-img-1.10/doc/README.img
--- w3m-0.2.1/doc/README.img	Thu Jan  1 09:00:00 1970
+++ w3m-0.2.1-img-1.10/doc/README.img	Thu Aug  2 00:43:04 2001
@@ -0,0 +1,133 @@
+
+Inline image support of w3m
+                                                              2001/08/01
+                                                              H. Sakamoto
+
+Introduction
+
+  This is the extension patch for w3m to support inline image.
+  The patch for w3m-0.2.1 is available on the following site.
+
+    http://www2u.biglobe.ne.jp/~hsaka/w3m/index.html#img
+                                          patch/w3m-0.2.1-img-1.10.patch
+                                          patch/README.img
+
+Support
+
+  * Display inline image (GIF,PNG,JPEG, etc.) on terminals
+    (xterm,rxvt, etc.) of X11.
+  * Support inline image of <img> tag.
+    Support of attributes "width", "height", and "align".
+  * Direct display of image file which header is "Content-type: image/*"
+  * Support of <map> tag.
+    Support of attributes "shape" and "coords" of <area> tag. 
+  * Support of an attribute "ismap" of <img> tag.
+    "w3m" adds coordinate of the cursor as ?<x>,<y> to url, and sends url.
+  * Support of an attribute "type=image" of <input> tag.
+    "w3m" sends coordinate of the cursor as <name>.x=<x>&<name>.y=<y>.
+  * Asynchronous loading of image files.
+  * Using cache of image file as pixmap.
+
+Key functions
+
+  DISPLAY_IMAGE
+      Restart loading and drawing of image.
+  STOP_IMAGE
+      Stop loading of image.
+
+  These functions are not keybinded as default.
+  Specify the following keymaps in ~/.w3m/keymap.
+      keymap X DISPLAY_IMAGE
+      keymap C-c STOP_IMAGE
+
+Comandline options
+
+  -ppc <pixel>
+      # of pixels per character. The default value is 7.
+      Must fit the width of font of terminal.
+  -ppl <pixel>
+      # of pixels per character. The default value is 14.
+      Must fit the height of font of terminal.
+
+Option panel
+
+  pixel_per_char
+      # of pixels per character. The default value is 7.
+      Must fit the width of font of terminal.
+  pixel_per_line
+      # of pixels per character. The default value is 14.
+      Must fit the height of font of terminal.
+  display_image
+      Display of inline image. The default is ON.
+  auto_image
+      Automatic loading of inline image. The default is ON.
+      If it is OFF, loading starts with a command DISPLAY_IMAGE.
+  ext_image_viewer
+      Use external image viewer, when a command VIEW_IMAGE or
+      view of image file which header is "Content-type: image/*".
+      The default is ON. If it is OFF, the image is directly displaied.
+  image_scale
+      Scale of image (%). The default value is 100(%).
+  imgdisplay
+      External command to display image". The default value is "w3mimgdisplay".
+      See "Setting w3mimgdisplay".
+  imgsize
+      External command to get size of image. The default value is "w3mimgsize".
+
+Required programs
+
+  * w3m-0.2.1
+  * Imlib-1.9.8 (1.9.10 is recommendable)
+
+Install
+
+  tar -xvzf DIST/w3m-0.2.1.tar.gz
+  cd w3m-0.2.1
+  patch -p1 < DIST/w3m-0.2.1-img-1.10.patch
+  configure
+    # Select MENU.
+  make
+    # To make "w3mimgdisplay" and "w3mimgsize", Imlib is required.
+  make install
+    # Must install "w3mimgdisplay" and "w3mimgsize" to $LIB(PREFIX/lib/w3m).
+
+Setting w3mimgdisplay
+
+  "w3mimgdisplay" has the following options. Set options to fit terminal.
+
+  -x <offset_x>
+      The X origin of display of image on terminal. The default value is 2.
+      If the terminal is "xterm", the width of scroll bar is added.
+      If the terminal is "Eterm", it may be better to specify 5.
+  -y <offset_y>
+      The Y origin of display of image on terminal. The default value is 2.
+      If the terminal is "Eterm", it may be better to specify 5.
+  -bg <background>
+      Background color. The default value is white.
+      When the color is specified as #RRGGBB, escape '#'.
+
+  ex.)
+    w3m -o 'imgdisplay=w3mimgdisplay -x 5 -bg "#cccccc"'
+  
+Change log
+
+2001/08/01	w3m-0.2.1-img-1.10
+ * Adjust image position.
+ * Fixed scaling image.
+
+2001/07/31	w3m-0.2.1-img-1.9
+ * Fixed initImgdisplay(). Thanks > David.
+
+2001/07/29	w3m-0.2.1-img-1.8
+ * Fixed "configure".
+
+2001/07/28	w3m-0.2.1-img-1.7
+ * Sorry, w3m-0.2.1-img-1.6 is not complete.
+ * Added "configure" and "Makefile" to the patch.
+
+2001/07/27	w3m-0.2.1-img-1.6
+ * Created doc/README.img.
+
+-------------------------------------------
+Hironori Sakamoto <hsaka@mth.biglobe.ne.jp>
+ http://www2u.biglobe.ne.jp/~hsaka/
diff -urN -x gc w3m-0.2.1/doc-jp/README.img w3m-0.2.1-img-1.10/doc-jp/README.img
--- w3m-0.2.1/doc-jp/README.img	Thu Jan  1 09:00:00 1970
+++ w3m-0.2.1-img-1.10/doc-jp/README.img	Thu Aug  2 00:43:04 2001
@@ -0,0 +1,197 @@
+
+w3m でインライン画像を表示
+                                                              2001/08/01
+                                                              坂本 浩則
+
+はじめに
+
+  w3m でインライン画像を表示する拡張です。以下に置いてあります。
+
+    http://www2u.biglobe.ne.jp/~hsaka/w3m/index-ja.html#img
+                                          patch/w3m-0.2.1-img-1.10.patch
+                                          patch/README.img-ja
+
+機能
+
+  ・X11 上の端末(xterm,kterm,rxvt,...)上に画像(GIF,PNG,JPEG 等)を表示します。
+  ・img タグで指定されたインライン画像を表示できます。
+    width,height 属性に応じて必要な領域を確保してレンダリングします。
+    align 属性に対応しています。
+  ・Content-type: image/* な画像ファイルを直接表示できます。
+  ・map タグに対応しています。
+    area タグの shape, coords 属性を認識し、メニュー表示から選択できます。
+  ・img タグの ismap 属性に対応しています。
+    座標値を ?<x>,<y> として URL に追加して送ります。
+  ・input タグの type=image 属性で指定されたインライン画像を表示できます。
+    座標値を <name>.x=<x>&<name>.y=<y> として送ります。
+  ・非同期に画像を読み込みます。
+  ・画像をキャッシュできます。
+
+キー操作
+
+  DISPLAY_IMAGE
+      画像の読み込み/描画を再開します。
+  STOP_IMAGE
+      画像の読み込みを停止します。
+
+  デフォルトのキーマップはありませんので、~/.w3m/keymap に
+      keymap X DISPLAY_IMAGE
+      keymap C-c STOP_IMAGE
+  の様に記述して使用してください。
+
+コマンドラインオプション
+
+  -ppc <pixel>
+      一文字あたりの幅(pixel 値)を指定します。デフォルトは 8。
+      端末の font の大きさに必ず合わせてください。
+  -ppl <pixel>
+      一行あたりの幅(pixel 値)を指定します。デフォルトは 16。
+      端末の font の大きさに必ず合わせてください。
+
+オプションパネル
+
+  pixel_per_char
+      一文字あたりの幅(pixel 値)を指定します。デフォルトは 8。
+      端末の font の大きさに必ず合わせてください。
+  pixel_per_line
+      一行あたりの幅(pixel 値)を指定します。デフォルトは 16。
+      端末の font の大きさに必ず合わせてください。
+  display_image
+      インライン画像を表示します。デフォルトは ON。
+  auto_image
+      インライン画像を自動で読み込みます。デフォルトは ON。
+      OFF の場合は、コマンド DISPLAY_IMAGE で読み込みを開始します。
+  ext_image_viewer
+      コマンド VIEW_IMAGE('I')の場合や Content-type: image/* である
+      画像ファイルを外部ビューワで表示します。デフォルトは ON。
+      OFF の場合は、インライン画像として直接表示します。
+  image_scale
+      画像のスケールを指定します。デフォルトは 100(%)。
+      小さい font と共に使う場合には値を小さくすると有用。
+  imgdisplay
+      インライン画像を表示するためのコマンド。デフォルトは w3mimgdisplay。
+      下記の "w3mimgdisplay の設定" を参考にしてオプション設定してください。
+  imgsize
+      インライン画像の大きさを得るためのコマンド。デフォルトは w3mimgsize。
+
+必要なもの
+
+  ・w3m-0.2.1
+  ・Imlib-1.9.8 (以上。1.9.10 以上を推奨)
+
+インストール
+
+  tar -xvzf DIST/w3m-0.2.1.tar.gz
+  cd w3m-0.2.1
+  patch -p1 < DIST/w3m-0.2.1-img-1.10.patch
+  configure
+    # MENU は有効にしてください。
+  make
+    # w3mimgdisplay, w3mimgsize を make する時に Imlib が必要です。
+  make install
+    # w3mimgdisplay, w3mimgsize は必ず $LIB(PREFIX/lib/w3m) へ
+    # install してください。
+
+w3mimgdisplay の設定
+
+  w3mimgdisplay は以下のオプションを受け付けますので端末に合わせて
+  オプション設定パネルで(または -o オプションで)設定してください。
+
+  -x <offset_x>
+      端末上に画像を表示する X 方向の原点。デフォルトは 2 ですが、
+      xterm や kterm ではスクロールバーの幅を計算して加えようとします。
+      (正しく出来ないかもしれません。)
+      Eterm では 5 にすべきかもしれません。
+  -y <offset_y>
+      端末上に画像を表示する Y 方向の原点。デフォルトは 2。
+      Eterm では 5 にすべきかもしれません。
+  -bg <background>
+      端末の背景色。デフォルトは black。
+      #RRGGBB で指定する場合は # をエスケープして設定してください。
+
+  例)
+    w3m -o 'imgdisplay=w3mimgdisplay -x 5 -bg "#cccccc"'
+  
+更新記録
+
+2001/08/01	w3m-0.2.1-img-1.10
+ * 画像の位置の微調整。
+ * スケールのバグ修正。
+
+2001/07/31	w3m-0.2.1-img-1.9
+ * initImgdisplay() の修正。Thanks > David.
+
+2001/07/29	w3m-0.2.1-img-1.8
+ * configure の修正。Thanks > 坂根さん。
+
+2001/07/28	w3m-0.2.1-img-1.7
+ * configure, XMakefile が patch に入って無かった。
+ * 画像を表示しない場合の処理をオリジナルに近づけた。
+ * [w3m-dev 02121] に対応。
+
+2001/07/27	w3m-0.2.1-img-1.6
+ * README.img を doc-jp へ移動。doc/README.img を作成。
+ * インライン画像対応部分を USE_IMAGE マクロで分離。
+ * configure でインライン画像対応を選択できる様にした。
+ * configure で Imlib をチェックする様にした。
+
+2001/07/26	w3m-0.2.1-img-1.5
+ * w3mimgdisplay は必要になるまで立ち上げない様にした。
+ * w3mimgdisplay が落ちた時に、w3mimgdisplay を再立ち上げできる様にした。
+ * <img align=middle の場合の計算間違いの修正。
+ * [w3m-dev 02118] に対応。
+ * funcname.tab が間違っていたので修正。
+
+2001/07/25	w3m-0.2.1-img-1.4
+ * w3mimgdisplay を環境変数 WINDOWID を見る様に改良。
+   また、text window の推量部分も改良。
+ * image タグを img タグと同じものとして追加。
+ * [w3m-dev 02090], [w3m-dev 02097] に対応。
+
+2001/07/14	w3m-0.2.1-img-1.3
+ * ext_image_viewer が OFF の場合は画像を直接フレーム表示可能にした。
+ * Option Panel が SEGV するバグの修正。
+
+2001/07/13	w3m-0.2.1-img-1.2
+ * 画像のスケールを指定出来る様にした。
+ * SIGUSR1 のブロックに関する修正。
+
+2001/07/12	w3m-0.2.1-img-1.1
+ * キー入力中以外は SIGUSR1, SIGWINCH をブロックする様にした。
+ * バグ修正。
+
+2001/07/11	w3m-0.2.1-img-1.0
+ * MGL 版の画像読み込みを採用。
+
+2001/07/10	w3m-0.2.1-img-0.5
+ * 描画の高速化。w3mimgdisplay で不要な XSync() を止めた。
+   不要な drawImage() を止めた。
+
+2001/07/08	w3m-0.2.1-img-0.4
+ * w3mimgdisplay での Window の取得や offset_x のデフォルト値の改良。
+ * <img align=middle の場合の計算間違いの修正。
+ * <img align=left|center|right では <div>〜</div> を使う様にしてみた。
+ * w3mimgdisplay では SIGINT を無視する様にした。
+ * w3mimgsize もオプション設定できる様にした。
+
+2001/07/07	w3m-0.2.1-img-0.3
+ * kterm に限らず、X11 上の端末では画像を描画できる様にした。
+
+2001/07/06	w3m-0.2.1-img-0.2
+ * README.img を作成。
+ * kterm-6.2.0-img-0.2.patch を w3m-0.2.1-img-0.2.patch に含める様にした。
+ * コードの整理、安全側への修正
+
+2001/07/04	w3m-0.2.1-img-0.1
+ * バージョン管理開始。
+ * Imlib 対応版。
+
+2001/06/30
+ * XPM 版でほぼ実装完了。
+
+2001/06/19
+ * MGL 版に刺激を受けて img への対応のテストを開始。
+
+-----------------------------------
+坂本 浩則 <hsaka@mth.biglobe.ne.jp>
+ http://www2u.biglobe.ne.jp/~hsaka/
diff -urN -x gc w3m-0.2.1/file.c w3m-0.2.1-img-1.10/file.c
--- w3m-0.2.1/file.c	Fri Mar 23 11:19:54 2001
+++ w3m-0.2.1-img-1.10/file.c	Thu Aug  2 00:43:06 2001
@@ -26,6 +26,12 @@
 #define min(a,b)        ((a) > (b) ? (b) : (a))
 #endif				/* not min */
 
+extern int w3m_dump, w3m_dump_source, w3m_dump_head;
+#ifdef USE_IMAGE
+static int image_flag = 0;
+static char *current_source = NULL;
+#endif
+
 static void gunzip_stream(URLFile * uf);
 static FILE *lessopen_stream(char *path);
 static Buffer *loadcmdout(char *cmd,
@@ -48,6 +54,13 @@
 static struct table *tables[MAX_TABLE];
 static struct table_mode table_mode[MAX_TABLE];
 
+#ifdef USE_IMAGE
+static ParsedURL *cur_baseURL = NULL;
+#ifdef JP_CHARSET
+static char cur_document_code;
+#endif
+#endif
+
 static Str cur_select;
 static Str select_str;
 static int select_is_multiple;
@@ -116,6 +129,9 @@
 static int current_content_length;
 
 static int cur_hseq;
+#ifdef USE_IMAGE
+static int cur_iseq;
+#endif
 
 #define MAX_UL_LEVEL 9
 #ifdef KANJI_SYMBOLS
@@ -176,7 +192,7 @@
 currentLn(Buffer * buf)
 {
     if (buf->currentLine)
-	return buf->currentLine->real_linenumber + 1;
+	return buf->currentLine->linenumber + 1;
     else
 	return 1;
 }
@@ -439,7 +455,6 @@
 #ifdef JP_CHARSET
     char code = DocumentCode, ic;
 #endif
-    extern int w3m_dump_head;
 
     headerlist = newBuf->document_header = newTextList();
     if (uf->scheme == SCM_HTTP
@@ -877,7 +892,6 @@
     unsigned char status = HTST_NORMAL;
     URLOption url_option;
     Str tmp;
-    extern int w3m_dump, w3m_dump_source;
 
     tpath = path;
     prevtrap = NULL;
@@ -900,10 +914,10 @@
          * on an FTP server, or (2) is a local directory name. 
          */
 	extern Str FTPDIRtmp;
-	if (fmInitialized && prevtrap) {
+	if (fmInitialized)
 	    term_raw();
+	if (prevtrap)
 	    signal(SIGINT, prevtrap);
-	}
 	switch (f.scheme) {
 	case SCM_FTPDIR:
 	    if (FTPDIRtmp->length > 0) {
@@ -952,10 +966,9 @@
     /* openURL() succeeded */
     if (SETJMP(AbortLoading) != 0) {
         /* transfer interrupted */
-	if (fmInitialized) {
+	if (fmInitialized)
 	    term_raw();
-	    signal(SIGINT, prevtrap);
-	}
+	signal(SIGINT, prevtrap);
 	if (b)
 	    discardBuffer(b);
 	UFclose(&f);
@@ -968,10 +981,9 @@
 	searchHeader = TRUE;
 	searchHeader_through = FALSE;
     }
-    if (fmInitialized) {
-	prevtrap = signal(SIGINT, KeyAbort);
+    prevtrap = signal(SIGINT, KeyAbort);
+    if (fmInitialized)
 	term_cbreak();
-    }
     if (pu.scheme == SCM_HTTP ||
 #ifdef USE_SSL
 	pu.scheme == SCM_HTTPS ||
@@ -1114,16 +1126,19 @@
 		real_type = "text/plain";
 	    t = real_type;
 	}
-	if (!strncasecmp(t, "application/", 12)) {
+	if (!strncasecmp(t, "application/", 12)
+#ifdef USE_IMAGE
+		&& ! current_source
+#endif
+		) {
 	    char *tmpf = tmpfname(TMPF_DFL, NULL)->ptr;
 	    current_content_length = 0;
 	    if (save2tmp(f, tmpf) < 0)
 		UFclose(&f);
 	    else {
-		if (fmInitialized) {
+		if (fmInitialized)
 		    term_raw();
-		    signal(SIGINT, prevtrap);
-		}
+		signal(SIGINT, prevtrap);
 		doFileMove(tmpf, guess_save_name(pu.file));
 	    }
 	    return NO_BUFFER;
@@ -1166,13 +1181,16 @@
     if (real_type == NULL)
 	real_type = t;
     proc = loadBuffer;
+#ifdef USE_IMAGE
+    cur_baseURL = New(ParsedURL);
+    copyParsedURL(cur_baseURL, &pu);
+#endif
 
     if (do_download) {
 	/* download only */
-	if (fmInitialized) {
+	if (fmInitialized)
 	    term_raw();
-	    signal(SIGINT, prevtrap);
-	}
+	signal(SIGINT, prevtrap);
 	doFileSave(f, guess_save_name(pu.file));
 	UFclose(&f);
 	return NO_BUFFER;
@@ -1189,11 +1207,31 @@
 	    f.compression = CMP_NOCOMPRESS;
 	}
     }
+#ifdef USE_IMAGE
+    if (current_source) {
+	Buffer *b = NULL;
+	if (save2tmp(f, current_source) == 0) {
+	    b = newBuffer(INIT_BUFFER_WIDTH);
+	    b->sourcefile = current_source;
+	    b->real_type = t;
+	}
+	if (fmInitialized)
+	    term_raw();
+	signal(SIGINT, prevtrap);
+	UFclose(&f);
+	return b;
+    }
+#endif
 
     if (!strcasecmp(t, "text/html"))
 	proc = loadHTMLBuffer;
     else if (is_plain_text_type(t))
 	proc = loadBuffer;
+#ifdef USE_IMAGE
+    else if (activeImage && displayImage && ! useExtImageViewer &&
+	     !w3m_dump && !strncasecmp(t, "image/", 6))
+	proc = loadImageBuffer;
+#endif
 #ifdef USE_GOPHER
     else if (!strcasecmp(t, "gopher:directory")) {
 	proc = loadGopherDir;
@@ -1209,17 +1247,15 @@
 		    copyParsedURL(&b->currentURL, &pu);
 	    }
 	    UFclose(&f);
-	    if (fmInitialized) {
+	    if (fmInitialized)
 		term_raw();
-		signal(SIGINT, prevtrap);
-	    }
+	    signal(SIGINT, prevtrap);
 	    return b;
 	}
 	else {
-	    if (fmInitialized) {
+	    if (fmInitialized)
 		term_raw();
-		signal(SIGINT, prevtrap);
-	    }
+	    signal(SIGINT, prevtrap);
 	    if (pu.scheme == SCM_LOCAL) {
 		UFclose(&f);
 		doFileCopy(pu.file, guess_save_name(pu.file));
@@ -1285,10 +1321,9 @@
 	    }
 	}
     }
-    if (fmInitialized) {
+    if (fmInitialized)
 	term_raw();
-	signal(SIGINT, prevtrap);
-    }
+    signal(SIGINT, prevtrap);
     return b;
 }
 
@@ -1430,6 +1465,10 @@
 #ifdef FORMAT_NICE
     obuf->bp.flag &= ~RB_FILL;
 #endif				/* FORMAT_NICE */
+#ifdef USE_IMAGE
+    obuf->bp.top_margin = obuf->top_margin;
+    obuf->bp.bottom_margin = obuf->bottom_margin;
+#endif
 
     if (!obuf->bp.init_flag)
 	return;
@@ -1457,6 +1496,10 @@
     obuf->in_under = obuf->bp.in_under;
     obuf->prev_ctype = obuf->bp.prev_ctype;
     obuf->pos = obuf->bp.pos;
+#ifdef USE_IMAGE
+    obuf->top_margin = obuf->bp.top_margin;
+    obuf->bottom_margin = obuf->bp.bottom_margin;
+#endif
     if (obuf->flag & RB_NOBR)
 	obuf->nobr_level = obuf->bp.nobr_level;
 }
@@ -1593,12 +1636,14 @@
 }
 
 void
-push_render_image(Str str, int width, struct html_feed_environ *h_env)
+push_render_image(Str str, int width, int limit, struct html_feed_environ *h_env)
 {
     struct readbuffer *obuf = h_env->obuf;
     int indent = h_env->envs[h_env->envc].indent;
 
+    push_spaces(obuf, 1, (limit - width) / 2);
     push_str(obuf, width, str, PC_ASCII);
+    push_spaces(obuf, 1, (limit - width + 1) / 2);
     if (width > 0)
 	flushline(h_env, obuf, indent, 0, h_env->limit);
 }
@@ -1760,6 +1805,28 @@
     if (obuf->in_under && !hidden_under)
 	Strcat_charp(line, "</u>");
 
+#ifdef USE_IMAGE
+    if (obuf->top_margin > 0) {
+	int i;
+	struct html_feed_environ h;
+	struct readbuffer o;
+	struct environment e[1];
+  
+	init_henv(&h, &o, e, 1, NULL, width, indent);
+	o.line = Strnew_size(width + 20);
+	o.pos = obuf->pos;
+	o.flag = obuf->flag;
+	o.top_margin = -1;
+	o.bottom_margin = -1;
+	Strcat_charp(o.line, "<pre_int>");
+	for (i = 0; i < o.pos; i++)
+	    Strcat_char(o.line, ' ');
+	Strcat_charp(o.line, "</pre_int>");
+	for (i = 0; i < obuf->top_margin; i++)
+	    flushline(h_env, &o, indent, force, width);
+    }
+#endif
+
     if (force == 1 || obuf->flag & RB_NFLUSHED) {
 	TextLine *lbuf = newTextLine(line, obuf->pos);
 	if (RB_GET_ALIGN(obuf) == RB_CENTER) {
@@ -1870,8 +1937,37 @@
 	    pass = tmp2;
 	}
     }
+
+#ifdef USE_IMAGE
+    if (obuf->bottom_margin > 0) {
+	int i;
+	struct html_feed_environ h;
+	struct readbuffer o;
+	struct environment e[1];
+  
+	init_henv(&h, &o, e, 1, NULL, width, indent);
+	o.line = Strnew_size(width + 20);
+	o.pos = obuf->pos;
+	o.flag = obuf->flag;
+	o.top_margin = -1;
+	o.bottom_margin = -1;
+	Strcat_charp(o.line, "<pre_int>");
+	for (i = 0; i < o.pos; i++)
+	    Strcat_char(o.line, ' ');
+	Strcat_charp(o.line, "</pre_int>");
+	for (i = 0; i < obuf->bottom_margin; i++)
+	    flushline(h_env, &o, indent, force, width);
+    }
+    if (obuf->top_margin < 0 || obuf->bottom_margin < 0)
+	return;
+#endif
+
     obuf->line = Strnew_size(256);
     obuf->pos = 0;
+#ifdef USE_IMAGE
+    obuf->top_margin = 0;
+    obuf->bottom_margin = 0;
+#endif
     obuf->prevchar = ' ';
     obuf->bp.init_flag = 1;
     obuf->flag &= ~RB_NFLUSHED;
@@ -2050,12 +2146,263 @@
 	push_tag(obuf, "<u>", HTML_U);
 }
 
+#ifdef USE_IMAGE
+static Hash_hist *image_hash = NULL;
+static Hash_hist *image_file = NULL;
+static GeneralList *image_list = NULL;
+static ImageCache *image_cache = NULL;
+static pid_t image_pid = 0;
+int image_index = 0;
+
+static MySignalHandler
+SigUsr1(SIGNAL_ARG)
+{
+    loadImage(IMG_FLAG_NEXT);
+    SIGNAL_RETURN;
+}
+
+void
+deleteImage(Buffer *buf)
+{
+    AnchorList *al;
+    Anchor *a;
+    int i;
+
+    if (! buf)
+	return;
+    al = buf->img;
+    if (! al)
+	return;
+    for (i = 0, a = al->anchors; i < al->nanchor; i++, a++) {
+	if (a->image && a->image->cache &&
+		a->image->cache->loaded != IMG_FLAG_UNLOADED &&
+		a->image->cache->index < 0)
+	    unlink(a->image->cache->file);
+    }
+    loadImage(IMG_FLAG_STOP);
+}
+
+void
+getAllImage(Buffer *buf)
+{
+    AnchorList *al;
+    Anchor *a;
+    ParsedURL *current;
+    int i;
+
+    if (! buf)
+	return;
+    al = buf->img;
+    if (! al)
+	return;
+    current = baseURL(buf);
+    for (i = 0, a = al->anchors; i < al->nanchor; i++, a++) {
+	if (a->image)
+	    a->image->cache = getImage(a->image, current, buf->image_flag);
+    }
+}
+
+void
+loadImage(int flag)
+{
+    extern int in_getch;
+    int wait_st;
+
+    if (flag == IMG_FLAG_STOP) {
+	if (image_pid) {
+	    kill(image_pid, SIGKILL);
+#ifdef HAVE_WAITPID
+	    waitpid(image_pid, &wait_st, 0);
+#else
+	    wait(&wait_st);
+#endif
+	    image_pid = 0;
+	}
+	image_cache = NULL;
+	image_list = NULL;
+	image_file = NULL;
+	return;
+    }
+
+    if (flag == IMG_FLAG_NEXT && image_cache) {
+	struct stat st;
+	if (image_pid) {
+#ifdef HAVE_WAITPID
+	    waitpid(image_pid, &wait_st, 0);
+#else
+	    wait(&wait_st);
+#endif
+	    image_pid = 0;
+	}
+	if (! stat(image_cache->file, &st)) {
+	    image_cache->loaded = IMG_FLAG_LOADED;
+	    if (getImageSize(image_cache)) {
+		if (Currentbuf)
+		    Currentbuf->need_reshape = TRUE;
+	    }
+	} else {
+	    image_cache->loaded = IMG_FLAG_ERROR;
+	}
+	image_cache = NULL;
+	if (! in_getch)
+	    return;
+	drawImage();
+    }
+    if (image_cache)
+	return;
+
+    image_pid = 0;
+    if (! image_list)
+	return;
+    while(1) {
+	image_cache = (ImageCache *)popValue(image_list);
+	if (! image_cache) {
+	    if (Currentbuf && Currentbuf->need_reshape)
+		displayBuffer(Currentbuf, B_NORMAL);
+	    return;
+	}
+	if (image_cache->loaded == IMG_FLAG_UNLOADED)
+	    break;
+    }
+
+    flush_tty();
+    signal(SIGUSR1, SigUsr1);
+    if ((image_pid = fork()) == 0) {
+	Buffer *b;
+
+	signal(SIGHUP, SIG_IGN);
+	signal(SIGINT, SIG_IGN);
+	signal(SIGQUIT, SIG_IGN);
+	signal(SIGTERM, SIG_IGN);
+	close_tty();
+	QuietMessage = TRUE;
+	fmInitialized = FALSE;
+	current_source = image_cache->file;
+	b = loadGeneralFile(image_cache->url, image_cache->current, NULL, 0,
+		NULL);
+	if (! b || ! b->real_type  || strncasecmp(b->real_type, "image/", 6))
+	    unlink(image_cache->file);
+	kill(getppid(), SIGUSR1);
+	exit(0);
+    }
+}
+
+ImageCache *
+getImage(Image *image, ParsedURL *current, int flag)
+{
+    Str key;
+    ImageCache *cache;
+
+    if (! activeImage)
+	return;
+    if (! image_hash)
+	image_hash = newHash_hist(100);
+    if (image->cache)
+	cache = image->cache;
+    else {
+	key = Sprintf("%d;%d;%s", image->width, image->height, image->url);
+    	cache = (ImageCache *)getHash_hist(image_hash, key->ptr, NULL);
+    }
+    if (cache && cache->index && abs(cache->index) <= image_index - MAX_IMAGE) {
+	struct stat st;
+	if (stat(cache->file, &st))
+	    cache->loaded = IMG_FLAG_UNLOADED;
+	cache->index = 0;
+    }
+
+    if (! cache) {
+	if (flag == IMG_FLAG_SKIP)
+	    return NULL;
+
+	cache = New(ImageCache);
+	cache->url = image->url;
+	cache->current = current;
+	cache->file = tmpfname(TMPF_DFL, image->ext)->ptr;
+	cache->index = 0;
+	cache->loaded = IMG_FLAG_UNLOADED;
+	cache->width = image->width;
+	cache->height = image->height;
+	putHash_hist(image_hash, key->ptr, (void *)cache);
+	pushText(fileToDelete, cache->file);
+    }
+    if (flag != IMG_FLAG_SKIP) {
+	if (cache->loaded == IMG_FLAG_UNLOADED) {
+	    if (! image_file)
+		image_file = newHash_hist(100);
+	    if (! getHash_hist(image_file, cache->file, NULL)) {
+		putHash_hist(image_file, cache->file, (void *)cache);
+		if (! image_list)
+		    image_list = newGeneralList();
+		pushValue(image_list, (void *)cache);
+	    }
+	}
+	if (! cache->index)
+	    cache->index = ++image_index;
+    }
+    if (cache->loaded == IMG_FLAG_LOADED)
+	getImageSize(cache);
+    return cache;
+}
+
+int
+getImageSize(ImageCache *cache)
+{
+    Str tmp;
+    FILE *f;
+    int w = 0, h = 0;
+
+    if (! activeImage)
+	return 0;
+    if (! cache || cache->loaded != IMG_FLAG_LOADED ||
+	(cache->width > 0 && cache->height > 0))
+	return 0;
+    if (Imgsize[0] != '/')
+	tmp = Sprintf("%s/%s %s", LIB_DIR, Imgsize,
+		quoteShell(cache->file)->ptr);
+    else
+	tmp = Sprintf("%s %s", Imgsize, quoteShell(cache->file)->ptr);
+    f = popen(tmp->ptr, "r");
+    if (!f)
+	return 0;
+    fscanf(f, "%d %d", &w, &h);
+    pclose(f);
+
+    if (! (w > 0 && h > 0))
+	return 0;
+    w = (int)(w * image_scale / 100 + 0.5);
+    if (w == 0)
+	w = 1;
+    h = (int)(h * image_scale / 100 + 0.5);
+    if (h == 0)
+	h = 1;
+    if (cache->width < 0 && cache->height < 0) {
+	cache->width = w;
+	cache->height = h;
+    } else if (cache->width < 0) {
+	cache->width = (int)((double)cache->height * w / h + 0.5);
+    } else if (cache->height < 0) {
+	cache->height = (int)((double)cache->width * h / w + 0.5);
+    }
+    if (cache->width == 0)
+	cache->width = 1;
+    if (cache->height == 0)
+	cache->height = 1;
+    tmp = Sprintf("%d;%d;%s", cache->width, cache->height, cache->url);
+    putHash_hist(image_hash, tmp->ptr, (void *)cache);
+    return 1;
+}
+#endif
 
 Str
-process_img(struct parsed_tag * tag)
+process_img(struct parsed_tag * tag, int width)
 {
     char *p, *q, *r, *r2, *s;
-    int w, i;
+#ifdef USE_IMAGE
+    int w, i, nw, ni, n, w0, i0, align, xoffset, yoffset, top, bottom, ismap;
+    int use_image = activeImage && displayImage;
+#else
+    int w, i, nw, n;
+#endif
     Str tmp = Strnew();
 
     if (!parsedtag_get_value(tag, ATTR_SRC, &p))
@@ -2063,19 +2410,68 @@
     q = NULL;
     parsedtag_get_value(tag, ATTR_ALT, &q);
     w = -1;
-    parsedtag_get_value(tag, ATTR_WIDTH, &w);
+    if (parsedtag_get_value(tag, ATTR_WIDTH, &w)) {
+	if (w < 0) {
+	    if (width > 0)
+		w = (int)(- width * pixel_per_char * w / 100 + 0.5);
+	    else
+		w = -1;
+	}
+#ifdef USE_IMAGE
+if (use_image) {
+	if (w > 0) {
+	    w = (int)(w * image_scale / 100 + 0.5);
+	    if (w == 0)
+		w = 1;
+	}
+}
+#endif
+    }
+#ifdef USE_IMAGE
+if (use_image) {
     i = -1;
+    if (parsedtag_get_value(tag, ATTR_HEIGHT, &i)) {
+	if (i > 0) {
+	    i = (int)(i * image_scale / 100 + 0.5);
+	    if (i == 0)
+		i = 1;
+	} else {
+	    i = -1;
+	}
+    }
+    align = -1;
+    parsedtag_get_value(tag, ATTR_ALIGN, &align);
+    ismap = 0;
+    if (parsedtag_exists(tag, ATTR_ISMAP))
+	ismap = 1;
+} else
+#endif
     parsedtag_get_value(tag, ATTR_HEIGHT, &i);
     r = NULL;
     parsedtag_get_value(tag, ATTR_USEMAP, &r);
 
     tmp = Strnew_size(128);
+#ifdef USE_IMAGE
+if (use_image) {
+    switch (align) {
+    case ALIGN_LEFT:
+	Strcat_charp(tmp, "<div align=left>");
+	break;
+    case ALIGN_CENTER:
+	Strcat_charp(tmp, "<div align=center>");
+	break;
+    case ALIGN_RIGHT:
+	Strcat_charp(tmp, "<div align=right>");
+	break;
+    }
+}
+#endif
     if (r) {
 	r2 = strchr(r, '#');
-#ifdef NEW_FORM
 	s = "<form_int method=internal action=map>";
+#ifdef NEW_FORM
 	process_form(parse_tag(&s, TRUE));
-	Strcat(tmp, Sprintf("<pre_int><input_alt fid=\"%d\" "
+	Strcat(tmp, Sprintf("<input_alt fid=\"%d\" "
 			    "type=hidden name=link value=\"",
 			    cur_form_id));
 	Strcat_charp(tmp, htmlquote_str((r2) ? r2 + 1 : r));
@@ -2083,58 +2479,158 @@
 			    "type=submit no_effect=true>",
 			    cur_hseq++, cur_form_id));
 #else				/* not NEW_FORM */
-	Strcat_charp(tmp, "<form_int method=internal action=map>"
-		   "<pre_int><input_alt type=hidden name=link value=\"");
+	Strcat_charp(tmp, s);
+	Strcat_charp(tmp, "<input_alt type=hidden name=link value=\"");
 	Strcat_charp(tmp, htmlquote_str((r2) ? r2 + 1 : r));
 	Strcat(tmp, Sprintf("\"><input_alt hseq=\"%d\" type=submit "
 			    "no_effect=true>", cur_hseq++));
 #endif				/* not NEW_FORM */
     }
+#ifdef USE_IMAGE
+if (use_image) {
+    w0 = w;
+    i0 = i;
+    if (w < 0 || i < 0) {
+	char *url, *ext;
+	Image image;
+	ParsedURL u;
+
+	parseURL2(p, &u, cur_baseURL);
+	image.url = cURLcode(parsedURL2Str(&u)->ptr, cur_document_code);
+	image.ext = filename_extension(u.file, TRUE);
+	image.cache = NULL;
+	image.width = w;
+	image.height = i;
+
+	image.cache = getImage(&image, cur_baseURL, IMG_FLAG_SKIP);
+	if (image.cache && image.cache->width > 0 &&
+		image.cache->height > 0) {
+	    w = w0 = image.cache->width;
+	    i = i0 = image.cache->height;
+	}
+	if (w < 0)
+	    w = 8 * pixel_per_char;
+	if (i < 0)
+	    i = pixel_per_line;
+    }
+    nw = (w > 3) ? (int)((w - 3) / pixel_per_char + 1) : 1;
+    ni = (i > 3) ? (int)((i - 3) / pixel_per_line + 1) : 1;
+    Strcat(tmp, Sprintf("<pre_int><img_alt hseq=\"%d\" src=\"", cur_iseq++));
+} else 
+#endif
+{
+    if (w < 0)
+	w = 12 * pixel_per_char;
+    nw = w ? (int)((w - 1) / pixel_per_char + 1) : 1;
+    Strcat(tmp, Sprintf("<pre_int><img_alt src=\""));
+}
+    Strcat_charp(tmp, htmlquote_str(p));
+    Strcat_charp(tmp, "\"");
+#ifdef USE_IMAGE
+if (use_image) {
+    if (w0 >= 0)
+	Strcat(tmp, Sprintf(" width=%d", w0));
+    if (i0 >= 0)
+	Strcat(tmp, Sprintf(" height=%d", i0));
+    switch (align) {
+    case ALIGN_TOP:
+	top = 0;
+	bottom = ni - 1;
+	yoffset = 0;
+	break;
+    case ALIGN_MIDDLE:
+	top = ni / 2;
+	bottom = top;
+	if (top * 2 == ni)
+	    yoffset = (int)(((ni + 1) * pixel_per_line - i) / 2);
+	else
+	    yoffset = (int)((ni * pixel_per_line - i) / 2);
+	break;
+    case ALIGN_BOTTOM:
+	top = ni - 1;
+	bottom = 0;
+	yoffset = (int)(ni * pixel_per_line - i);
+	break;
+    default:
+	top = ni - 1;
+	bottom = 0;
+	if (ni == 1 && ni * pixel_per_line > i)
+	    yoffset = 0;
+	else {
+	    yoffset = (int)(ni * pixel_per_line - i);
+	    if (yoffset <= -2)
+		yoffset++;
+	}
+	break;
+    }
+    xoffset = (int)((nw * pixel_per_char - w) / 2);
+    if (xoffset)
+	Strcat(tmp, Sprintf(" xoffset=%d", xoffset));
+    if (yoffset)
+	Strcat(tmp, Sprintf(" yoffset=%d", yoffset));
+    if (top)
+	Strcat(tmp, Sprintf(" top_margin=%d", top));
+    if (bottom)
+	Strcat(tmp, Sprintf(" bottom_margin=%d", bottom));
+    if (r) {
+	Strcat_charp(tmp, " usemap=\"");
+	Strcat_charp(tmp, htmlquote_str((r2) ? r2 + 1 : r));
+	Strcat_charp(tmp, "\"");
+    }
+    if (ismap)
+	Strcat_charp(tmp, " ismap");
+}
+#endif
+    Strcat_charp(tmp, ">");
     if (q != NULL && *q == '\0' && ignore_null_img_alt)
 	q = NULL;
-    if (q != NULL || r != NULL)
-	Strcat_charp(tmp, "<img_alt src=\"");
-    else
-	Strcat_charp(tmp, "<nobr><img_alt src=\"");
-    Strcat_charp(tmp, htmlquote_str(p));
-    Strcat_charp(tmp, "\">");
     if (q != NULL) {
-	Strcat_charp(tmp, htmlquote_str(q));
-	Strcat_charp(tmp, "</img_alt> ");
-	goto img_end2;
+	n = strlen(q);
+#ifdef USE_IMAGE
+if (use_image) {
+	if (n > nw) {
+	    n = nw;
+	    Strcat_charp(tmp, htmlquote_str(Strnew_charp_n(q, nw)->ptr));
+	} else
+	    Strcat_charp(tmp, q);
+} else
+#endif
+	Strcat_charp(tmp, q);
+	goto img_end;
     }
     if (w > 0 && i > 0) {
 	/* guess what the image is! */
 	if (w < 32 && i < 48) {
 	    /* must be an icon or space */
+	    n = 1;
 	    if (strcasestr(p, "space") || strcasestr(p, "blank"))
-		Strcat_charp(tmp, "_</img_alt>");
+		Strcat_charp(tmp, "_");
 	    else {
 		if (w * i < 8 * 16)
-		    Strcat_charp(tmp, "*</img_alt>");
+		    Strcat_charp(tmp, "*");
 		else {
 #ifdef KANJI_SYMBOLS
-		    Strcat_charp(tmp, "●</img_alt>");
+		    Strcat_charp(tmp, "●");
+		    n = 2;
 #else				/* not KANJI_SYMBOLS */
-		    Strcat_charp(tmp, "#</img_alt>");
+		    Strcat_charp(tmp, "#");
 #endif				/* not KANJI_SYMBOLS */
 		}
 	    }
-	    goto img_end1;
+	    goto img_end;
 	}
 	if (w > 200 && i < 13) {
 	    /* must be a horizontal line */
 #ifndef KANJI_SYMBOLS
 	    Strcat_charp(tmp, "<_RULE>");
 #endif				/* not KANJI_SYMBOLS */
-	    w /= pixel_per_char;
-	    for (i = 0; i < w - (HR_RULE_WIDTH - 1); i += HR_RULE_WIDTH)
+	    for (i = 0; i < nw - (HR_RULE_WIDTH - 1); i += HR_RULE_WIDTH)
 		Strcat_charp(tmp, HR_RULE);
 #ifndef KANJI_SYMBOLS
 	    Strcat_charp(tmp, "</_RULE>");
 #endif				/* not KANJI_SYMBOLS */
-	    Strcat_charp(tmp, "</img_alt>");
-	    goto img_end1;
+	    n = i;
+	    goto img_end;
 	}
     }
     for (q = p; *q; q++);
@@ -2143,30 +2639,46 @@
     if (*q == '/')
 	q++;
     Strcat_char(tmp, '[');
+    n = 1;
     p = q;
     for (; *q; q++) {
 	if (!IS_ALNUM(*q) && *q != '_' && *q != '-') {
 	    break;
 	}
-	else if (w > 0 && !IS_ALNUM(*q) && q - p + 2 > (int)(w / pixel_per_char)) {
-	    Strcat_charp(tmp, "..");
-	    break;
-	}
 	Strcat_char(tmp, *q);
+	n++;
+	if (n + 1 >= nw)
+	    break;
     }
-    Strcat_charp(tmp, "]</img_alt>");
-  img_end1:
-    if (r == NULL)
-	Strcat_charp(tmp, "</nobr>");
-  img_end2:
+    Strcat_char(tmp, ']');
+    n++;
+  img_end:
+#ifdef USE_IMAGE
+if (use_image) {
+    for (; n < nw; n++)
+	Strcat_char(tmp, ' ');
+}
+#endif
+    Strcat_charp(tmp, "</img_alt></pre_int>");
     if (r) {
+	Strcat_charp(tmp, "</input_alt>");
 #ifdef NEW_FORM
-	Strcat_charp(tmp, "</input_alt></pre_int>");
 	process_n_form();
 #else				/* not NEW_FORM */
-	Strcat_charp(tmp, "</input_alt></pre_int></form_int>");
+	Strcat_charp(tmp, "</form_int>");
 #endif				/* not NEW_FORM */
     }
+#ifdef USE_IMAGE
+if (use_image) {
+    switch (align) {
+    case ALIGN_RIGHT:
+    case ALIGN_CENTER:
+    case ALIGN_LEFT:
+	Strcat_charp(tmp, "</div>");
+	break;
+    }
+}
+#endif
     return tmp;
 }
 
@@ -2187,8 +2699,8 @@
 Str
 process_input(struct parsed_tag * tag)
 {
-    int i, w, v, x, y;
-    char *q , *p, *r, *p2;
+    int i, w, v, x, y, iw, ih;
+    char *q , *p, *r, *p2, *s;
     Str tmp;
     char *qq = "";
     int qlen = 0;
@@ -2275,6 +2787,22 @@
 	    Strcat_charp(tmp, "<u>");
 	    break;
 	case FORM_INPUT_IMAGE:
+#ifdef USE_IMAGE
+	    s = NULL;
+	    parsedtag_get_value(tag, ATTR_SRC, &s);
+	    if (s) {
+		Strcat(tmp, Sprintf("<img src=\"%s\"", htmlquote_str(s)));
+		if (p2)
+		    Strcat(tmp, Sprintf(" alt=\"%s\"", htmlquote_str(p2)));
+		if (parsedtag_get_value(tag, ATTR_WIDTH, &iw))
+		    Strcat(tmp, Sprintf(" width=\"%d\"", iw));
+		if (parsedtag_get_value(tag, ATTR_HEIGHT, &ih))
+		    Strcat(tmp, Sprintf(" height=\"%d\"", ih));
+		Strcat_charp(tmp, ">");
+		Strcat_charp(tmp, "</input_alt></pre_int>");
+		return tmp;
+	    }
+#endif
 	case FORM_INPUT_SUBMIT:
 	case FORM_INPUT_BUTTON:
 	case FORM_INPUT_RESET:
@@ -2393,10 +2921,11 @@
     process_option();
 #ifdef MENU_SELECT
     if (!select_is_multiple && n_select < MAX_SELECT) {
-	if (select_option[n_select].first)
-	    Strcat(select_str, textfieldrep(chooseSelectOption(
-		select_option[n_select].first, CHOOSE_OPTION),
-		cur_option_maxwidth));
+	 if (select_option[n_select].first) {
+	     FormItemList sitem;
+	     chooseSelectOption(&sitem, select_option[n_select].first);
+	     Strcat(select_str, textfieldrep(sitem.label, cur_option_maxwidth));
+	 }
 	Strcat_charp(select_str, "</input_alt>]</pre_int>");
 	n_select++;
 	if (n_select == MAX_SELECT) {
@@ -2689,7 +3218,7 @@
 Str
 process_form(struct parsed_tag *tag)
 {
-    char *p, *q, *r, *s, *tg;
+    char *p, *q, *r, *s, *tg, *n;
     char cs = 0;
 
     p = "get";
@@ -2707,6 +3236,8 @@
     parsedtag_get_value(tag, ATTR_ENCTYPE, &s);
     tg = NULL;
     parsedtag_get_value(tag, ATTR_TARGET, &tg);
+    n = NULL;
+    parsedtag_get_value(tag, ATTR_NAME, &n);
     form_max++;
     form_sp++;
     if (forms_size == 0) {
@@ -2720,7 +3251,7 @@
 	form_stack = New_Reuse(int, form_stack, forms_size);
     }
     forms[form_max] =
-	newFormList(q, p, &cs, s, tg, (form_max > 0) ? forms[form_max - 1] : NULL);
+	newFormList(q, p, &cs, s, tg, n, (form_max > 0) ? forms[form_max - 1] : NULL);
     form_stack[form_sp] = form_max;
 
     return NULL;
@@ -3278,12 +3809,24 @@
 	close_anchor(h_env, obuf);
 	return 1;
     case HTML_IMG:
-	tmp = process_img(tag);
+	tmp = process_img(tag, h_env->limit);
 	HTMLlineproc1(tmp->ptr, h_env);
 	return 1;
     case HTML_IMG_ALT:
 	if (parsedtag_get_value(tag, ATTR_SRC, &p))
 	    obuf->img_alt = Strnew_charp(p);
+#ifdef USE_IMAGE
+	i = 0;
+	if (parsedtag_get_value(tag, ATTR_TOP_MARGIN, &i)) {
+	    if (i > obuf->top_margin)
+		obuf->top_margin = i;
+	}
+	i = 0;
+	if (parsedtag_get_value(tag, ATTR_BOTTOM_MARGIN, &i)) {
+	    if (i > obuf->bottom_margin)
+		obuf->bottom_margin = i;
+	}
+#endif
 	return 0;
     case HTML_N_IMG_ALT:
 	if (obuf->img_alt) {
@@ -3482,6 +4025,11 @@
 	}
 	return 1;
     case HTML_BASE:
+#ifdef USE_IMAGE
+	p = NULL;
+	if (parsedtag_get_value(tag, ATTR_HREF, &p))
+	    parseURL(p, cur_baseURL, NULL);
+#endif
     case HTML_MAP:
     case HTML_N_MAP:
     case HTML_AREA:
@@ -3578,7 +4126,7 @@
 {
     Anchor *a_href = NULL, *a_img = NULL, *a_form = NULL;
     char outc[LINELEN];
-    char *p, *q, *r, *str;
+    char *p, *q, *r, *s, *str;
 #ifndef NEW_FORM
     char cs;
 #endif
@@ -3735,8 +4283,64 @@
 		    break;
 		case HTML_IMG_ALT:
 		    if (parsedtag_get_value(tag, ATTR_SRC, &p)) {
-			a_img = registerImg(buf, p,
-					    currentLn(buf), pos);
+#ifdef USE_IMAGE
+			int w = -1, h = -1, iseq = 0, ismap = 0;
+			int xoffset = 0, yoffset = 0, top = 0, bottom = 0;
+			parsedtag_get_value(tag, ATTR_HSEQ, &iseq);
+			parsedtag_get_value(tag, ATTR_WIDTH, &w);
+			parsedtag_get_value(tag, ATTR_HEIGHT, &h);
+			parsedtag_get_value(tag, ATTR_XOFFSET, &xoffset);
+			parsedtag_get_value(tag, ATTR_YOFFSET, &yoffset);
+			parsedtag_get_value(tag, ATTR_TOP_MARGIN, &top);
+			parsedtag_get_value(tag, ATTR_BOTTOM_MARGIN, &bottom);
+			if (parsedtag_exists(tag, ATTR_ISMAP))
+			    ismap = 1;
+			q = NULL;
+			parsedtag_get_value(tag, ATTR_USEMAP, &q);
+			if (iseq > 0) {
+			    buf->imarklist = putHmarker(buf->imarklist,
+				currentLn(buf), pos, iseq - 1);
+			}
+#endif
+			a_img = registerImg(buf, p, currentLn(buf), pos);
+#ifdef USE_IMAGE
+			a_img->hseq = iseq;
+			a_img->image = NULL;
+			if (iseq > 0) {
+			    ParsedURL u;
+			    Image *image;
+
+			    parseURL2(a_img->url, &u, cur_baseURL);
+			    a_img->image = image = New(Image);
+			    image->url = cURLcode(parsedURL2Str(&u)->ptr,
+				 cur_document_code);;
+			    image->ext = filename_extension(u.file, TRUE);
+			    image->cache = NULL;
+			    image->width = w;
+			    image->height = h;
+			    image->xoffset = xoffset;
+			    image->yoffset = yoffset;
+			    image->y = currentLn(buf) - top;
+			    if (image->xoffset < 0 && pos == 0)
+				image->xoffset = 0;
+			    if (image->yoffset < 0 && image->y == 1)
+				image->yoffset = 0;
+			    image->rows = 1 + top + bottom;
+			    image->map = q;
+			    image->ismap = ismap;
+			    image->touch = 0;
+			    image->cache = getImage(image, cur_baseURL,
+				IMG_FLAG_SKIP);
+			} else if (iseq < 0) {
+			    BufferPoint *po = buf->imarklist->marks - iseq - 1;
+			    Anchor *a = retrieveAnchor(buf->img,
+				po->line, po->pos);
+			    if (a) {
+				a_img->url = a->url;
+				a_img->image = a->image;
+			    }	
+			}
+#endif
 		    }
 		    effect |= PE_IMAGE;
 		    break;
@@ -3804,12 +4408,15 @@
 #ifndef NEW_FORM
 		case HTML_FORM:
 		case HTML_FORM_INT:
+		    char *s, *t, *n;
 		    form_sp++;
 		    if (form_sp >= FORMSTACK_SIZE)
 			break;
 		    p = "get";
 		    q = "/";
 		    s = NULL;
+		    t = NULL;
+		    n = NULL;
 		    cs = 0;
 		    parsedtag_get_value(tag, ATTR_METHOD, &p);
 		    parsedtag_get_value(tag, ATTR_ACTION, &q);
@@ -3818,7 +4425,9 @@
 			cs = check_charset(r);
 #endif
 		    parsedtag_get_value(tag, ATTR_ENCTYPE, &s);
-		    buf->formlist = newFormList(q, p, &cs, s, buf->formlist);
+		    parsedtag_get_value(tag, ATTR_TARGET, &t);
+		    parsedtag_get_value(tag, ATTR_NAME, &n);
+		    buf->formlist = newFormList(q, p, &cs, s, t, n, buf->formlist);
 		    form_stack[form_sp] = buf->formlist;
 		    break;
 		case HTML_N_FORM:
@@ -3831,9 +4440,8 @@
 		    if (parsedtag_get_value(tag, ATTR_NAME, &p)) {
 			MapList *m = New(MapList);
 			m->name = Strnew_charp(p);
+			m->area = newGeneralList();
 			m->next = buf->maplist;
-			m->urls = newTextList();
-			m->alts = newTextList();
 			buf->maplist = m;
 		    }
 		    break;
@@ -3845,11 +4453,17 @@
 						 * <map>..</map> */
 			break;
 		    if (parsedtag_get_value(tag, ATTR_HREF, &p)) {
-			pushText(buf->maplist->urls, p);
-		        if (parsedtag_get_value(tag, ATTR_ALT, &q))
-			    pushText(buf->maplist->alts, q);
-			else
-			    pushText(buf->maplist->alts, "");
+			MapArea *a;
+			q = "";
+		        parsedtag_get_value(tag, ATTR_ALT, &q);
+			r = NULL;
+			s = NULL;
+#ifdef USE_IMAGE
+		        parsedtag_get_value(tag, ATTR_SHAPE, &r);
+		        parsedtag_get_value(tag, ATTR_COORDS, &s);
+#endif
+			a = newMapArea(p, q, r, s);
+			pushValue(buf->maplist->area, (void *)a);
 		    }
 		    break;
 		case HTML_FRAMESET:
@@ -3938,6 +4552,9 @@
     }
     if (w3m_debug)
 	fclose(debug);
+#ifdef USE_IMAGE
+    addMultirowsImg(buf, buf->img);
+#endif
 }
 
 void
@@ -4634,6 +5251,10 @@
     obuf->prev_ctype = PC_ASCII;
     obuf->tag_sp = 0;
     obuf->fontstat_sp = 0;
+#ifdef USE_IMAGE
+    obuf->top_margin = 0;
+    obuf->bottom_margin = 0;
+#endif
     obuf->bp.init_flag = 1;
     set_breakpoint(obuf, 0);
 
@@ -4695,10 +5316,9 @@
 	HTMLlineproc1("<br>Transfer Interrupted!<br>", &htmlenv1);
 	goto phase2;
     }
-    if (fmInitialized) {
-	prevtrap = signal(SIGINT, KeyAbort);
+    prevtrap = signal(SIGINT, KeyAbort);
+    if (fmInitialized)
 	term_cbreak();
-    }
 
     n_textarea = 0;
     cur_textarea = NULL;
@@ -4714,6 +5334,17 @@
 #endif				/* NEW_FORM */
 
     cur_hseq = 1;
+#ifdef USE_IMAGE
+    cur_iseq = 1;
+    if (newBuf->image_flag)
+	image_flag = newBuf->image_flag;
+    else if (activeImage && displayImage && autoImage)
+	image_flag = IMG_FLAG_AUTO;
+    else
+	image_flag = IMG_FLAG_SKIP;
+    if (newBuf->currentURL.file)
+	cur_baseURL = baseURL(newBuf);
+#endif
 
     if (w3m_halfload) {
 	newBuf->buffername = "---";
@@ -4722,10 +5353,9 @@
 #endif				/* JP_CHARSET */
 	HTMLlineproc3(newBuf, f->stream);
 	w3m_halfload = FALSE;
-	if (fmInitialized) {
+	if (fmInitialized)
 	    term_raw();
-	    signal(SIGINT, prevtrap);
-	}
+	signal(SIGINT, prevtrap);
 	return;
     }
 
@@ -4743,6 +5373,9 @@
 	code = content_charset;
     else
 	code = DocumentCode;
+#ifdef USE_IMAGE
+    cur_document_code = code;
+#endif
     content_charset = '\0';
 #endif
 #if	0
@@ -4755,15 +5388,26 @@
 	if (src)
 	    Strfputs(lineBuf2, src);
 	linelen += lineBuf2->length;
+	if (w3m_dump_source)
+	    continue;
 	showProgress(&linelen, &trbyte);
 #ifdef JP_CHARSET
 	if (content_charset != '\0') {	/* <META> */
 	    code = content_charset;
+#ifdef USE_IMAGE
+	    cur_document_code = code;
+#endif
 	    content_charset = '\0';
 	}
 #endif
-	if (!internal)
+	if (!internal) {
 	    lineBuf2 = convertLine(f, lineBuf2, &code, HTML_MODE);
+#ifdef JP_CHARSET
+#ifdef USE_IMAGE
+	    cur_document_code = code;
+#endif
+#endif
+	}
 #ifdef USE_NNTP
 	if (f->scheme == SCM_NEWS) {
 	    if (Str_news_endline(lineBuf2)) {
@@ -4782,22 +5426,23 @@
     if (htmlenv1.title)
 	newBuf->buffername = htmlenv1.title;
     if (w3m_halfdump) {
-	if (fmInitialized) {
+	if (fmInitialized)
 	    term_raw();
-	    signal(SIGINT, prevtrap);
-	}
+	signal(SIGINT, prevtrap);
 	return;
     }
   phase2:
     newBuf->trbyte = trbyte + linelen;
-    if (fmInitialized) {
+    if (fmInitialized)
 	term_raw();
-	signal(SIGINT, prevtrap);
-    }
+    signal(SIGINT, prevtrap);
     HTMLlineproc2(newBuf, htmlenv1.buf);
 #ifdef JP_CHARSET
     newBuf->document_code = code;
 #endif				/* JP_CHARSET */
+#ifdef USE_IMAGE
+    newBuf->image_flag = image_flag;
+#endif
 }
 
 /* 
@@ -4812,22 +5457,22 @@
 
     newBuf = newBuffer(INIT_BUFFER_WIDTH);
     if (SETJMP(AbortLoading) != 0) {
+	if (fmInitialized)
+	    term_raw();
+	signal(SIGINT, prevtrap);
 	discardBuffer(newBuf);
 	return NULL;
     }
-    init_stream(&f, SCM_LOCAL, newStrStream(page));
-
-    if (fmInitialized) {
-	prevtrap = signal(SIGINT, KeyAbort);
+    prevtrap = signal(SIGINT, KeyAbort);
+    if (fmInitialized)
 	term_cbreak();
-    }
 
+    init_stream(&f, SCM_LOCAL, newStrStream(page));
     loadHTMLstream(&f, newBuf, NULL, TRUE);
 
-    if (fmInitialized) {
+    if (fmInitialized)
 	term_raw();
-	signal(SIGINT, prevtrap);
-    }
+    signal(SIGINT, prevtrap);
     newBuf->topLine = newBuf->firstLine;
     newBuf->lastLine = newBuf->currentLine;
     newBuf->currentLine = newBuf->firstLine;
@@ -4963,10 +5608,9 @@
     if (SETJMP(AbortLoading) != 0) {
 	goto _end;
     }
-    if (fmInitialized) {
-	prevtrap = signal(SIGINT, KeyAbort);
+    prevtrap = signal(SIGINT, KeyAbort);
+    if (fmInitialized)
 	term_cbreak();
-    }
 
     if (newBuf->sourcefile == NULL && uf->scheme != SCM_LOCAL) {
 	tmpf = tmpfname(TMPF_SRC, NULL);
@@ -4991,6 +5635,8 @@
 	if (src)
 	    Strfputs(lineBuf2, src);
 	linelen += lineBuf2->length;
+	if (w3m_dump_source)
+	    continue;
 	showProgress(&linelen, &trbyte);
 	lineBuf2 = convertLine(uf, lineBuf2, &code, PAGER_MODE);
 	if (squeezeBlankLine) {
@@ -5027,10 +5673,9 @@
 		   lineBuf2->length, nlines);
     }
   _end:
-    if (fmInitialized) {
-	signal(SIGINT, prevtrap);
+    if (fmInitialized)
 	term_raw();
-    }
+    signal(SIGINT, prevtrap);
     newBuf->topLine = newBuf->firstLine;
     newBuf->currentLine = newBuf->firstLine;
     newBuf->trbyte = trbyte + linelen;
@@ -5043,6 +5688,71 @@
     return newBuf;
 }
 
+#ifdef USE_IMAGE
+Buffer *
+loadImageBuffer(URLFile *uf, Buffer *newBuf)
+{
+    Image *image;
+    ImageCache *cache;
+    Str tmp, tmpf;
+    FILE *src;
+    URLFile f;
+    MySignalHandler(*prevtrap) ();
+
+    loadImage(IMG_FLAG_STOP);
+    image = New(Image);
+    image->url = parsedURL2Str(cur_baseURL)->ptr;
+    image->ext = filename_extension(cur_baseURL->file, 1);
+    image->width = -1;
+    image->height = -1;
+    cache = getImage(image, cur_baseURL, IMG_FLAG_AUTO);
+    if (! cur_baseURL->is_nocache && cache->loaded == IMG_FLAG_LOADED)
+	goto image_buffer;
+
+    prevtrap = signal(SIGINT, KeyAbort);
+    if (fmInitialized)
+	term_cbreak();
+    if (save2tmp(*uf, cache->file) < 0) {
+	if (fmInitialized)
+	    term_raw();
+	signal(SIGINT, prevtrap);
+	return NULL;
+    }
+    if (fmInitialized)
+	term_raw();
+    signal(SIGINT, prevtrap);
+
+    cache->loaded = IMG_FLAG_LOADED;
+    getImageSize(cache);
+
+image_buffer:
+    if (newBuf == NULL)
+	newBuf = newBuffer(INIT_BUFFER_WIDTH);
+    tmp = Sprintf("<img alt=\"\" src=\"%s\"", htmlquote_str(image->url));
+/*
+    if (cache->width > 0 && cache->height > 0)
+	Strcat(tmp, Sprintf(" width=%d height=%d",
+		cache->width, cache->height));
+*/
+    Strcat_char(tmp, '>');
+    tmpf = tmpfname(TMPF_SRC, ".html");
+    src = fopen(tmpf->ptr, "w");
+    if (src) {
+	newBuf->sourcefile = tmpf->ptr;
+	pushText(fileToDelete, tmpf->ptr);
+    }
+    init_stream(&f, SCM_LOCAL, newStrStream(tmp));
+    loadHTMLstream(&f, newBuf, src, TRUE);
+    if (src)
+	fclose(src);
+
+    newBuf->topLine = newBuf->firstLine;
+    newBuf->lastLine = newBuf->currentLine;
+    newBuf->currentLine = newBuf->firstLine;
+    return newBuf;
+}
+#endif
+
 /* 
  * saveBuffer: write buffer to file
  */
@@ -5413,10 +6123,9 @@
     if (SETJMP(AbortLoading) != 0) {
 	goto _end;
     }
-    if (fmInitialized) {
-	prevtrap = signal(SIGINT, KeyAbort);
+    prevtrap = signal(SIGINT, KeyAbort);
+    if (fmInitialized)
 	term_cbreak();
-    }
     check = 0;
     current_content_length = 0;
 #ifdef USE_NNTP
@@ -5452,10 +6161,9 @@
     }	
   _end:
     bcopy(env_bak, AbortLoading, sizeof(JMP_BUF));
-    if (fmInitialized) {
+    if (fmInitialized)
 	term_raw();
-	signal(SIGINT, prevtrap);
-    }
+    signal(SIGINT, prevtrap);
     fclose(ff);
     if (uf.scheme == SCM_FTP)
 	FTPhalfclose(uf.stream);
diff -urN -x gc w3m-0.2.1/fm.h w3m-0.2.1-img-1.10/fm.h
--- w3m-0.2.1/fm.h	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/fm.h	Thu Aug  2 00:43:06 2001
@@ -66,7 +66,14 @@
 #define PAGER_MAX_LINE	10000	/* Maximum line kept as pager */
 #define FNLEN 80
 
+#ifdef USE_IMAGE
+#define MAX_IMAGE 1000
+
+#define DEFAULT_PIXEL_PER_CHAR  7.0	/* arbitrary */
+#define DEFAULT_PIXEL_PER_LINE  14.0	/* arbitrary */
+#else
 #define DEFAULT_PIXEL_PER_CHAR  8.0	/* arbitrary */
+#endif
 #define MINIMUM_PIXEL_PER_CHAR  4.0
 #define MAXIMUM_PIXEL_PER_CHAR  32.0
 
@@ -156,6 +163,7 @@
 #define B_FORCE_REDRAW	1
 #define B_REDRAW	2
 #define B_SCROLL        3
+#define B_REDRAW_IMAGE	4
 
 /* Buffer Property */
 #define BP_NORMAL	0x0
@@ -213,6 +221,17 @@
 #define IN_COMMAND	0x80
 #define IN_URL		0x100
 
+#define IMG_FLAG_SKIP	1
+#define IMG_FLAG_AUTO	2
+
+#define IMG_FLAG_START	0
+#define IMG_FLAG_STOP	1
+#define IMG_FLAG_NEXT	2
+
+#define IMG_FLAG_UNLOADED	0
+#define IMG_FLAG_LOADED		1
+#define IMG_FLAG_ERROR		2
+
 /* 
  * Macros.
  */
@@ -255,10 +274,21 @@
 typedef unsigned char Linecolor;
 #endif
 
+typedef struct _MapArea {
+    char *url;
+    char *alt;
+#ifdef MENU_MAP
+#ifdef USE_IMAGE
+    char shape;
+    short *coords;
+    int ncoords;
+#endif
+#endif
+} MapArea;
+
 typedef struct _MapList {
     Str name;
-    TextList *urls;
-    TextList *alts;
+    GeneralList *area;
     struct _MapList *next;
 } MapList;
 
@@ -282,6 +312,33 @@
     short pos;
 } BufferPoint;
 
+#ifdef USE_IMAGE
+typedef struct _imageCache {
+    char *url;
+    ParsedURL *current;
+    char *file;
+    char loaded;
+    int index;
+    short width;
+    short height;
+} ImageCache;
+
+typedef struct _image {
+    char *url;
+    char *ext;
+    short width;
+    short height;
+    short xoffset;
+    short yoffset;
+    short y;
+    short rows;
+    char *map;
+    char ismap;
+    int touch;
+    ImageCache *cache;
+} Image;
+#endif
+
 typedef struct _anchor {
     char *url;
     char *target;
@@ -289,6 +346,9 @@
     BufferPoint start;
     BufferPoint end;
     int hseq;
+#ifdef USE_IMAGE
+    Image *image;
+#endif
 } Anchor;
 
 #define NO_REFERER ((char*)-1)
@@ -336,6 +396,7 @@
     FormList *formlist;
     MapList *maplist;
     HmarkerList *hmarklist;
+    HmarkerList *imarklist;
     ParsedURL currentURL;
     ParsedURL *baseURL;
     char *baseTarget;
@@ -357,6 +418,8 @@
 #ifdef USE_SSL
     char *ssl_certificate;
 #endif
+    char image_flag;
+    char need_reshape;
 } Buffer;
 
 #define NO_BUFFER ((Buffer*)1)
@@ -384,6 +447,8 @@
     short nobr_level;
     Lineprop prev_ctype;
     char init_flag;
+    short top_margin;
+    short bottom_margin;
 } Breakpoint;
 
 struct readbuffer {
@@ -409,6 +474,8 @@
     Breakpoint bp;
     struct cmdtable *tag_stack[TAG_STACK_SIZE];
     int tag_sp;
+    short top_margin;
+    short bottom_margin;
 };
 
 #define in_bold fontstat[0]
@@ -552,6 +619,9 @@
 #define ALIGN_CENTER 0
 #define ALIGN_LEFT   1
 #define ALIGN_RIGHT  2
+#define ALIGN_MIDDLE 4
+#define ALIGN_TOP    5
+#define ALIGN_BOTTOM 6
 
 #define VALIGN_MIDDLE 0
 #define VALIGN_TOP    1
@@ -609,6 +679,7 @@
 global char PermitSaveToPipe init(FALSE);
 
 global char fmInitialized init(FALSE);
+global char QuietMessage init(FALSE);
 
 extern char GlobalKeymap[];
 extern char EscKeymap[];
@@ -679,6 +750,14 @@
 global int displayLink init(FALSE);
 global int retryAsHttp init(TRUE);
 global int showLineNum init(FALSE);
+#ifdef USE_IMAGE
+global char *Imgdisplay init(IMGDISPLAY);
+global char *Imgsize init(IMGSIZE);
+global int activeImage init(FALSE);
+global int displayImage init(TRUE);
+global int autoImage init(TRUE);
+global int useExtImageViewer init(TRUE);
+#endif
 global char *Editor init(DEF_EDITOR);
 global char *Mailer init(DEF_MAILER);
 global char *ExtBrowser init(DEF_EXT_BROWSER);
@@ -780,6 +859,10 @@
 global int is_redisplay init(FALSE);
 global int clear_buffer init(TRUE);
 global double pixel_per_char init(DEFAULT_PIXEL_PER_CHAR);
+#ifdef USE_IMAGE
+global double pixel_per_line init(DEFAULT_PIXEL_PER_LINE);
+global double image_scale init(100);
+#endif
 global int use_lessopen init(FALSE);
 
 #ifdef JP_CHARSET
diff -urN -x gc w3m-0.2.1/form.c w3m-0.2.1-img-1.10/form.c
--- w3m-0.2.1/form.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/form.c	Thu Aug  2 00:43:06 2001
@@ -43,7 +43,7 @@
 };
 
 struct form_list *
-newFormList(char *action, char *method, char *charset, char *enctype, char *target, struct form_list *_next)
+newFormList(char *action, char *method, char *charset, char *enctype, char *target, char *name, struct form_list *_next)
 {
     struct form_list *l;
     Str a = Strnew_charp(action);
@@ -75,6 +75,7 @@
     l->charset = c;
     l->enctype = e;
     l->target = target;
+    l->name = name;
     l->next = _next;
     l->nitems = 0;
     l->body = NULL;
@@ -100,10 +101,10 @@
     item->type = FORM_UNKNOWN;
     item->size = -1;
     item->rows = 0;
-    item->checked = 0;
+    item->checked = item->init_checked = 0;
     item->accept = 0;
     item->name = NULL;
-    item->value = NULL;
+    item->value = item->init_value = NULL;
     if (parsedtag_get_value(tag, ATTR_TYPE, &p)) {
 	item->type = formtype(p);
 	if (item->size < 0 &&
@@ -115,13 +116,13 @@
     if (parsedtag_get_value(tag, ATTR_NAME, &p))
 	item->name = Strnew_charp(p);
     if (parsedtag_get_value(tag, ATTR_VALUE, &p))
-	item->value = Strnew_charp(p);
-    item->checked = parsedtag_exists(tag, ATTR_CHECKED);
+	item->value = item->init_value = Strnew_charp(p);
+    item->checked = item->init_checked = parsedtag_exists(tag, ATTR_CHECKED);
     item->accept = parsedtag_exists(tag, ATTR_ACCEPT);
     parsedtag_get_value(tag, ATTR_SIZE, &item->size);
     parsedtag_get_value(tag, ATTR_MAXLENGTH, &item->maxlength);
     if (parsedtag_get_value(tag, ATTR_TEXTAREANUMBER, &i))
-	item->value = textarea_str[i];
+	item->value = item->init_value = textarea_str[i];
 #ifdef MENU_SELECT
     if (parsedtag_get_value(tag, ATTR_SELECTNUMBER, &i))
 	item->select_option = select_option[i].first;
@@ -134,8 +135,10 @@
     }
 #ifdef MENU_SELECT
     if (item->type == FORM_SELECT) {
-	item->value = chooseSelectOption(item->select_option, CHOOSE_VALUE);
-	item->label = chooseSelectOption(item->select_option, CHOOSE_OPTION);
+	chooseSelectOption(item, item->select_option);
+	item->init_selected = item->selected;
+	item->init_value = item->value;
+	item->init_label = item->label;
     }
 #endif				/* MENU_SELECT */
     if (item->type == FORM_INPUT_FILE && item->value && item->value->length) {
@@ -300,9 +303,10 @@
     case FORM_TEXTAREA:
 #ifdef MENU_SELECT
     case FORM_SELECT:
-	if (form->type == FORM_SELECT)
+	if (form->type == FORM_SELECT) {
 	    p = form->label->ptr;
-	else
+	    updateSelectOption(form, form->select_option);
+	} else
 #endif				/* MENU_SELECT */
 	    p = form->value->ptr;
 	i = spos + 1;
@@ -503,53 +507,73 @@
     }
 }
 
-Str
-chooseSelectOption(FormSelectOptionItem * item, int choose_type)
+void
+chooseSelectOption(FormItemList *fi, FormSelectOptionItem *item)
 {
-    Str chosen;
-    if (item == NULL)
-	return Strnew_size(0);
-    if (choose_type == CHOOSE_OPTION)
-	chosen = item->label;
-    else
-	chosen = item->value;
-    while (item) {
-	if (item->checked) {
-	    if (choose_type == CHOOSE_OPTION)
-		chosen = item->label;
-	    else
-		chosen = item->value;
+    FormSelectOptionItem *opt;
+    int i;
+
+    fi->selected = 0;
+    if (item == NULL) {
+	fi->value = Strnew_size(0);
+	fi->label = Strnew_size(0);
+	return;
+    }
+    fi->value = item->value;
+    fi->label = item->label;
+    for (i = 0, opt = item; opt != NULL; i++, opt = opt->next) {
+	if (opt->checked) {
+	    fi->value = opt->value;
+	    fi->label = opt->label;
+	    fi->selected = i;
+	    break;
 	}
-	item = item->next;
     }
-    return chosen;
+    updateSelectOption(fi, item);
 }
 
 void
+updateSelectOption(FormItemList *fi, FormSelectOptionItem *item)
+{
+    int i;
+
+    if (fi == NULL || item == NULL)
+	return;
+    for (i = 0; item != NULL; i++, item = item->next) {
+	if (i == fi->selected)
+	    item->checked = TRUE;
+	else
+	    item->checked = FALSE;
+    }
+}
+
+int
 formChooseOptionByMenu(struct form_item_list *fi, int x, int y)
 {
-    int i, n, selected = -1, init_select = 0;
+    int i, n, selected = -1, init_select = fi->selected;
     FormSelectOptionItem *opt;
     char **label;
 
     for (n = 0, opt = fi->select_option; opt != NULL; n++, opt = opt->next);
     label = New_N(char *, n + 1);
-    for (i = 0, opt = fi->select_option; opt != NULL; i++, opt = opt->next) {
+    for (i = 0, opt = fi->select_option; opt != NULL; i++, opt = opt->next)
 	label[i] = opt->label->ptr;
-	if (!Strcmp(fi->value, opt->value))
-	    init_select = i;
-    }
     label[n] = NULL;
 
     optionMenu(x, y, label, &selected, init_select, NULL);
 
+    if (selected < 0)
+	return 0;
     for (i = 0, opt = fi->select_option; opt != NULL; i++, opt = opt->next) {
 	if (i == selected) {
+	    fi->selected = selected;
 	    fi->value = opt->value;
 	    fi->label = opt->label;
 	    break;
 	}
     }
+    updateSelectOption(fi, fi->select_option);
+    return 1;
 }
 #endif				/* MENU_SELECT */
 
diff -urN -x gc w3m-0.2.1/form.h w3m-0.2.1-img-1.10/form.h
--- w3m-0.2.1/form.h	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/form.h	Thu Aug  2 00:43:06 2001
@@ -45,6 +45,7 @@
     int method;
     Str action;
     char *target;
+    char *name;
     int charset;
     int enctype;
     struct form_list *next;
@@ -68,25 +69,24 @@
 } FormSelectOption;
 
 void addSelectOption(FormSelectOption * fso, Str value, Str label, int chk);
-Str chooseSelectOption(FormSelectOptionItem * item, int choose_type);
-void formChooseOptionByMenu(struct form_item_list *fi, int x, int y);
-/* macros for chooseSelectOption */
-#define CHOOSE_OPTION 0
-#define CHOOSE_VALUE 1
+void chooseSelectOption(struct form_item_list *fi, FormSelectOptionItem *item);
+void updateSelectOption(struct form_item_list *fi, FormSelectOptionItem *item);
+int formChooseOptionByMenu(struct form_item_list *fi, int x, int y);
 #endif				/* MENU_SELECT */
 
 typedef struct form_item_list {
     int type;
     Str name;
-    Str value;
-    int checked;
+    Str value, init_value;
+    int checked, init_checked;
     int accept;
     int size;
     int rows;
     int maxlength;
 #ifdef MENU_SELECT
     FormSelectOptionItem *select_option;
-    Str label;
+    Str label, init_label;
+    int selected, init_selected;
 #endif				/* MENU_SELECT */
     struct form_list *parent;
     struct form_item_list *next;
diff -urN -x gc w3m-0.2.1/frame.c w3m-0.2.1-img-1.10/frame.c
--- w3m-0.2.1/frame.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/frame.c	Thu Aug  2 00:43:06 2001
@@ -397,7 +397,12 @@
 	return NULL;
     }
     b->url = parsedURL2Str(&buf->currentURL)->ptr;
-    if (buf->real_scheme != SCM_LOCAL) {
+    if ((buf->real_scheme != SCM_LOCAL)
+#ifdef USE_IMAGE
+	|| (activeImage && ! useExtImageViewer &&
+	 buf->real_type && ! strncasecmp(buf->real_type, "image/", 6))
+#endif
+	) {
 	tmp = tmpfname(TMPF_FRAME, NULL);
 	rename(buf->sourcefile, tmp->ptr);
 	b->source = tmp->ptr;
diff -urN -x gc w3m-0.2.1/func.c w3m-0.2.1-img-1.10/func.c
--- w3m-0.2.1/func.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/func.c	Thu Aug  2 00:43:07 2001
@@ -24,6 +24,8 @@
     int c;
     int f;
     int lineno;
+    int verbose = 1;
+    extern int str_to_bool(char *value, int old);
 
     if (!w3mNFuncList)
 	w3mNFuncList = countFuncList(w3mFuncList);
@@ -43,36 +45,46 @@
 	s = getWord(&p);
 	if (*s == '#')		/* comment */
 	    continue;
-	if (strcmp(s, "keymap")) {	/* error */
-	    emsg = Sprintf("line %d: keymap not found\n", lineno)->ptr;
+	if (! strcmp(s, "keymap"))
+	    ;
+	else if (! strcmp(s, "verbose")) {
+	    s = getWord(&p);
+	    if (*s)
+		verbose = str_to_bool(s, verbose);
+	    continue;
+	} else {		/* error */
+	    emsg = Sprintf("line %d: syntax error '%s'", lineno, s)->ptr;
 	    record_err_message(emsg);
-	    disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE);
+	    if (verbose)
+		disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE);
 	    continue;
 	}
 	s = getQWord(&p);
 	c = getKey(s);
 	if (c < 0) {		/* error */
-	    emsg = Sprintf("line %d: unknown key '%s'\n", lineno, s)->ptr;
+	    emsg = Sprintf("line %d: unknown key '%s'", lineno, s)->ptr;
 	    record_err_message(emsg);
-	    disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE);
+	    if (verbose)
+		disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE);
 	    continue;
 	}
 	s = getWord(&p);
 	f = getFuncList(s, w3mFuncList, w3mNFuncList);
 	if (f < 0) {
-	    emsg = Sprintf("line %d: invalid command '%s'\n", lineno, s)->ptr;
+	    emsg = Sprintf("line %d: invalid command '%s'", lineno, s)->ptr;
 	    record_err_message(emsg);
-	    disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE);
-	    f = FUNCNAME_nulcmd;
+	    if (verbose)
+		disp_message_nsec(emsg, FALSE, 1, TRUE, FALSE);
+	    continue;
 	}
 	if (c & K_ESCD)
-	    EscDKeymap[c ^ K_ESCD] = (f >= 0) ? f : FUNCNAME_nulcmd;
+	    EscDKeymap[c ^ K_ESCD] = f;
 	else if (c & K_ESCB)
-	    EscBKeymap[c ^ K_ESCB] = (f >= 0) ? f : FUNCNAME_nulcmd;
+	    EscBKeymap[c ^ K_ESCB] = f;
 	else if (c & K_ESC)
-	    EscKeymap[c ^ K_ESC] = (f >= 0) ? f : FUNCNAME_nulcmd;
+	    EscKeymap[c ^ K_ESC] = f;
 	else
-	    GlobalKeymap[c] = (f >= 0) ? f : FUNCNAME_nulcmd;
+	    GlobalKeymap[c] = f;
 	s = getQWord(&p);
 	addKeyList(&w3mKeyList, c, s);
     }
diff -urN -x gc w3m-0.2.1/funcname.c w3m-0.2.1-img-1.10/funcname.c
--- w3m-0.2.1/funcname.c	Fri Mar 23 10:49:54 2001
+++ w3m-0.2.1-img-1.10/funcname.c	Thu Jul 26 23:45:55 2001
@@ -11,88 +11,91 @@
 /*9*/ {"DELETE_PREVBUF",deletePrevBuf},
 /*10*/ {"DICT_WORD",dictword},
 /*11*/ {"DICT_WORD_AT",dictwordat},
-/*12*/ {"DOWN",ldown1},
-/*13*/ {"DOWNLOAD",svSrc},
-/*14*/ {"EDIT",editBf},
-/*15*/ {"EDIT_SCREEN",editScr},
-/*16*/ {"END",goLineL},
-/*17*/ {"ESCBMAP",escbmap},
-/*18*/ {"ESCMAP",escmap},
-/*19*/ {"EXEC_SHELL",execsh},
-/*20*/ {"EXIT",quitfm},
-/*21*/ {"EXTERN",extbrz},
-/*22*/ {"EXTERN_LINK",linkbrz},
-/*23*/ {"FRAME",rFrame},
-/*24*/ {"GOTO",goURL},
-/*25*/ {"GOTO_LINE",goLine},
-/*26*/ {"GOTO_LINK",followA},
-/*27*/ {"HELP",ldhelp},
-/*28*/ {"HISTORY",ldHist},
-/*29*/ {"INFO",pginfo},
-/*30*/ {"INIT_MAILCAP",initMailcap},
-/*31*/ {"INTERRUPT",susp},
-/*32*/ {"LEFT",col1L},
-/*33*/ {"LINE_BEGIN",linbeg},
-/*34*/ {"LINE_END",linend},
-/*35*/ {"LINE_INFO",curlno},
-/*36*/ {"LINK_BEGIN",topA},
-/*37*/ {"LINK_END",lastA},
-/*38*/ {"LOAD",ldfile},
-/*39*/ {"MAIN_MENU",mainMn},
-/*40*/ {"MARK",_mark},
-/*41*/ {"MARK_MID",chkNMID},
-/*42*/ {"MARK_URL",chkURL},
-/*43*/ {"MENU",mainMn},
-/*44*/ {"MOUSE",mouse},
-/*45*/ {"MOUSE_TOGGLE",msToggle},
-/*46*/ {"MOVE_DOWN",movD},
-/*47*/ {"MOVE_LEFT",movL},
-/*48*/ {"MOVE_RIGHT",movR},
-/*49*/ {"MOVE_UP",movU},
-/*50*/ {"MSGS",msgs},
-/*51*/ {"NEXT_LINK",nextA},
-/*52*/ {"NEXT_MARK",nextMk},
-/*53*/ {"NEXT_PAGE",pgFore},
-/*54*/ {"NEXT_WORD",movRW},
-/*55*/ {"NOTHING",nulcmd},
-/*56*/ {"NULL",nulcmd},
-/*57*/ {"OPTIONS",ldOpt},
-/*58*/ {"PCMAP",pcmap},
-/*59*/ {"PEEK",curURL},
-/*60*/ {"PEEK_LINK",peekURL},
+/*12*/ {"DISPLAY_IMAGE",dispI},
+/*13*/ {"DOWN",ldown1},
+/*14*/ {"DOWNLOAD",svSrc},
+/*15*/ {"EDIT",editBf},
+/*16*/ {"EDIT_SCREEN",editScr},
+/*17*/ {"END",goLineL},
+/*18*/ {"ESCBMAP",escbmap},
+/*19*/ {"ESCMAP",escmap},
+/*20*/ {"EXEC_SHELL",execsh},
+/*21*/ {"EXIT",quitfm},
+/*22*/ {"EXTERN",extbrz},
+/*23*/ {"EXTERN_LINK",linkbrz},
+/*24*/ {"FRAME",rFrame},
+/*25*/ {"GOTO",goURL},
+/*26*/ {"GOTO_LINE",goLine},
+/*27*/ {"GOTO_LINK",followA},
+/*28*/ {"HELP",ldhelp},
+/*29*/ {"HISTORY",ldHist},
+/*30*/ {"INFO",pginfo},
+/*31*/ {"INIT_MAILCAP",initMailcap},
+/*32*/ {"INTERRUPT",susp},
+/*33*/ {"LEFT",col1L},
+/*34*/ {"LINE_BEGIN",linbeg},
+/*35*/ {"LINE_END",linend},
+/*36*/ {"LINE_INFO",curlno},
+/*37*/ {"LINK_BEGIN",topA},
+/*38*/ {"LINK_END",lastA},
+/*39*/ {"LOAD",ldfile},
+/*40*/ {"MAIN_MENU",mainMn},
+/*41*/ {"MARK",_mark},
+/*42*/ {"MARK_MID",chkNMID},
+/*43*/ {"MARK_URL",chkURL},
+/*44*/ {"MENU",mainMn},
+/*45*/ {"MOUSE",mouse},
+/*46*/ {"MOUSE_TOGGLE",msToggle},
+/*47*/ {"MOVE_DOWN",movD},
+/*48*/ {"MOVE_LEFT",movL},
+/*49*/ {"MOVE_RIGHT",movR},
+/*50*/ {"MOVE_UP",movU},
+/*51*/ {"MSGS",msgs},
+/*52*/ {"NEXT_LINK",nextA},
+/*53*/ {"NEXT_MARK",nextMk},
+/*54*/ {"NEXT_PAGE",pgFore},
+/*55*/ {"NEXT_WORD",movRW},
+/*56*/ {"NOTHING",nulcmd},
+/*57*/ {"NULL",nulcmd},
+/*58*/ {"OPTIONS",ldOpt},
+/*59*/ {"PCMAP",pcmap},
+/*60*/ {"PEEK",curURL},
 /*61*/ {"PEEK_IMG",peekIMG},
-/*62*/ {"PIPE_SHELL",pipesh},
-/*63*/ {"PREV_LINK",prevA},
-/*64*/ {"PREV_MARK",prevMk},
-/*65*/ {"PREV_PAGE",pgBack},
-/*66*/ {"PREV_WORD",movLW},
-/*67*/ {"PRINT",svBuf},
-/*68*/ {"QUIT",qquitfm},
-/*69*/ {"READ_SHELL",readsh},
-/*70*/ {"REDRAW",rdrwSc},
-/*71*/ {"REG_MARK",reMark},
-/*72*/ {"RELOAD",reload},
-/*73*/ {"RIGHT",col1R},
-/*74*/ {"SAVE",svSrc},
-/*75*/ {"SAVE_IMAGE",svI},
-/*76*/ {"SAVE_LINK",svA},
-/*77*/ {"SAVE_SCREEN",svBuf},
-/*78*/ {"SEARCH",srchfor},
-/*79*/ {"SEARCH_BACK",srchbak},
-/*80*/ {"SEARCH_FORE",srchfor},
-/*81*/ {"SEARCH_NEXT",srchnxt},
-/*82*/ {"SEARCH_PREV",srchprv},
-/*83*/ {"SELECT",selBuf},
-/*84*/ {"SHELL",execsh},
-/*85*/ {"SHIFT_LEFT",shiftl},
-/*86*/ {"SHIFT_RIGHT",shiftr},
-/*87*/ {"SOURCE",vwSrc},
-/*88*/ {"SUSPEND",susp},
-/*89*/ {"UP",lup1},
-/*90*/ {"VIEW",vwSrc},
-/*91*/ {"VIEW_BOOKMARK",ldBmark},
-/*92*/ {"VIEW_IMAGE",followI},
-/*93*/ {"WHEREIS",srchfor},
-/*94*/ {"WRAP_TOGGLE",wrapToggle},
+/*62*/ {"PEEK_LINK",peekURL},
+/*63*/ {"PIPE_SHELL",pipesh},
+/*64*/ {"PREV_LINK",prevA},
+/*65*/ {"PREV_MARK",prevMk},
+/*66*/ {"PREV_PAGE",pgBack},
+/*67*/ {"PREV_WORD",movLW},
+/*68*/ {"PRINT",svBuf},
+/*69*/ {"QUIT",qquitfm},
+/*70*/ {"READ_SHELL",readsh},
+/*71*/ {"REDRAW",rdrwSc},
+/*72*/ {"REG_MARK",reMark},
+/*73*/ {"RELOAD",reload},
+/*74*/ {"RIGHT",col1R},
+/*75*/ {"SAVE",svSrc},
+/*76*/ {"SAVE_IMAGE",svI},
+/*77*/ {"SAVE_LINK",svA},
+/*78*/ {"SAVE_SCREEN",svBuf},
+/*79*/ {"SEARCH",srchfor},
+/*80*/ {"SEARCH_BACK",srchbak},
+/*81*/ {"SEARCH_FORE",srchfor},
+/*82*/ {"SEARCH_NEXT",srchnxt},
+/*83*/ {"SEARCH_PREV",srchprv},
+/*84*/ {"SELECT",selBuf},
+/*85*/ {"SHELL",execsh},
+/*86*/ {"SHIFT_LEFT",shiftl},
+/*87*/ {"SHIFT_RIGHT",shiftr},
+/*88*/ {"SOURCE",vwSrc},
+/*89*/ {"STOP_IMAGE",stopI},
+/*90*/ {"SUBMIT",submitForm},
+/*91*/ {"SUSPEND",susp},
+/*92*/ {"UP",lup1},
+/*93*/ {"VIEW",vwSrc},
+/*94*/ {"VIEW_BOOKMARK",ldBmark},
+/*95*/ {"VIEW_IMAGE",followI},
+/*96*/ {"WHEREIS",srchfor},
+/*97*/ {"WRAP_TOGGLE",wrapToggle},
 { NULL, NULL }
 };
diff -urN -x gc w3m-0.2.1/funcname.tab w3m-0.2.1-img-1.10/funcname.tab
--- w3m-0.2.1/funcname.tab	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/funcname.tab	Thu Aug  2 00:43:08 2001
@@ -12,6 +12,7 @@
 DELETE_PREVBUF	deletePrevBuf
 DICT_WORD	dictword
 DICT_WORD_AT	dictwordat
+DISPLAY_IMAGE	dispI
 DOWN		ldown1
 DOWNLOAD	svSrc
 EDIT		editBf
@@ -60,8 +61,8 @@
 OPTIONS		ldOpt
 PCMAP		pcmap
 PEEK		curURL
-PEEK_LINK	peekURL
 PEEK_IMG	peekIMG
+PEEK_LINK	peekURL
 PIPE_SHELL	pipesh
 PREV_LINK	prevA
 PREV_MARK	prevMk
@@ -88,6 +89,8 @@
 SHIFT_LEFT	shiftl
 SHIFT_RIGHT	shiftr
 SOURCE		vwSrc
+STOP_IMAGE	stopI
+SUBMIT		submitForm
 SUSPEND		susp
 UP		lup1
 VIEW		vwSrc
diff -urN -x gc w3m-0.2.1/funcname1.h w3m-0.2.1-img-1.10/funcname1.h
--- w3m-0.2.1/funcname1.h	Fri Mar 23 10:49:54 2001
+++ w3m-0.2.1-img-1.10/funcname1.h	Thu Jul 26 23:45:55 2001
@@ -10,74 +10,77 @@
 #define FUNCNAME_deletePrevBuf 9
 #define FUNCNAME_dictword 10
 #define FUNCNAME_dictwordat 11
-#define FUNCNAME_ldown1 12
-#define FUNCNAME_svSrc 13
-#define FUNCNAME_editBf 14
-#define FUNCNAME_editScr 15
-#define FUNCNAME_goLineL 16
-#define FUNCNAME_escbmap 17
-#define FUNCNAME_escmap 18
-#define FUNCNAME_execsh 19
-#define FUNCNAME_extbrz 21
-#define FUNCNAME_linkbrz 22
-#define FUNCNAME_rFrame 23
-#define FUNCNAME_goURL 24
-#define FUNCNAME_goLine 25
-#define FUNCNAME_followA 26
-#define FUNCNAME_ldhelp 27
-#define FUNCNAME_ldHist 28
-#define FUNCNAME_pginfo 29
-#define FUNCNAME_initMailcap 30
-#define FUNCNAME_susp 31
-#define FUNCNAME_col1L 32
-#define FUNCNAME_linbeg 33
-#define FUNCNAME_linend 34
-#define FUNCNAME_curlno 35
-#define FUNCNAME_topA 36
-#define FUNCNAME_lastA 37
-#define FUNCNAME_ldfile 38
-#define FUNCNAME_mainMn 39
-#define FUNCNAME__mark 40
-#define FUNCNAME_chkNMID 41
-#define FUNCNAME_chkURL 42
-#define FUNCNAME_mouse 44
-#define FUNCNAME_msToggle 45
-#define FUNCNAME_movD 46
-#define FUNCNAME_movL 47
-#define FUNCNAME_movR 48
-#define FUNCNAME_movU 49
-#define FUNCNAME_msgs 50
-#define FUNCNAME_nextA 51
-#define FUNCNAME_nextMk 52
-#define FUNCNAME_pgFore 53
-#define FUNCNAME_movRW 54
-#define FUNCNAME_ldOpt 57
-#define FUNCNAME_pcmap 58
-#define FUNCNAME_curURL 59
-#define FUNCNAME_peekURL 60
+#define FUNCNAME_dispI 12
+#define FUNCNAME_ldown1 13
+#define FUNCNAME_svSrc 14
+#define FUNCNAME_editBf 15
+#define FUNCNAME_editScr 16
+#define FUNCNAME_goLineL 17
+#define FUNCNAME_escbmap 18
+#define FUNCNAME_escmap 19
+#define FUNCNAME_execsh 20
+#define FUNCNAME_extbrz 22
+#define FUNCNAME_linkbrz 23
+#define FUNCNAME_rFrame 24
+#define FUNCNAME_goURL 25
+#define FUNCNAME_goLine 26
+#define FUNCNAME_followA 27
+#define FUNCNAME_ldhelp 28
+#define FUNCNAME_ldHist 29
+#define FUNCNAME_pginfo 30
+#define FUNCNAME_initMailcap 31
+#define FUNCNAME_susp 32
+#define FUNCNAME_col1L 33
+#define FUNCNAME_linbeg 34
+#define FUNCNAME_linend 35
+#define FUNCNAME_curlno 36
+#define FUNCNAME_topA 37
+#define FUNCNAME_lastA 38
+#define FUNCNAME_ldfile 39
+#define FUNCNAME_mainMn 40
+#define FUNCNAME__mark 41
+#define FUNCNAME_chkNMID 42
+#define FUNCNAME_chkURL 43
+#define FUNCNAME_mouse 45
+#define FUNCNAME_msToggle 46
+#define FUNCNAME_movD 47
+#define FUNCNAME_movL 48
+#define FUNCNAME_movR 49
+#define FUNCNAME_movU 50
+#define FUNCNAME_msgs 51
+#define FUNCNAME_nextA 52
+#define FUNCNAME_nextMk 53
+#define FUNCNAME_pgFore 54
+#define FUNCNAME_movRW 55
+#define FUNCNAME_ldOpt 58
+#define FUNCNAME_pcmap 59
+#define FUNCNAME_curURL 60
 #define FUNCNAME_peekIMG 61
-#define FUNCNAME_pipesh 62
-#define FUNCNAME_prevA 63
-#define FUNCNAME_prevMk 64
-#define FUNCNAME_pgBack 65
-#define FUNCNAME_movLW 66
-#define FUNCNAME_svBuf 67
-#define FUNCNAME_qquitfm 68
-#define FUNCNAME_readsh 69
-#define FUNCNAME_rdrwSc 70
-#define FUNCNAME_reMark 71
-#define FUNCNAME_reload 72
-#define FUNCNAME_col1R 73
-#define FUNCNAME_svI 75
-#define FUNCNAME_svA 76
-#define FUNCNAME_srchfor 78
-#define FUNCNAME_srchbak 79
-#define FUNCNAME_srchnxt 81
-#define FUNCNAME_srchprv 82
-#define FUNCNAME_selBuf 83
-#define FUNCNAME_shiftl 85
-#define FUNCNAME_shiftr 86
-#define FUNCNAME_vwSrc 87
-#define FUNCNAME_lup1 89
-#define FUNCNAME_followI 92
-#define FUNCNAME_wrapToggle 94
+#define FUNCNAME_peekURL 62
+#define FUNCNAME_pipesh 63
+#define FUNCNAME_prevA 64
+#define FUNCNAME_prevMk 65
+#define FUNCNAME_pgBack 66
+#define FUNCNAME_movLW 67
+#define FUNCNAME_svBuf 68
+#define FUNCNAME_qquitfm 69
+#define FUNCNAME_readsh 70
+#define FUNCNAME_rdrwSc 71
+#define FUNCNAME_reMark 72
+#define FUNCNAME_reload 73
+#define FUNCNAME_col1R 74
+#define FUNCNAME_svI 76
+#define FUNCNAME_svA 77
+#define FUNCNAME_srchfor 79
+#define FUNCNAME_srchbak 80
+#define FUNCNAME_srchnxt 82
+#define FUNCNAME_srchprv 83
+#define FUNCNAME_selBuf 84
+#define FUNCNAME_shiftl 86
+#define FUNCNAME_shiftr 87
+#define FUNCNAME_vwSrc 88
+#define FUNCNAME_stopI 89
+#define FUNCNAME_submitForm 90
+#define FUNCNAME_lup1 92
+#define FUNCNAME_followI 95
+#define FUNCNAME_wrapToggle 97
diff -urN -x gc w3m-0.2.1/funcname2.h w3m-0.2.1-img-1.10/funcname2.h
--- w3m-0.2.1/funcname2.h	Fri Mar 23 10:49:54 2001
+++ w3m-0.2.1-img-1.10/funcname2.h	Thu Jul 26 23:45:55 2001
@@ -10,74 +10,77 @@
 #define deletePrevBuf 9
 #define dictword 10
 #define dictwordat 11
-#define ldown1 12
-#define svSrc 13
-#define editBf 14
-#define editScr 15
-#define goLineL 16
-#define escbmap 17
-#define escmap 18
-#define execsh 19
-#define extbrz 21
-#define linkbrz 22
-#define rFrame 23
-#define goURL 24
-#define goLine 25
-#define followA 26
-#define ldhelp 27
-#define ldHist 28
-#define pginfo 29
-#define initMailcap 30
-#define susp 31
-#define col1L 32
-#define linbeg 33
-#define linend 34
-#define curlno 35
-#define topA 36
-#define lastA 37
-#define ldfile 38
-#define mainMn 39
-#define _mark 40
-#define chkNMID 41
-#define chkURL 42
-#define mouse 44
-#define msToggle 45
-#define movD 46
-#define movL 47
-#define movR 48
-#define movU 49
-#define msgs 50
-#define nextA 51
-#define nextMk 52
-#define pgFore 53
-#define movRW 54
-#define ldOpt 57
-#define pcmap 58
-#define curURL 59
-#define peekURL 60
+#define dispI 12
+#define ldown1 13
+#define svSrc 14
+#define editBf 15
+#define editScr 16
+#define goLineL 17
+#define escbmap 18
+#define escmap 19
+#define execsh 20
+#define extbrz 22
+#define linkbrz 23
+#define rFrame 24
+#define goURL 25
+#define goLine 26
+#define followA 27
+#define ldhelp 28
+#define ldHist 29
+#define pginfo 30
+#define initMailcap 31
+#define susp 32
+#define col1L 33
+#define linbeg 34
+#define linend 35
+#define curlno 36
+#define topA 37
+#define lastA 38
+#define ldfile 39
+#define mainMn 40
+#define _mark 41
+#define chkNMID 42
+#define chkURL 43
+#define mouse 45
+#define msToggle 46
+#define movD 47
+#define movL 48
+#define movR 49
+#define movU 50
+#define msgs 51
+#define nextA 52
+#define nextMk 53
+#define pgFore 54
+#define movRW 55
+#define ldOpt 58
+#define pcmap 59
+#define curURL 60
 #define peekIMG 61
-#define pipesh 62
-#define prevA 63
-#define prevMk 64
-#define pgBack 65
-#define movLW 66
-#define svBuf 67
-#define qquitfm 68
-#define readsh 69
-#define rdrwSc 70
-#define reMark 71
-#define reload 72
-#define col1R 73
-#define svI 75
-#define svA 76
-#define srchfor 78
-#define srchbak 79
-#define srchnxt 81
-#define srchprv 82
-#define selBuf 83
-#define shiftl 85
-#define shiftr 86
-#define vwSrc 87
-#define lup1 89
-#define followI 92
-#define wrapToggle 94
+#define peekURL 62
+#define pipesh 63
+#define prevA 64
+#define prevMk 65
+#define pgBack 66
+#define movLW 67
+#define svBuf 68
+#define qquitfm 69
+#define readsh 70
+#define rdrwSc 71
+#define reMark 72
+#define reload 73
+#define col1R 74
+#define svI 76
+#define svA 77
+#define srchfor 79
+#define srchbak 80
+#define srchnxt 82
+#define srchprv 83
+#define selBuf 84
+#define shiftl 86
+#define shiftr 87
+#define vwSrc 88
+#define stopI 89
+#define submitForm 90
+#define lup1 92
+#define followI 95
+#define wrapToggle 97
diff -urN -x gc w3m-0.2.1/html.c w3m-0.2.1-img-1.10/html.c
--- w3m-0.2.1/html.c	Fri Mar 23 10:49:54 2001
+++ w3m-0.2.1-img-1.10/html.c	Thu Aug  2 00:43:07 2001
@@ -20,8 +20,8 @@
 unsigned char ALST_PRE[] = {ATTR_FOR_TABLE,ATTR_CORE};
 #define MAXA_PRE	MAXA_CORE + 1
 unsigned char ALST_IMG[] =
-{ATTR_SRC,ATTR_ALT,ATTR_WIDTH,ATTR_HEIGHT,ATTR_USEMAP,ATTR_CORE};
-#define MAXA_IMG	MAXA_CORE + 5
+{ATTR_SRC,ATTR_ALT,ATTR_WIDTH,ATTR_HEIGHT,ATTR_ALIGN,ATTR_USEMAP,ATTR_ISMAP,ATTR_CORE};
+#define MAXA_IMG	MAXA_CORE + 7
 unsigned char ALST_TABLE[] =
 {ATTR_BORDER,ATTR_WIDTH,ATTR_HBORDER,ATTR_CELLSPACING,ATTR_CELLPADDING,ATTR_VSPACE,ATTR_CORE};
 #define MAXA_TABLE	MAXA_CORE + 6
@@ -32,11 +32,11 @@
 unsigned char ALST_FRAMESET[] = {ATTR_COLS,ATTR_ROWS,ATTR_CORE};
 #define MAXA_FRAMESET	MAXA_CORE + 2
 unsigned char ALST_FORM[] =
-{ATTR_METHOD,ATTR_ACTION,ATTR_CHARSET,ATTR_ACCEPT_CHARSET,ATTR_ENCTYPE,ATTR_TARGET,ATTR_CORE};
-#define MAXA_FORM	MAXA_CORE + 6
+{ATTR_METHOD,ATTR_ACTION,ATTR_CHARSET,ATTR_ACCEPT_CHARSET,ATTR_ENCTYPE,ATTR_TARGET,ATTR_NAME,ATTR_CORE};
+#define MAXA_FORM	MAXA_CORE + 7
 unsigned char ALST_INPUT[] =
-{ATTR_TYPE,ATTR_VALUE,ATTR_NAME,ATTR_CHECKED,ATTR_ACCEPT,ATTR_SIZE,ATTR_MAXLENGTH,ATTR_ALT,ATTR_CORE};
-#define MAXA_INPUT	MAXA_CORE + 8
+{ATTR_TYPE,ATTR_VALUE,ATTR_NAME,ATTR_CHECKED,ATTR_ACCEPT,ATTR_SIZE,ATTR_MAXLENGTH,ATTR_ALT,ATTR_SRC,ATTR_WIDTH,ATTR_HEIGHT,ATTR_CORE};
+#define MAXA_INPUT	MAXA_CORE + 11
 unsigned char ALST_TEXTAREA[] = {ATTR_COLS,ATTR_ROWS,ATTR_NAME,ATTR_CORE};
 #define MAXA_TEXTAREA	MAXA_CORE + 3
 unsigned char ALST_SELECT[] = {ATTR_NAME,ATTR_MULTIPLE,ATTR_CORE};
@@ -47,8 +47,8 @@
 #define MAXA_ISINDEX	MAXA_CORE + 2
 unsigned char ALST_MAP[] = {ATTR_NAME,ATTR_CORE};
 #define MAXA_MAP	MAXA_CORE + 1
-unsigned char ALST_AREA[] = {ATTR_HREF,ATTR_ALT,ATTR_CORE};
-#define MAXA_AREA	MAXA_CORE + 2
+unsigned char ALST_AREA[] = {ATTR_HREF,ATTR_ALT,ATTR_SHAPE,ATTR_COORDS,ATTR_CORE};
+#define MAXA_AREA	MAXA_CORE + 4
 unsigned char ALST_BASE[] = {ATTR_HREF,ATTR_TARGET,ATTR_CORE};
 #define MAXA_BASE	MAXA_CORE + 2
 unsigned char ALST_BODY[] = {ATTR_BACKGROUND,ATTR_CORE};
@@ -72,8 +72,8 @@
 unsigned char ALST_INPUT_ALT[] =
 {ATTR_HSEQ,ATTR_FID,ATTR_NO_EFFECT,ATTR_TYPE,ATTR_NAME,ATTR_VALUE,ATTR_CHECKED,ATTR_ACCEPT,ATTR_SIZE,ATTR_MAXLENGTH,ATTR_TEXTAREANUMBER,ATTR_SELECTNUMBER,ATTR_ROWS};
 #define MAXA_INPUT_ALT	13
-unsigned char ALST_IMG_ALT[] = {ATTR_SRC};
-#define MAXA_IMG_ALT	1
+unsigned char ALST_IMG_ALT[] = {ATTR_SRC,ATTR_WIDTH,ATTR_HEIGHT,ATTR_USEMAP,ATTR_ISMAP,ATTR_HSEQ,ATTR_XOFFSET,ATTR_YOFFSET,ATTR_TOP_MARGIN,ATTR_BOTTOM_MARGIN};
+#define MAXA_IMG_ALT	10
 unsigned char ALST_NOP[] = {ATTR_CORE};
 #define MAXA_NOP	MAXA_CORE
 
@@ -258,18 +258,18 @@
     {"selected"      ,	VTYPE_NONE,    0},        /* 41 ATTR_SELECTED       */
     {"label"         ,	VTYPE_STR,     0},        /* 42 ATTR_LABEL          */
                                        		   
-    {NULL            ,	VTYPE_NONE,    0},        /* 43 Undefined           */
-    {NULL            ,	VTYPE_NONE,    0},        /* 44 Undefined           */
-    {NULL            ,	VTYPE_NONE,    0},        /* 45 Undefined           */
+    {"shape"         ,	VTYPE_STR,     0},        /* 43 ATTR_SHAPE          */
+    {"coords"        ,	VTYPE_STR,     0},        /* 44 ATTR_COORDS         */
+    {"ismap"         ,	VTYPE_NONE,    0},        /* 45 ATTR_ISMAP          */
     {NULL            ,	VTYPE_NONE,    0},        /* 46 Undefined           */
     {NULL            ,	VTYPE_NONE,    0},        /* 47 Undefined           */
     {NULL            ,	VTYPE_NONE,    0},        /* 48 Undefined           */
-    {NULL            ,	VTYPE_NONE,    0},        /* 49 Undefined           */
-    {NULL            ,	VTYPE_NONE,    0},        /* 50 Undefined           */
-    {NULL            ,	VTYPE_NONE,    0},        /* 51 Undefined           */
-    {NULL            ,	VTYPE_NONE,    0},        /* 52 Undefined           */
                                                            		   
     /* Internal attribute */                               		   
+    {"xoffset"       ,	VTYPE_NUMBER,  AFLG_INT}, /* 49 ATTR_XOFFSET        */
+    {"yoffset"       ,	VTYPE_NUMBER,  AFLG_INT}, /* 50 ATTR_YOFFSET        */
+    {"top_margin"    ,	VTYPE_NUMBER,  AFLG_INT}, /* 51 ATTR_TOP_MARGIN     */
+    {"bottom_margin" ,	VTYPE_NUMBER,  AFLG_INT}, /* 52 ATTR_BOTTOM_MARGIN  */
     {"tid"           ,	VTYPE_NUMBER,  AFLG_INT}, /* 53 ATTR_TID            */
     {"fid"           ,	VTYPE_NUMBER,  AFLG_INT}, /* 54 ATTR_FID            */
     {"for_table"     ,	VTYPE_NONE,    AFLG_INT}, /* 55 ATTR_FOR_TABLE      */
diff -urN -x gc w3m-0.2.1/html.h w3m-0.2.1-img-1.10/html.h
--- w3m-0.2.1/html.h	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/html.h	Thu Aug  2 00:43:07 2001
@@ -242,8 +242,15 @@
 #define ATTR_START		40
 #define ATTR_SELECTED		41
 #define ATTR_LABEL		42
+#define ATTR_SHAPE		43
+#define ATTR_COORDS		44
+#define ATTR_ISMAP		45
 
 /* Internal attribute */
+#define ATTR_XOFFSET		49
+#define ATTR_YOFFSET		50
+#define ATTR_TOP_MARGIN		51
+#define ATTR_BOTTOM_MARGIN	52
 #define ATTR_TID		53
 #define ATTR_FID		54
 #define ATTR_FOR_TABLE		55
@@ -290,6 +297,12 @@
 #define VTYPE_METHOD    8
 #define VTYPE_MLENGTH   9
 #define VTYPE_TYPE      10
+
+#define SHAPE_UNKNOWN	0
+#define SHAPE_DEFAULT	1
+#define SHAPE_RECT	2
+#define SHAPE_CIRCLE	3
+#define SHAPE_POLY	4
 
 extern TagInfo TagMAP[];
 extern TagAttrInfo AttrMAP[];
diff -urN -x gc w3m-0.2.1/main.c w3m-0.2.1-img-1.10/main.c
--- w3m-0.2.1/main.c	Fri Mar 23 11:14:58 2001
+++ w3m-0.2.1-img-1.10/main.c	Thu Aug  2 00:43:07 2001
@@ -64,7 +64,11 @@
 int prec_num = 0;
 int prev_key = -1;
 int on_target = 1;
+#ifdef USE_IMAGE
+int in_getch = FALSE;
+#endif
 
+static void _followForm(int);
 static void _goLine(char*);
 #define PREC_NUM (prec_num ? prec_num : 1)
 #define PREC_LIMIT 10000
@@ -105,6 +109,9 @@
     fprintf(f, "    -dump            dump formatted page into stdout\n");
     fprintf(f, "    -cols width      specify column width (used with -dump)\n");
     fprintf(f, "    -ppc count       specify the number of pixels per character (4.0...32.0)\n");
+#ifdef USE_IMAGE
+    fprintf(f, "    -ppl count       specify the number of pixels per line (4.0...64.0)\n");
+#endif
     fprintf(f, "    -dump_source     dump page source into stdout\n");
     fprintf(f, "    -dump_head       dump response of HEAD request into stdout\n");
     fprintf(f, "    +<num>           goto <num> line\n");
@@ -200,6 +207,18 @@
     int load_argc = 0;
     int load_bookmark = FALSE;
     int visual_start = FALSE;
+#if defined(USE_IMAGE) || defined(SIGWINCH)
+    sigset_t block_sigset;
+
+    sigemptyset(&block_sigset);
+#ifdef USE_IMAGE
+    sigaddset(&block_sigset, SIGUSR1);
+#endif
+#ifdef SIGWINCH
+    sigaddset(&block_sigset, SIGWINCH);
+#endif
+    sigprocmask(SIG_BLOCK, &block_sigset, NULL);
+#endif
 
 #ifndef SYS_ERRLIST
     prepare_sys_errlist();
@@ -427,6 +446,17 @@
 		    ppc <= MAXIMUM_PIXEL_PER_CHAR)
 		    pixel_per_char = ppc;
 	    }
+#ifdef USE_IMAGE
+	    else if (!strcmp("-ppl", argv[i])) {
+		double ppc;
+		if (++i >= argc)
+		    usage();
+		ppc = atof(argv[i]);
+		if (ppc >= MINIMUM_PIXEL_PER_CHAR &&
+		    ppc <= MAXIMUM_PIXEL_PER_CHAR * 2)
+		    pixel_per_line = ppc;
+	    }
+#endif
 	    else if (!strcmp("-num", argv[i]))
 		showLineNum = TRUE;
 	    else if (!strcmp("-no-proxy", argv[i]))
@@ -710,7 +740,21 @@
 	if (use_mouse)
 	    mouse_active();
 #endif				/* MOUSE */
+#if defined(USE_IMAGE) || defined(SIGWINCH)
+	sigprocmask(SIG_UNBLOCK, &block_sigset, NULL);
+#endif
+#ifdef USE_IMAGE
+	if (activeImage && displayImage)
+	    loadImage(IMG_FLAG_START);
+	in_getch = TRUE;
+#endif
 	c = getch();
+#ifdef USE_IMAGE
+	in_getch = FALSE;
+#endif
+#if defined(USE_IMAGE) || defined(SIGWINCH)
+	sigprocmask(SIG_BLOCK, &block_sigset, NULL);
+#endif
 #ifdef MOUSE
 	if (use_mouse)
 	    mouse_inactive();
@@ -870,6 +914,9 @@
 {
     Buffer *b;
 
+#ifdef USE_IMAGE
+    deleteImage(Currentbuf);
+#endif
     if (clear_buffer)
 	tmpClearBuffer(Currentbuf);
     if (Firstbuf == Currentbuf) {
@@ -1572,6 +1619,12 @@
 void
 quitfm(void)
 {
+#ifdef USE_IMAGE
+    if (fmInitialized && activeImage) {
+	resetImage();
+	termImage();
+    }
+#endif
     fmTerm();
     deleteFiles();
 #ifdef USE_COOKIE
@@ -1621,8 +1674,13 @@
 	}
     } while (!ok);
 
-    if (clear_buffer) {
-	for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer)
+    for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer) {
+	if (buf == Currentbuf)
+	    continue;
+#ifdef USE_IMAGE
+	deleteImage(buf);
+#endif
+	if (clear_buffer)
 	    tmpClearBuffer(buf);
     }
     displayBuffer(Currentbuf, B_FORCE_REDRAW);
@@ -1977,8 +2035,8 @@
 #endif				/* USE_MARK */
 
 #ifdef JP_CHARSET
-static char *
-cURLcode(char *url, Buffer * buf)
+char *
+cURLcode(char *url, char code)
 {
     char *p;
     Str s;
@@ -1986,14 +2044,12 @@
     for (p = url; *p; p++) {
 	if (!IS_ASCII(*p)) {
 	    /* URL contains Kanji... uugh */
-	    s = conv(url, InnerCode, buf->document_code);
+	    s = conv(url, InnerCode, code);
 	    return s->ptr;
 	}
     }
     return url;
 }
-#else				/* not JP_CHARSET */
-#define cURLcode(url,buf) (url)
 #endif				/* not JP_CHARSET */
 
 static Buffer *
@@ -2022,7 +2078,7 @@
 	referer = NO_REFERER;
     if (referer == NULL)
 	referer = parsedURL2Str(&Currentbuf->currentURL)->ptr;
-    buf = loadGeneralFile(cURLcode(url, Currentbuf),
+    buf = loadGeneralFile(cURLcode(url, Currentbuf->document_code),
 			  baseURL(Currentbuf),
 			  referer,
 			  flag,
@@ -2136,14 +2192,29 @@
     Line *l;
     Anchor *a;
     ParsedURL u;
+#ifdef USE_IMAGE
+    int x = 0, y = 0, map = 0;
+#endif
+    char *url;
 
     if (Currentbuf->firstLine == NULL)
 	return;
     l = Currentbuf->currentLine;
 
+#ifdef USE_IMAGE
+    a = retrieveCurrentImg(Currentbuf);
+    if (a && a->image && a->image->map) {
+	_followForm(FALSE);
+	return;
+    }
+    if (a && a->image && a->image->ismap) {
+	getMapXY(Currentbuf, retrieveCurrentImg(Currentbuf), &x, &y);
+	map = 1;
+    }
+#endif
     a = retrieveCurrentAnchor(Currentbuf);
     if (a == NULL) {
-	followForm();
+	_followForm(FALSE);
 	return;
     }
     if (*a->url == '#') {	/* index within this buffer */
@@ -2187,7 +2258,12 @@
 	return;
     }
 #endif				/* USE_NNTP */
-    loadLink(a->url, a->target, a->referer, NULL);
+    url = a->url;
+#ifdef USE_IMAGE
+    if (map)
+	url = Sprintf("%s?%d,%d", a->url, x, y)->ptr;
+#endif
+    loadLink(url, a->target, a->referer, NULL);
     displayBuffer(Currentbuf, B_NORMAL);
 }
 
@@ -2217,7 +2293,8 @@
 	return;
     message(Sprintf("loading %s\n", a->url)->ptr, 0, 0);
     refresh();
-    buf = loadGeneralFile(cURLcode(a->url, Currentbuf), baseURL(Currentbuf), NULL, 0, NULL);
+    buf = loadGeneralFile(cURLcode(a->url, Currentbuf->document_code),
+	baseURL(Currentbuf), NULL, 0, NULL);
     if (buf == NULL) {
 	char *emsg = Sprintf("Can't load %s\n", a->url)->ptr;
 	disp_err_message(emsg, FALSE);
@@ -2351,12 +2428,18 @@
 	}
 	if (multipart) {
 	    if (f2->type == FORM_INPUT_IMAGE) {
+		int x = 0, y = 0;
+#ifdef USE_IMAGE
+		getMapXY(Currentbuf, retrieveCurrentImg(Currentbuf), &x, &y);
+#endif
 		*query = Strdup(f2->name);
 		Strcat_charp(*query, ".x");
-		form_write_data(body, fi->parent->boundary, (*query)->ptr, "1");
+		form_write_data(body, fi->parent->boundary, (*query)->ptr,
+			Sprintf("%d", x)->ptr);
 		*query = Strdup(f2->name);
 		Strcat_charp(*query, ".y");
-		form_write_data(body, fi->parent->boundary, (*query)->ptr, "1");
+		form_write_data(body, fi->parent->boundary, (*query)->ptr,
+			Sprintf("%d", y)->ptr);
 	    }
 	    else if (f2->name && f2->name->length > 0) {
 		/* not IMAGE */
@@ -2379,10 +2462,14 @@
 	else {
 	    /* not multipart */
 	    if (f2->type == FORM_INPUT_IMAGE) {
+		int x = 0, y = 0;
+#ifdef USE_IMAGE
+		getMapXY(Currentbuf, retrieveCurrentImg(Currentbuf), &x, &y);
+#endif
 		Strcat(*query, f2->name);
-		Strcat_charp(*query, ".x=1&");
+		Strcat(*query, Sprintf(".x=%d&", x));
 		Strcat(*query, f2->name);
-		Strcat_charp(*query, ".y=1");
+		Strcat(*query, Sprintf(".y=%d", y));
 	    }
 	    else {
 		/* not IMAGE */
@@ -2426,10 +2513,23 @@
     }
 }
 
+/* submit form */
+void
+submitForm(void)
+{
+  _followForm(TRUE);
+}
+
 /* process form */
 void
 followForm(void)
 {
+  _followForm(FALSE);
+}
+
+static void
+_followForm(int submit)
+{
     Line *l;
     Anchor *a;
     char *p;
@@ -2447,6 +2547,8 @@
     fi = (FormItemList *) a->url;
     switch (fi->type) {
     case FORM_INPUT_TEXT:
+	if (submit)
+	    goto do_submit;
 	p = inputStrHist("TEXT:", fi->value ? fi->value->ptr : NULL, TextHist);
 	if (p == NULL)
 	    return;
@@ -2456,6 +2558,8 @@
 	    goto do_submit;
 	break;
     case FORM_INPUT_FILE:
+	if (submit)
+	    goto do_submit;
 	p = inputFilenameHist("Filename:", fi->value ? fi->value->ptr : NULL, NULL);
 	if (p == NULL)
 	    return;
@@ -2465,6 +2569,8 @@
 	    goto do_submit;
 	break;
     case FORM_INPUT_PASSWORD:
+	if (submit)
+	    goto do_submit;
 	p = inputLine("TEXT:", fi->value ? fi->value->ptr : NULL, IN_PASSWORD);
 	if (p == NULL)
 	    return;
@@ -2474,6 +2580,8 @@
 	    goto do_submit;
 	break;
     case FORM_TEXTAREA:
+	if (submit)
+	    goto do_submit;
 	if (fi->rows == 1) {
 	    p = inputStrHist("TEXT:", fi->value ? fi->value->ptr : NULL, TextHist);
 	    if (p == NULL)
@@ -2485,18 +2593,27 @@
 	formUpdateBuffer(a, Currentbuf, fi);
 	break;
     case FORM_INPUT_RADIO:
+	if (submit)
+	    goto do_submit;
 	form_recheck_radio(fi, Currentbuf, do_update_form_radio);
 	break;
     case FORM_INPUT_CHECKBOX:
+	if (submit)
+	    goto do_submit;
 	fi->checked = !fi->checked;
 	formUpdateBuffer(a, Currentbuf, fi);
 	break;
 #ifdef MENU_SELECT
     case FORM_SELECT:
-	formChooseOptionByMenu(fi,
-		    Currentbuf->cursorX - Currentbuf->pos + a->start.pos,
-			       Currentbuf->cursorY);
+	if (submit)
+	    goto do_submit;
+	if (! formChooseOptionByMenu(fi,
+		Currentbuf->cursorX - Currentbuf->pos + a->start.pos,
+		Currentbuf->cursorY))
+	    break;
 	formUpdateBuffer(a, Currentbuf, fi);
+	if (fi->parent->nitems == 1)
+	    goto do_submit;
 	break;
 #endif				/* MENU_SELECT */
     case FORM_INPUT_IMAGE:
@@ -2554,12 +2671,15 @@
     case FORM_INPUT_RESET:
 	for (f2 = fi->parent->item; f2; f2 = f2->next) {
 	    if (f2->name && f2->value &&
-		f2->type != FORM_INPUT_RADIO &&
-		f2->type != FORM_INPUT_CHECKBOX &&
 		f2->type != FORM_INPUT_SUBMIT &&
 		f2->type != FORM_INPUT_HIDDEN &&
 		f2->type != FORM_INPUT_RESET) {
-		f2->value = Strnew();
+		f2->value = f2->init_value;
+		f2->checked = f2->init_checked;
+#ifdef MENU_SELECT
+		f2->label = f2->init_label;
+		f2->selected = f2->init_selected;
+#endif				/* MENU_SELECT */
 		formUpdateBuffer(&Currentbuf->formitem->anchors[f2->anchor_num], Currentbuf, f2);
 	    }
 	}
@@ -2965,6 +3085,7 @@
     }
     parseURL2(url, &p_url, NULL);
     pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);
+    url = cURLcode(url, Currentbuf->document_code);
     cmd_loadURL(url, baseURL(Currentbuf));
 }
 
@@ -3059,11 +3180,15 @@
     ParsedURL p_url;
 
     a = retrieveCurrentImg(Currentbuf);
+/*
     if (a != NULL)
 	x = Currentbuf->cursorX - Currentbuf->pos + a->start.pos;
     else
 	x = Currentbuf->cursorX;
-    url = follow_map_menu(Currentbuf, arg, x, Currentbuf->cursorY + 2);
+    url = follow_map_menu(Currentbuf, arg, a, x, Currentbuf->cursorY + 2);
+*/
+    url = follow_map_menu(Currentbuf, arg, a, Currentbuf->cursorX,
+	Currentbuf->cursorY);
     if (url == NULL || *url == '\0')
 	return;
     if (*url == '#') {
@@ -3072,6 +3197,7 @@
     }
     parseURL2(url, &p_url, baseURL(Currentbuf));
     pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);
+    url = cURLcode(url, Currentbuf->document_code);
     cmd_loadURL(url, baseURL(Currentbuf));
 #else
     Buffer *buf;
@@ -3662,6 +3788,32 @@
 
     disp_message(tmp->ptr, FALSE);
 }
+
+#ifdef USE_IMAGE
+void
+dispI(void)
+{
+    if (! activeImage)
+	return;
+    if (! (Currentbuf->type && !strcmp(Currentbuf->type, "text/html")))
+	return;
+    if (! displayImage || Currentbuf->image_flag == IMG_FLAG_SKIP) {
+	displayImage = TRUE;
+	Currentbuf->image_flag = IMG_FLAG_AUTO;
+	Currentbuf->need_reshape = TRUE;
+	displayBuffer(Currentbuf, B_REDRAW_IMAGE);
+    } else {
+	displayBuffer(Currentbuf, B_NORMAL);
+    }
+}
+
+void
+stopI(void)
+{
+    Currentbuf->image_flag = IMG_FLAG_SKIP;
+    displayBuffer(Currentbuf, B_NORMAL);
+}
+#endif
 
 #ifdef MOUSE
 /* Addition:mouse event */
diff -urN -x gc w3m-0.2.1/map.c w3m-0.2.1-img-1.10/map.c
--- w3m-0.2.1/map.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/map.c	Thu Aug  2 00:43:07 2001
@@ -2,16 +2,66 @@
  * client-side image maps
  */
 #include "fm.h"
+#include <math.h>
 
 #ifdef MENU_MAP
+#ifdef USE_IMAGE
+static int
+inMapArea(MapArea *a, int x, int y)
+{
+    int i;
+    double r1, r2, s, c, t;
+
+    if (! a)
+	return FALSE;
+    switch (a->shape) {
+    case SHAPE_RECT:
+	if (x >= a->coords[0] && y >= a->coords[1] &&
+	    x <= a->coords[2] && y <= a->coords[3])
+	    return TRUE;
+	break;
+    case SHAPE_CIRCLE:
+	if (  (x - a->coords[0]) * (x - a->coords[0])  
+	    + (y - a->coords[1]) * (y - a->coords[1])
+	    <= a->coords[2] * a->coords[2])
+	    return TRUE;
+	break;
+    case SHAPE_POLY:
+	for (t = 0, i = 0; i < a->ncoords; i += 2) {
+	   r1 = sqrt((double)(x - a->coords[i])   * (x - a->coords[i])
+		   + (double)(y - a->coords[i+1]) * (y - a->coords[i+1]));
+	   r2 = sqrt((double)(x - a->coords[i+2]) * (x - a->coords[i+2])
+		   + (double)(y - a->coords[i+3]) * (y - a->coords[i+3]));
+	   if (r1 == 0 || r2 == 0)
+		return TRUE;
+	   s = ((double)(x - a->coords[i])   * (y - a->coords[i+3])
+	      - (double)(x - a->coords[i+2]) * (y - a->coords[i+1])) / r1 / r2;
+	   c = ((double)(x - a->coords[i])   * (x - a->coords[i+2])
+	      + (double)(y - a->coords[i+1]) * (y - a->coords[i+3])) / r1 / r2;
+	   t += atan2(s, c);
+	}
+	if (fabs(t) > 2 * 3.14)
+	    return TRUE;
+	break;
+    case SHAPE_DEFAULT:
+	return TRUE;
+    default:
+	break;
+    }
+    return FALSE;
+}
+#endif
+
 char *
-follow_map_menu(Buffer * buf, struct parsed_tagarg *arg, int x, int y)
+follow_map_menu(Buffer * buf, struct parsed_tagarg *arg, Anchor *a_img, int x, int y)
 {
     MapList *ml;
+    ListItem *al;
+    MapArea *a;
     char *name;
-    TextListItem *t, *s;
-    int i, n, selected = -1;
+    int i, n, selected = -1, initial;
     char **label;
+    int px, py, map = 0;
 
     name = tag_get_value(arg, "link");
     if (name == NULL)
@@ -21,24 +71,47 @@
 	if (!Strcmp_charp(ml->name, name))
 	    break;
     }
-    if (ml == NULL)
+    if (ml == NULL || ml->area == NULL)
 	return NULL;
 
-    for (n = 0, t = ml->urls->first; t != NULL; n++, t = t->next);
+    n = ml->area->nitem;
     if (n == 0)
 	return NULL;
     label = New_N(char *, n + 1);
-    for (i = 0, t = ml->urls->first, s = ml->alts->first; t != NULL;
-	i++, t = t->next, s = s->next)
-	label[i] = *s->ptr ? s->ptr : t->ptr;
+#ifdef USE_IMAGE
+    if (getMapXY(buf, a_img, &px, &py))
+	map = 1;
+#endif
+    initial = -n;
+    for (i = 0, al = ml->area->first; al != NULL; i++, al = al->next) {
+	a = (MapArea *)al->ptr;
+	if (a) {
+	    label[i] = *a->alt ? a->alt : a->url;
+#ifdef USE_IMAGE
+	    if (initial < 0 && map && inMapArea(a, px, py)) {
+		if (a->shape == SHAPE_DEFAULT) {
+		    if (initial == -n)
+			initial = - i;
+		} else
+		    initial = i;
+	    }
+#endif
+	} else
+	    label[i] = "";
+    }
     label[n] = NULL;
+    if (initial == -n)
+	initial = 0;
+    else if (initial < 0)
+	initial *= -1;
 
-    optionMenu(x, y, label, &selected, 0, NULL);
+    optionMenu(x, y, label, &selected, initial, NULL);
 
     if (selected >= 0) {
-	for (i = 0, t = ml->urls->first; t != NULL; i++, t = t->next)
-	    if (i == selected)
-		return t->ptr;
+	for (i = 0, al = ml->area->first; al != NULL; i++, al = al->next) {
+	    if (al->ptr && i == selected)
+		return ((MapArea *)al->ptr)->url;
+	}
     }
     return NULL;
 }
@@ -52,8 +125,9 @@
 {
     Str mappage;
     MapList *ml;
+    ListItem *al;
+    MapArea *a;
     char *name;
-    TextListItem *t, *s;
     ParsedURL pu;
 
     name = tag_get_value(arg, "link");
@@ -68,15 +142,17 @@
 	return NULL;
 
     mappage = Strnew_charp(map1);
-    for (t = ml->urls->first, s = ml->alts->first; t != NULL;
-	t = t->next, s = s->next) {
-	parseURL2(t->ptr, &pu, baseURL(buf));
+    for (al = ml->area->first; al != NULL; al = al->next) {
+	a = (MapArea *)al->ptr;
+	if (! a)
+	    continue;
+	parseURL2(a->url, &pu, baseURL(buf));
 	Strcat_charp(mappage, "<a href=\"");
 	Strcat_charp(mappage, htmlquote_str(parsedURL2Str(&pu)->ptr));
 	Strcat_charp(mappage, "\">");
-	Strcat_charp(mappage, htmlquote_str(s->ptr));
+	Strcat_charp(mappage, htmlquote_str(a->alt));
 	Strcat_charp(mappage, " ");
-	Strcat_charp(mappage, htmlquote_str(t->ptr));
+	Strcat_charp(mappage, htmlquote_str(a->url));
 	Strcat_charp(mappage, "</a><br>\n");
     }
     Strcat_charp(mappage, "</body></html>");
@@ -84,6 +160,105 @@
     return loadHTMLString(mappage);
 }
 #endif
+
+#ifdef USE_IMAGE
+int
+getMapXY(Buffer *buf, Anchor *a, int *x, int *y)
+{
+    if (! buf || ! a || ! a->image || ! x || ! y)
+	return 0;
+    *x = (int)((buf->currentColumn + buf->cursorX 
+	- COLPOS(buf->currentLine, a->start.pos) + 0.5)
+	* pixel_per_char) - a->image->xoffset;
+    *y = (int)((buf->currentLine->linenumber - a->image->y + 0.5)
+	* pixel_per_line) - a->image->yoffset;
+    if (*x <= 0)
+	*x = 1;
+    if (*y <= 0)
+	*y = 1;
+    return 1;
+}
+#endif
+
+MapArea *
+newMapArea(char *url, char *alt, char *shape, char *coords)
+{
+    MapArea *a = New(MapArea);
+#ifdef MENU_MAP
+    char *p;
+    int i, max;
+#endif
+
+    a->url = url;
+    a->alt = alt ? alt : "";
+#ifdef MENU_MAP
+#ifdef USE_IMAGE
+    a->shape = SHAPE_RECT;
+    if (shape) {
+ 	if (!strcasecmp(shape, "default"))
+	    a->shape = SHAPE_DEFAULT;
+ 	else if (!strncasecmp(shape, "rect", 4))
+	    a->shape = SHAPE_RECT;
+	else if (!strncasecmp(shape, "circ", 4))
+	    a->shape = SHAPE_CIRCLE;
+	else if (!strncasecmp(shape, "poly", 4))
+	    a->shape = SHAPE_POLY;
+	else
+	    a->shape = SHAPE_UNKNOWN;
+    }
+    a->coords = NULL;
+    a->ncoords = 0;
+    if (a->shape == SHAPE_UNKNOWN || a->shape == SHAPE_DEFAULT)
+	return a;
+    if (! coords) {
+	a->shape = SHAPE_UNKNOWN;
+	return a;
+    }
+    if (a->shape == SHAPE_RECT) {
+	a->coords = New_N(short, 4);
+	a->ncoords = 4;
+    } else if (a->shape == SHAPE_CIRCLE) {
+	a->coords = New_N(short, 3);
+	a->ncoords = 3;
+    }
+    max = a->ncoords;
+    for (i = 0, p = coords; (a->shape == SHAPE_POLY || i < a->ncoords) && *p;) {
+	while (IS_SPACE(*p))
+	    p++;
+	if (! IS_DIGIT(*p))
+	    break;
+	if (a->shape == SHAPE_POLY) {
+	    if (max <= i) {
+		max = i ? i * 2 : 6;
+		a->coords = New_Reuse(short, a->coords, max + 2);
+	    }
+	    a->ncoords++;
+	}
+	a->coords[i] = (short)atoi(p);
+	i++;
+	while (IS_DIGIT(*p))
+	    p++;
+	if (*p != ',' && ! IS_SPACE(*p))
+	    break;
+	while (IS_SPACE(*p))
+	    p++;
+	if (*p == ',')
+	    p++;
+    }
+    if (i != a->ncoords || (a->shape == SHAPE_POLY && a->ncoords < 6)) {
+	a->shape = SHAPE_UNKNOWN;
+	a->coords = NULL;
+	a->ncoords = 0;
+    }
+    if (a->shape == SHAPE_POLY) {
+	a->ncoords = a->ncoords / 2 * 2;
+	a->coords[a->ncoords] = a->coords[0];
+	a->coords[a->ncoords+1] = a->coords[1];
+    }
+#endif
+#endif
+    return a;
+}
 
 /* append frame URL */
 static void
diff -urN -x gc w3m-0.2.1/menu.c w3m-0.2.1-img-1.10/menu.c
--- w3m-0.2.1/menu.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/menu.c	Thu Aug  2 00:43:07 2001
@@ -1322,8 +1322,13 @@
 	return;
     for (i = 0, buf = Firstbuf; i < SelectV; i++, buf = buf->nextBuffer);
     Currentbuf = buf;
-    if (clear_buffer) {
-	for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer)
+    for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer) {
+	if (buf == Currentbuf)
+	    continue;
+#ifdef USE_IMAGE
+	deleteImage(buf);
+#endif
+	if (clear_buffer)
 	    tmpClearBuffer(buf);
     }
 }
diff -urN -x gc w3m-0.2.1/parsetagx.c w3m-0.2.1-img-1.10/parsetagx.c
--- w3m-0.2.1/parsetagx.c	Fri Mar 23 10:49:54 2001
+++ w3m-0.2.1-img-1.10/parsetagx.c	Thu Aug  2 00:43:07 2001
@@ -70,6 +70,12 @@
 	*align = ALIGN_RIGHT;
     else if (strcasecmp(oval, "center") == 0)
 	*align = ALIGN_CENTER;
+    else if (strcasecmp(oval, "top") == 0)
+	*align = ALIGN_TOP;
+    else if (strcasecmp(oval, "bottom") == 0)
+	*align = ALIGN_BOTTOM;
+    else if (strcasecmp(oval, "middle") == 0)
+	*align = ALIGN_MIDDLE;
     else
 	return 0;
     return 1;
diff -urN -x gc w3m-0.2.1/proto.h w3m-0.2.1-img-1.10/proto.h
--- w3m-0.2.1/proto.h	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/proto.h	Thu Aug  2 00:43:07 2001
@@ -50,6 +50,7 @@
 extern void followA(void);
 extern void bufferA(void);
 extern void followI(void);
+extern void submitForm(void);
 extern void followForm(void);
 extern void topA(void);
 extern void lastA(void);
@@ -84,6 +85,13 @@
 extern void extbrz(void);
 extern void linkbrz(void);
 extern void curlno(void);
+#ifdef USE_IMAGE
+extern void dispI(void);
+extern void stopI(void);
+#else
+#define dispI nulcmd
+#define stopI nulcmd
+#endif
 extern int currentLn(Buffer * buf);
 extern void tmpClearBuffer(Buffer * buf);
 extern char *filename_extension(char *patch, int is_url);
@@ -94,7 +102,7 @@
 extern Buffer *loadGeneralFile(char *path, ParsedURL * current, char *referer, int flag, FormList * request);
 extern int is_boundary(int, int);
 extern int is_blank_line(char *line, int indent);
-extern void push_render_image(Str str, int width, struct html_feed_environ *h_env);
+extern void push_render_image(Str str, int width, int limit, struct html_feed_environ *h_env);
 extern void flushline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, int force, int width);
 extern void do_blankline(struct html_feed_environ *h_env, struct readbuffer *obuf, int indent, int indent_incr, int width);
 extern void purgeline(struct html_feed_environ *h_env);
@@ -102,7 +110,14 @@
 			    struct readbuffer *obuf);
 extern void restore_fonteffect(struct html_feed_environ *h_env,
 			       struct readbuffer *obuf);
-extern Str process_img(struct parsed_tag *tag);
+#ifdef USE_IMAGE
+extern void deleteImage(Buffer *buf);
+extern void getAllImage(Buffer *buf);
+extern void loadImage(int flag);
+extern ImageCache *getImage(Image *image, ParsedURL *current, int flag);
+extern int getImageSize(ImageCache *cache);
+#endif
+extern Str process_img(struct parsed_tag *tag, int width);
 extern Str process_anchor(struct parsed_tag *tag, char *tagbuf);
 extern Str process_input(struct parsed_tag *tag);
 extern void process_select(struct parsed_tag *tag);
@@ -131,6 +146,9 @@
 extern Buffer *loadGopherDir(URLFile * uf, Buffer * newBuf);
 #endif				/* USE_GOPHER */
 extern Buffer *loadBuffer(URLFile * uf, Buffer * newBuf);
+#ifdef USE_IMAGE
+extern Buffer *loadImageBuffer(URLFile * uf, Buffer * newBuf);
+#endif
 extern void saveBuffer(Buffer * buf, FILE * f);
 extern void saveBufferDelNum(Buffer * buf, FILE * f, int del);
 extern Buffer *getshell(char *cmd);
@@ -246,7 +264,7 @@
 extern int feed_table(struct table *tbl, char *line, struct table_mode *mode, int width, int internal);
 extern void feed_table1(struct table *tbl, Str tok, struct table_mode *mode, int width);
 extern void pushTable(struct table *, struct table *);
-extern struct form_list *newFormList(char *action, char *method, char *charset, char *enctype, char *target, struct form_list *_next);
+extern struct form_list *newFormList(char *action, char *method, char *charset, char *enctype, char *target, char *name, struct form_list *_next);
 extern struct form_item_list *formList_addInput(struct form_list *fl, struct parsed_tag *tag);
 extern char *form2str(FormItemList * fi);
 extern int formtype(char *typestr);
@@ -260,10 +278,14 @@
 extern void form_write_form_file(FILE * f, char *boundary, char *name, char *file);
 extern void follow_map(struct parsed_tagarg *arg);
 #ifdef MENU_MAP
-extern char *follow_map_menu(Buffer * buf, struct parsed_tagarg *arg, int x, int y);
+extern char *follow_map_menu(Buffer * buf, struct parsed_tagarg *arg, Anchor *a_img, int x, int y);
 #else
 extern Buffer *follow_map_panel(Buffer * buf, struct parsed_tagarg *arg);
 #endif
+#ifdef USE_IMAGE
+extern int getMapXY(Buffer *buf, Anchor *a, int *x, int *y);
+#endif
+extern MapArea *newMapArea(char *url, char *alt, char *shape, char *coords);
 extern Buffer *page_info_panel(Buffer * buf);
 extern struct frame_body *newFrame(struct parsed_tag *tag, ParsedURL * baseURL);
 extern struct frameset *newFrameSet(struct parsed_tag *tag);
@@ -444,6 +466,11 @@
 #define prevMk nulcmd
 #define reMark nulcmd
 #endif				/* not USE_MARK */
+#ifdef JP_CHARSET
+extern char *cURLcode(char *url, char code);
+#else
+#define cURLcode(url,buf) (url)
+#endif
 
 #ifdef MOUSE
 extern void mouse(void);
@@ -456,6 +483,14 @@
 #define mouse nulcmd
 #define msToggle nulcmd
 #endif				/* not MOUSE */
+
+#ifdef USE_IMAGE
+extern void initImage(void);
+extern void termImage(void);
+extern void addImage(ImageCache *cache, int x, int y, int sx, int sy, int w, int h);
+extern void drawImage(void);
+extern void clearImage(void);
+#endif
 
 extern char *searchKeyData(void);
 
diff -urN -x gc w3m-0.2.1/rc.c w3m-0.2.1-img-1.10/rc.c
--- w3m-0.2.1/rc.c	Fri Mar 23 10:51:04 2001
+++ w3m-0.2.1-img-1.10/rc.c	Thu Aug  2 00:43:08 2001
@@ -50,11 +50,13 @@
 #define P_CODE     7
 #endif
 #define P_PIXELS   8
+#define P_SCALE    9
 
 #if LANG == JA
 #define CMT_HELPER	 "外部ビューアの編集"
 #define CMT_TABSTOP      "タブ幅"
 #define CMT_PIXEL_PER_CHAR      "文字幅 (4.0...32.0)"
+#define CMT_PIXEL_PER_LINE      "一行の高さ (4.0...64.0)"
 #define CMT_PAGERLINE    "ページャとして利用した時に保存される行数"
 #define CMT_HISTSIZE     "保持するURL履歴の数"
 #define CMT_SAVEHIST     "URL履歴の保存"
@@ -62,6 +64,14 @@
 #define CMT_FRAME        "フレームの自動表示"
 #define CMT_TSELF        "targetが未指定の場合に_selfを使用する"
 #define CMT_DISPLINK     "リンク先の自動表示"
+#ifdef USE_IMAGE
+#define CMT_DISP_IMAGE   "インライン画像を表示"
+#define CMT_AUTO_IMAGE   "インライン画像を自動で読み込む"
+#define CMT_EXT_IMAGE_VIEWER   "画像を外部ビューワで表示"
+#define CMT_IMAGE_SCALE  "画像のスケール(%)"
+#define CMT_IMGDISPLAY   "画像を表示するためのコマンド"
+#define CMT_IMGSIZE      "画像の大きさを得るためのコマンド"
+#endif
 #define CMT_MULTICOL     "ファイル名のマルチカラム表示"
 #define CMT_COLOR        "カラー表示"
 #define CMT_B_COLOR      "文字の色"
@@ -143,6 +153,7 @@
 #define CMT_HELPER	 "External Viewer Setup"
 #define CMT_TABSTOP      "Tab width"
 #define CMT_PIXEL_PER_CHAR      "# of pixels per character (4.0...32.0)"
+#define CMT_PIXEL_PER_LINE      "# of pixels per line (4.0...64.0)"
 #define CMT_PAGERLINE    "# of reserved line when w3m is used as a pager"
 #define CMT_HISTSIZE     "# of reserved URL"
 #define CMT_SAVEHIST     "Save URL history"
@@ -150,6 +161,14 @@
 #define CMT_FRAME        "Automatic rendering of frame"
 #define CMT_TSELF        "use _self as default target"
 #define CMT_DISPLINK     "Automatic display of link URL"
+#ifdef USE_IMAGE
+#define CMT_DISP_IMAGE   "Display of inline image"
+#define CMT_AUTO_IMAGE   "Automatic loading of inline image"
+#define CMT_EXT_IMAGE_VIEWER   "Use external image viewer"
+#define CMT_IMAGE_SCALE  "Scale of image (%)"
+#define CMT_IMGDISPLAY   "External command to display image"
+#define CMT_IMGSIZE      "External command to get size of image"
+#endif
 #define CMT_MULTICOL     "Multi-column output of file names"
 #define CMT_COLOR        "Display with color"
 #define CMT_B_COLOR      "Color of normal character"
@@ -311,6 +330,9 @@
 {
     {"tabstop", P_INT, PI_TEXT, (void *) &Tabstop, CMT_TABSTOP, NULL},
     {"pixel_per_char", P_PIXELS, PI_TEXT, (void *) &pixel_per_char, CMT_PIXEL_PER_CHAR, NULL},
+#ifdef USE_IMAGE
+    {"pixel_per_line", P_PIXELS, PI_TEXT, (void *) &pixel_per_line, CMT_PIXEL_PER_LINE, NULL},
+#endif
 #ifdef JP_CHARSET
     {"kanjicode", P_CODE, PI_SEL_C, (void *) &DisplayCode, CMT_KANJICODE, kcodestr},
 #endif				/* JP_CHARSET */
@@ -321,6 +343,14 @@
     {"dirlist_cmd", P_STRING, PI_TEXT, (void *) &DirBufferCommand, CMT_DIRLIST_CMD, NULL},
 {"multicol", P_INT, PI_ONOFF, (void *) &multicolList, CMT_MULTICOL, NULL},
     {"ignore_null_img_alt", P_INT, PI_ONOFF, (void *) &ignore_null_img_alt, CMT_IGNORE_NULL_IMG_ALT, NULL},
+#ifdef USE_IMAGE
+    {"display_image", P_INT, PI_ONOFF, (void *) &displayImage, CMT_DISP_IMAGE, NULL},
+    {"auto_image", P_INT, PI_ONOFF, (void *) &autoImage, CMT_AUTO_IMAGE, NULL},
+    {"ext_image_viewer", P_INT, PI_ONOFF, (void *) &useExtImageViewer, CMT_EXT_IMAGE_VIEWER, NULL},
+    {"image_scale", P_SCALE, PI_TEXT, (void *) &image_scale, CMT_IMAGE_SCALE, NULL},
+    {"imgdisplay", P_STRING, PI_TEXT, (void *) &Imgdisplay, CMT_IMGDISPLAY, NULL},
+    {"imgsize", P_STRING, PI_TEXT, (void *) &Imgsize, CMT_IMGSIZE, NULL},
+#endif
     {NULL, 0, 0, NULL, NULL, NULL},
 };
 
@@ -626,6 +656,9 @@
 	    case P_PIXELS:
 		t = "number";
 		break;
+	    case P_SCALE:
+		t = "percent";
+		break;
 	    }
 #ifdef JP_CHARSET
 	    if (InnerCode != DisplayCode)
@@ -646,7 +679,7 @@
 }
 #endif
 
-static int
+int
 str_to_bool(char *value)
 {
     if (value == NULL)
@@ -810,7 +843,13 @@
     case P_PIXELS:
 	ppc = atof(value);
 	if (ppc >= MINIMUM_PIXEL_PER_CHAR &&
-	    ppc <= MAXIMUM_PIXEL_PER_CHAR)
+	    ppc <= MAXIMUM_PIXEL_PER_CHAR * 2)
+	    *(double *) p->varptr = ppc;
+	break;
+    case P_SCALE:
+	ppc = atof(value);
+	if (ppc >= 10 &&
+	    ppc <= 1000)
 	    *(double *) p->varptr = ppc;
 	break;
     }
@@ -1103,6 +1142,7 @@
 #endif
 	return Strnew_charp(*(char **) p->varptr);
     case P_PIXELS:
+    case P_SCALE:
 	return Sprintf("%g", *(double *) p->varptr);
     }
     /* not reached */
diff -urN -x gc w3m-0.2.1/table.c w3m-0.2.1-img-1.10/table.c
--- w3m-0.2.1/table.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/table.c	Thu Aug  2 00:43:08 2001
@@ -1639,33 +1639,29 @@
     struct html_feed_environ henv;
     struct readbuffer obuf;
     struct environment envs[MAX_ENV_LEVEL];
-    TextLineList *tl;
-    Str tmp;
+    int limit;
 
     if (t->caption->length <= 0)
 	return;
 
-    if (t->total_width <= 0)
-	t->total_width = h_env->limit;
-
+    if (t->total_width > 0)
+	limit = t->total_width;
+    else
+	limit = h_env->limit;
     init_henv(&henv, &obuf, envs, MAX_ENV_LEVEL, newTextLineList(),
-	      t->total_width, h_env->envs[h_env->envc].indent);
+	      limit, h_env->envs[h_env->envc].indent);
     HTMLlineproc1("<center>", &henv);
     HTMLlineproc0(t->caption->ptr, &henv, FALSE);
     HTMLlineproc1("</center>", &henv);
 
-    tl = henv.buf;
-
-    if (tl->nitem > 0) {
-	TextLineListItem *ti;
-	tmp = Strnew_charp("<pre for_table>");
-	for (ti = tl->first; ti != NULL; ti = ti->next) {
-	    Strcat(tmp, ti->ptr->line);
-	    Strcat_char(tmp, '\n');
-	}
-	Strcat_charp(tmp, "</pre>");
-	HTMLlineproc1(tmp->ptr, h_env);
-    }
+    if (t->total_width < henv.maxlimit)
+	t->total_width = henv.maxlimit;
+    limit = h_env->limit;
+    h_env->limit = t->total_width;
+    HTMLlineproc1("<center>", h_env);
+    HTMLlineproc0(t->caption->ptr, h_env, FALSE);
+    HTMLlineproc1("</center>", h_env);
+    h_env->limit = limit;
 }
 
 void
@@ -1682,6 +1678,7 @@
     MAT *mat, *minv;
     PERM *pivot;
 #endif				/* MATRIX */
+    int width;
     int rulewidth;
     Str vrulea, vruleb, vrulec;
 #ifdef ID_EXT
@@ -1830,6 +1827,8 @@
     }
 
     /* table output */
+    width = t->total_width;
+
     make_caption(t, h_env);
 
     HTMLlineproc1("<pre for_table>", h_env);
@@ -1844,7 +1843,7 @@
     case BORDER_THICK:
 	renderbuf = Strnew();
 	print_sep(t, -1, T_TOP, t->maxcol, renderbuf);
-	push_render_image(renderbuf, t->total_width, h_env);
+	push_render_image(renderbuf, width, t->total_width, h_env);
 	t->total_height += 1;
 	break;
     }
@@ -1921,12 +1920,12 @@
 		t->total_height += 1;
 		break;
 	    }
-	    push_render_image(renderbuf, t->total_width, h_env);
+	    push_render_image(renderbuf, width, t->total_width, h_env);
 	}
 	if (r < t->maxrow && t->border_mode != BORDER_NONE) {
 	    renderbuf = Strnew();
 	    print_sep(t, r, T_MIDDLE, t->maxcol, renderbuf);
-	    push_render_image(renderbuf, t->total_width, h_env);
+	    push_render_image(renderbuf, width, t->total_width, h_env);
 	}
 	t->total_height += t->tabheight[r];
     }
@@ -1935,7 +1934,7 @@
     case BORDER_THICK:
 	renderbuf = Strnew();
 	print_sep(t, t->maxrow, T_BOTTOM, t->maxcol, renderbuf);
-	push_render_image(renderbuf, t->total_width, h_env);
+	push_render_image(renderbuf, width, t->total_width, h_env);
 	t->total_height += 1;
 	break;
     }
@@ -1943,7 +1942,7 @@
 	renderbuf = Strnew(" ");
 	t->total_height++;
 	t->total_width = 1;
-	push_render_image(renderbuf, t->total_width, h_env);
+	push_render_image(renderbuf, 1, t->total_width, h_env);
     }
     HTMLlineproc1("</pre>", h_env);
 }
@@ -2790,7 +2789,21 @@
 	mode->pre_mode &= ~TBLM_PRE_INT;
 	break;
     case HTML_IMG:
-	tok = process_img(tag);
+	w = tbl->fixed_width[tbl->col];
+	if (w < 0) {
+	    if (tbl->total_width > 0)
+		w = - tbl->total_width * w / 100;
+	    else if (width > 0)
+		w = - width * w / 100;
+	    else
+		w = 0;
+	} else if (w == 0) {
+	    if (tbl->total_width > 0)
+		w = tbl->total_width;
+	    else if (width > 0)
+		w = width;
+	}
+	tok = process_img(tag, w);
 	feed_table1(tbl, tok, mode, width);
 	break;
 #ifdef NEW_FORM
diff -urN -x gc w3m-0.2.1/tagtable.c w3m-0.2.1-img-1.10/tagtable.c
--- w3m-0.2.1/tagtable.c	Fri Mar 23 12:43:49 2001
+++ w3m-0.2.1-img-1.10/tagtable.c	Thu Jul 26 23:45:52 2001
@@ -82,77 +82,78 @@
   /* 77 */ {"/h1",HTML_N_H,NULL},
   /* 78 */ {"tr",HTML_TR,&MyHashItem[79]},
   /* 79 */ {"/h2",HTML_N_H,NULL},
-  /* 80 */ {"/h3",HTML_N_H,NULL},
-  /* 81 */ {"pre_int",HTML_PRE_INT,&MyHashItem[82]},
-  /* 82 */ {"/font",HTML_N_FONT,&MyHashItem[83]},
-  /* 83 */ {"tt",HTML_NOP,&MyHashItem[84]},
-  /* 84 */ {"/h4",HTML_N_H,NULL},
-  /* 85 */ {"body",HTML_BODY,&MyHashItem[86]},
-  /* 86 */ {"/form",HTML_N_FORM,&MyHashItem[87]},
-  /* 87 */ {"/h5",HTML_N_H,NULL},
-  /* 88 */ {"/h6",HTML_N_H,NULL},
-  /* 89 */ {"frame",HTML_FRAME,NULL},
-  /* 90 */ {"/img_alt",HTML_N_IMG_ALT,&MyHashItem[91]},
-  /* 91 */ {"/center",HTML_N_CENTER,NULL},
-  /* 92 */ {"/pre",HTML_N_PRE,NULL},
-  /* 93 */ {"tfoot",HTML_TFOOT,NULL},
-  /* 94 */ {"ins",HTML_INS,NULL},
-  /* 95 */ {"/var",HTML_NOP,NULL},
-  /* 96 */ {"h1",HTML_H,NULL},
-  /* 97 */ {"/tfoot",HTML_N_TFOOT,&MyHashItem[98]},
-  /* 98 */ {"input",HTML_INPUT,&MyHashItem[99]},
-  /* 99 */ {"h2",HTML_H,NULL},
-  /* 100 */ {"h3",HTML_H,NULL},
-  /* 101 */ {"h4",HTML_H,NULL},
-  /* 102 */ {"h5",HTML_H,NULL},
-  /* 103 */ {"h6",HTML_H,NULL},
-  /* 104 */ {"/pre_int",HTML_N_PRE_INT,NULL},
-  /* 105 */ {"/menu",HTML_N_UL,NULL},
-  /* 106 */ {"form_int",HTML_FORM_INT,NULL},
-  /* 107 */ {"style",HTML_STYLE,&MyHashItem[108]},
-  /* 108 */ {"address",HTML_BR,NULL},
-  /* 109 */ {"/textarea",HTML_N_TEXTAREA,NULL},
-  /* 110 */ {"/input_alt",HTML_N_INPUT_ALT,NULL},
-  /* 111 */ {"doctype",HTML_DOCTYPE,&MyHashItem[112]},
-  /* 112 */ {"/style",HTML_N_STYLE,NULL},
-  /* 113 */ {"/html",HTML_N_BODY,NULL},
-  /* 114 */ {"pre",HTML_PRE,&MyHashItem[115]},
-  /* 115 */ {"title",HTML_TITLE,NULL},
-  /* 116 */ {"select",HTML_SELECT,NULL},
-  /* 117 */ {"var",HTML_NOP,NULL},
-  /* 118 */ {"/title",HTML_N_TITLE,NULL},
-  /* 119 */ {"embed",HTML_EMBED,&MyHashItem[120]},
-  /* 120 */ {"colgroup",HTML_COLGROUP,&MyHashItem[121]},
-  /* 121 */ {"/head",HTML_N_HEAD,&MyHashItem[122]},
-  /* 122 */ {"isindex",HTML_ISINDEX,NULL},
-  /* 123 */ {"strike",HTML_DEL,&MyHashItem[124]},
-  /* 124 */ {"listing",HTML_LISTING,NULL},
-  /* 125 */ {"bgsound",HTML_BGSOUND,NULL},
-  /* 126 */ {"/address",HTML_BR,NULL},
-  /* 127 */ {"thead",HTML_THEAD,&MyHashItem[128]},
-  /* 128 */ {"wbr",HTML_WBR,&MyHashItem[129]},
-  /* 129 */ {"/del",HTML_N_DEL,&MyHashItem[130]},
-  /* 130 */ {"/nobr",HTML_N_NOBR,&MyHashItem[131]},
-  /* 131 */ {"/select",HTML_N_SELECT,&MyHashItem[132]},
-  /* 132 */ {"frameset",HTML_FRAMESET,&MyHashItem[133]},
-  /* 133 */ {"/xmp",HTML_N_XMP,NULL},
-  /* 134 */ {"/code",HTML_NOP,NULL},
-  /* 135 */ {"/thead",HTML_N_THEAD,&MyHashItem[136]},
-  /* 136 */ {"/samp",HTML_NOP,&MyHashItem[137]},
-  /* 137 */ {"/dfn",HTML_NOP,&MyHashItem[138]},
-  /* 138 */ {"_id",HTML_NOP,NULL},
-  /* 139 */ {"/strike",HTML_N_DEL,&MyHashItem[140]},
-  /* 140 */ {"/a",HTML_N_A,NULL},
-  /* 141 */ {"/b",HTML_N_B,NULL},
-  /* 142 */ {"font",HTML_FONT,&MyHashItem[143]},
-  /* 143 */ {"/dl",HTML_N_DL,NULL},
-  /* 144 */ {"form",HTML_FORM,&MyHashItem[145]},
-  /* 145 */ {"/cite",HTML_NOP,&MyHashItem[146]},
-  /* 146 */ {"a",HTML_A,NULL},
-  /* 147 */ {"b",HTML_B,NULL},
-  /* 148 */ {"/listing",HTML_N_LISTING,&MyHashItem[149]},
-  /* 149 */ {"/em",HTML_N_EM,&MyHashItem[150]},
-  /* 150 */ {"/i",HTML_NOP,NULL},
+  /* 80 */ {"image",HTML_IMG,&MyHashItem[81]},
+  /* 81 */ {"/h3",HTML_N_H,NULL},
+  /* 82 */ {"pre_int",HTML_PRE_INT,&MyHashItem[83]},
+  /* 83 */ {"/font",HTML_N_FONT,&MyHashItem[84]},
+  /* 84 */ {"tt",HTML_NOP,&MyHashItem[85]},
+  /* 85 */ {"/h4",HTML_N_H,NULL},
+  /* 86 */ {"body",HTML_BODY,&MyHashItem[87]},
+  /* 87 */ {"/form",HTML_N_FORM,&MyHashItem[88]},
+  /* 88 */ {"/h5",HTML_N_H,NULL},
+  /* 89 */ {"/h6",HTML_N_H,NULL},
+  /* 90 */ {"frame",HTML_FRAME,NULL},
+  /* 91 */ {"/img_alt",HTML_N_IMG_ALT,&MyHashItem[92]},
+  /* 92 */ {"/center",HTML_N_CENTER,NULL},
+  /* 93 */ {"/pre",HTML_N_PRE,NULL},
+  /* 94 */ {"tfoot",HTML_TFOOT,NULL},
+  /* 95 */ {"ins",HTML_INS,NULL},
+  /* 96 */ {"/var",HTML_NOP,NULL},
+  /* 97 */ {"h1",HTML_H,NULL},
+  /* 98 */ {"/tfoot",HTML_N_TFOOT,&MyHashItem[99]},
+  /* 99 */ {"input",HTML_INPUT,&MyHashItem[100]},
+  /* 100 */ {"h2",HTML_H,NULL},
+  /* 101 */ {"h3",HTML_H,NULL},
+  /* 102 */ {"h4",HTML_H,NULL},
+  /* 103 */ {"h5",HTML_H,NULL},
+  /* 104 */ {"h6",HTML_H,NULL},
+  /* 105 */ {"/pre_int",HTML_N_PRE_INT,NULL},
+  /* 106 */ {"/menu",HTML_N_UL,NULL},
+  /* 107 */ {"form_int",HTML_FORM_INT,NULL},
+  /* 108 */ {"style",HTML_STYLE,&MyHashItem[109]},
+  /* 109 */ {"address",HTML_BR,NULL},
+  /* 110 */ {"/textarea",HTML_N_TEXTAREA,NULL},
+  /* 111 */ {"/input_alt",HTML_N_INPUT_ALT,NULL},
+  /* 112 */ {"doctype",HTML_DOCTYPE,&MyHashItem[113]},
+  /* 113 */ {"/style",HTML_N_STYLE,NULL},
+  /* 114 */ {"/html",HTML_N_BODY,NULL},
+  /* 115 */ {"pre",HTML_PRE,&MyHashItem[116]},
+  /* 116 */ {"title",HTML_TITLE,NULL},
+  /* 117 */ {"select",HTML_SELECT,NULL},
+  /* 118 */ {"var",HTML_NOP,NULL},
+  /* 119 */ {"/title",HTML_N_TITLE,NULL},
+  /* 120 */ {"embed",HTML_EMBED,&MyHashItem[121]},
+  /* 121 */ {"colgroup",HTML_COLGROUP,&MyHashItem[122]},
+  /* 122 */ {"/head",HTML_N_HEAD,&MyHashItem[123]},
+  /* 123 */ {"isindex",HTML_ISINDEX,NULL},
+  /* 124 */ {"strike",HTML_DEL,&MyHashItem[125]},
+  /* 125 */ {"listing",HTML_LISTING,NULL},
+  /* 126 */ {"bgsound",HTML_BGSOUND,NULL},
+  /* 127 */ {"/address",HTML_BR,NULL},
+  /* 128 */ {"thead",HTML_THEAD,&MyHashItem[129]},
+  /* 129 */ {"wbr",HTML_WBR,&MyHashItem[130]},
+  /* 130 */ {"/del",HTML_N_DEL,&MyHashItem[131]},
+  /* 131 */ {"/nobr",HTML_N_NOBR,&MyHashItem[132]},
+  /* 132 */ {"/select",HTML_N_SELECT,&MyHashItem[133]},
+  /* 133 */ {"frameset",HTML_FRAMESET,&MyHashItem[134]},
+  /* 134 */ {"/xmp",HTML_N_XMP,NULL},
+  /* 135 */ {"/code",HTML_NOP,NULL},
+  /* 136 */ {"/thead",HTML_N_THEAD,&MyHashItem[137]},
+  /* 137 */ {"/samp",HTML_NOP,&MyHashItem[138]},
+  /* 138 */ {"/dfn",HTML_NOP,&MyHashItem[139]},
+  /* 139 */ {"_id",HTML_NOP,NULL},
+  /* 140 */ {"/strike",HTML_N_DEL,&MyHashItem[141]},
+  /* 141 */ {"/a",HTML_N_A,NULL},
+  /* 142 */ {"/b",HTML_N_B,NULL},
+  /* 143 */ {"font",HTML_FONT,&MyHashItem[144]},
+  /* 144 */ {"/dl",HTML_N_DL,NULL},
+  /* 145 */ {"form",HTML_FORM,&MyHashItem[146]},
+  /* 146 */ {"/cite",HTML_NOP,&MyHashItem[147]},
+  /* 147 */ {"a",HTML_A,NULL},
+  /* 148 */ {"b",HTML_B,NULL},
+  /* 149 */ {"/listing",HTML_N_LISTING,&MyHashItem[150]},
+  /* 150 */ {"/em",HTML_N_EM,&MyHashItem[151]},
+  /* 151 */ {"/i",HTML_NOP,NULL},
 };
 
 static HashItem_si *MyHashItemTbl[] = {
@@ -204,58 +205,58 @@
   &MyHashItem[75],
   &MyHashItem[78],
   &MyHashItem[80],
-  &MyHashItem[81],
-  &MyHashItem[85],
-  &MyHashItem[88],
+  &MyHashItem[82],
+  &MyHashItem[86],
   &MyHashItem[89],
   &MyHashItem[90],
-  &MyHashItem[92],
+  &MyHashItem[91],
   &MyHashItem[93],
   &MyHashItem[94],
   &MyHashItem[95],
   &MyHashItem[96],
   &MyHashItem[97],
-  &MyHashItem[100],
+  &MyHashItem[98],
   &MyHashItem[101],
   &MyHashItem[102],
   &MyHashItem[103],
-  NULL,
   &MyHashItem[104],
+  NULL,
   &MyHashItem[105],
+  &MyHashItem[106],
   NULL,
   NULL,
-  &MyHashItem[106],
   &MyHashItem[107],
+  &MyHashItem[108],
   NULL,
-  &MyHashItem[109],
   &MyHashItem[110],
   &MyHashItem[111],
-  &MyHashItem[113],
-  NULL,
-  NULL,
+  &MyHashItem[112],
   &MyHashItem[114],
-  &MyHashItem[116],
   NULL,
+  NULL,
+  &MyHashItem[115],
   &MyHashItem[117],
+  NULL,
   &MyHashItem[118],
   &MyHashItem[119],
-  &MyHashItem[123],
-  &MyHashItem[125],
+  &MyHashItem[120],
+  &MyHashItem[124],
   &MyHashItem[126],
   &MyHashItem[127],
+  &MyHashItem[128],
   NULL,
   NULL,
-  &MyHashItem[134],
   &MyHashItem[135],
-  &MyHashItem[139],
-  &MyHashItem[141],
+  &MyHashItem[136],
+  &MyHashItem[140],
+  &MyHashItem[142],
   NULL,
   NULL,
   NULL,
-  &MyHashItem[142],
-  &MyHashItem[144],
-  &MyHashItem[147],
+  &MyHashItem[143],
+  &MyHashItem[145],
   &MyHashItem[148],
+  &MyHashItem[149],
 };
 
 Hash_si tagtable = {100, MyHashItemTbl};
diff -urN -x gc w3m-0.2.1/tagtable.tab w3m-0.2.1-img-1.10/tagtable.tab
--- w3m-0.2.1/tagtable.tab	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/tagtable.tab	Thu Aug  2 00:43:08 2001
@@ -45,6 +45,7 @@
 blockquote	HTML_BLQ
 /blockquote	HTML_N_BLQ
 img		HTML_IMG
+image		HTML_IMG
 code		HTML_NOP
 /code		HTML_NOP
 dfn		HTML_NOP
diff -urN -x gc w3m-0.2.1/terms.c w3m-0.2.1-img-1.10/terms.c
--- w3m-0.2.1/terms.c	Fri Mar 23 10:49:53 2001
+++ w3m-0.2.1-img-1.10/terms.c	Thu Aug  2 00:43:08 2001
@@ -1561,7 +1561,14 @@
 {
     char c;
 
-    read(tty, &c, 1);
+    /* read(tty, &c, 1); */
+    while (read(tty, &c, 1) < (ssize_t)1) {
+	if (errno == EINTR || errno == EAGAIN)
+	    continue;
+	/* error happend on read(2) */
+	quitfm();
+	break;	/* unreachable */
+    }
     return c;
 }
 
@@ -1837,3 +1844,232 @@
 {
     fflush(ttyf);
 }
+
+#ifdef USE_IMAGE
+typedef struct _termialImage {
+    ImageCache *cache;
+    short x;
+    short y;
+    short sx;
+    short sy;
+    short width;
+    short height;
+} TerminalImage;
+
+static TerminalImage *terminal_image = NULL;
+static int n_terminal_image = 0;
+static int max_terminal_image = 0;
+static FILE *Imgdisplay_rf = NULL, *Imgdisplay_wf = NULL;
+static pid_t Imgdisplay_pid = 0;
+int activeImgdisplay = FALSE;
+int volatile SigPipeReturn = 0;
+extern image_index;
+
+MySignalHandler
+SigPipe(SIGNAL_ARG)
+{
+    signal(SIGPIPE, SigPipe);
+    SigPipeReturn = 1;
+    SIGNAL_RETURN;
+}
+
+void
+initImage()
+{
+    char *cmd;
+
+    if (activeImage)
+	return;
+    if (Imgdisplay[0] != '/')
+	cmd = Sprintf("%s/%s", LIB_DIR, Imgdisplay)->ptr;
+    else
+	cmd = Imgdisplay;
+    if (system(Sprintf("%s -test", cmd)->ptr)) {
+	activeImage = FALSE;
+	return;
+    }
+    activeImage = TRUE;
+}
+
+void
+initImgdisplay()
+{
+    int rfd[2], wfd[2];
+    char *cmd;
+
+    if (activeImgdisplay)
+	return;
+    activeImage = FALSE;
+    flush_tty();
+    if (pipe(rfd) < 0)
+        return;
+    if (pipe(wfd) < 0) {
+        close(rfd[0]);
+        close(rfd[1]);
+        return;
+    }
+    signal(SIGPIPE, SigPipe);
+    if ((Imgdisplay_pid = fork()) == 0) {
+	signal(SIGHUP, SIG_IGN);
+	signal(SIGINT, SIG_IGN);
+	signal(SIGQUIT, SIG_IGN);
+	signal(SIGTERM, SIG_IGN);
+	close_tty();
+	close(rfd[0]);
+	close(wfd[1]);
+	dup2(rfd[1], 1);
+	dup2(wfd[0], 0);
+	if (Imgdisplay[0] != '/')
+	    cmd = Sprintf("%s/%s", LIB_DIR, Imgdisplay)->ptr;
+	else
+	    cmd = Imgdisplay;
+	execl("/bin/sh", "sh", "-c", cmd, NULL);
+	exit(1);
+    }
+    close(rfd[1]);
+    close(wfd[0]);
+    if (Imgdisplay_pid < 0) {
+	close(rfd[0]);
+	close(wfd[1]);
+	return;
+    }
+    Imgdisplay_rf = fdopen(rfd[0], "r");
+    Imgdisplay_wf = fdopen(wfd[1], "w");
+    if (! Imgdisplay_rf || ! Imgdisplay_wf) {
+	close(rfd[0]);
+	close(wfd[1]);
+	Imgdisplay_rf = NULL;
+	Imgdisplay_wf = NULL;
+	return;
+    }
+    activeImage = TRUE;
+    activeImgdisplay = TRUE;
+}
+
+void
+termImage()
+{
+    if (Imgdisplay_rf)
+	fclose(Imgdisplay_rf);
+    if (Imgdisplay_wf)
+	fclose(Imgdisplay_wf);
+    activeImage = FALSE;
+    activeImgdisplay = FALSE;
+}
+
+void
+addImage(ImageCache *cache, int x, int y, int sx, int sy, int w, int h)
+{
+    TerminalImage *i;
+
+    if (! activeImage)
+	return;
+    if (n_terminal_image >= max_terminal_image) {
+	max_terminal_image = max_terminal_image ? (2 * max_terminal_image) : 8;
+	terminal_image = New_Reuse(TerminalImage, terminal_image,
+		max_terminal_image);
+    }
+    i = &terminal_image[n_terminal_image];
+    i->cache = cache;
+    i->x = x;
+    i->y = y;
+    i->sx = sx;
+    i->sy = sy;
+    i->width = w;
+    i->height = h;
+    n_terminal_image++;
+}
+
+void
+drawImage()
+{
+    static char buf[64];
+    int j, draw = FALSE;
+    TerminalImage *i;
+
+    if (! activeImage)
+	return;
+    if (! n_terminal_image)
+	return;
+    for (j = 0; j < n_terminal_image; j++) {
+	i = &terminal_image[j];
+	if (! (i->cache->loaded == IMG_FLAG_LOADED &&
+		i->width > 0 && i->height > 0))
+	    continue;
+	if (! activeImgdisplay) {
+	    initImgdisplay();
+	    if (! activeImgdisplay)
+		return;
+	}
+	if (! draw) {
+	    fputs("3;\n", Imgdisplay_wf);	/* XSync() */
+	    draw = TRUE;
+	}
+	if (i->cache->index > 0) {
+	    i->cache->index *= -1;
+	    fputs("0;", Imgdisplay_wf);	/* DrawImage() */
+	} else
+	    fputs("1;", Imgdisplay_wf);	/* DrawImage(redraw) */
+	sprintf(buf, "%d;%d;%d;%d;%d;%d;%d;%d;%d;",
+		(- i->cache->index - 1) % MAX_IMAGE + 1, i->x, i->y,
+		(i->cache->width > 0) ? i->cache->width : 0,
+		(i->cache->height > 0) ? i->cache->height : 0,
+		i->sx, i->sy, i->width, i->height);
+	fputs(buf, Imgdisplay_wf);
+	fputs(i->cache->file, Imgdisplay_wf);
+	fputs("\n", Imgdisplay_wf);
+	fputs("4;\n", Imgdisplay_wf);	/* put '\n' */
+	fflush(Imgdisplay_wf);
+	if (! fgetc(Imgdisplay_rf) || SigPipeReturn) {
+	    int wait_st;
+	    kill(Imgdisplay_pid, SIGKILL);
+#ifdef HAVE_WAITPID
+            waitpid(Imgdisplay_pid, &wait_st, 0);
+#else
+            wait(&wait_st);
+#endif
+	    i->cache->loaded = IMG_FLAG_ERROR;
+	    image_index += MAX_IMAGE;
+	    activeImgdisplay = FALSE;
+	    SigPipeReturn = 0;
+	    return;
+	}
+    }
+    if (! draw)
+	return;
+    fputs("3;\n", Imgdisplay_wf);	/* XSync() */
+    fputs("4;\n", Imgdisplay_wf);	/* put '\n' */
+    fflush(Imgdisplay_wf);
+    fgetc(Imgdisplay_rf);
+
+    touch_line();
+    touch_column(CurColumn);
+#ifdef JP_CHARSET
+    if (CurColumn > 0 &&
+	CHMODE(ScreenImage[CurLine]->lineprop[CurColumn]) == C_WCHAR2)
+	touch_column(CurColumn - 1);
+    else if (CurColumn < COLS - 1 &&
+	CHMODE(ScreenImage[CurLine]->lineprop[CurColumn]) == C_WCHAR1)
+	touch_column(CurColumn + 1);
+#endif
+    refresh();
+}
+
+void
+clearImage()
+{
+    if (! activeImage)
+	return;
+    n_terminal_image = 0;
+}
+
+void
+resetImage()
+{
+    if (! activeImgdisplay)
+	return;
+    fputs("2;\n", Imgdisplay_wf);	/* ClearImage() */
+    fflush(Imgdisplay_wf);
+    clearImage();
+}
+#endif
diff -urN -x gc w3m-0.2.1/version.c w3m-0.2.1-img-1.10/version.c
--- w3m-0.2.1/version.c	Fri Mar 23 11:32:41 2001
+++ w3m-0.2.1-img-1.10/version.c	Thu Aug  2 00:43:08 2001
@@ -1,4 +1,4 @@
-#define CURRENT_VERSION "w3m/0.2.1"
+#define CURRENT_VERSION "w3m/0.2.1-img-1.10"
 
 #ifndef FM_H
 char *version = CURRENT_VERSION;
diff -urN -x gc w3m-0.2.1/w3mimgdisplay.c w3m-0.2.1-img-1.10/w3mimgdisplay.c
--- w3m-0.2.1/w3mimgdisplay.c	Thu Jan  1 09:00:00 1970
+++ w3m-0.2.1-img-1.10/w3mimgdisplay.c	Thu Aug  2 00:43:08 2001
@@ -0,0 +1,315 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <Imlib.h>
+
+static Display *display;
+static Window window, parent;
+static unsigned long background_pixel;
+static char *background = NULL;
+static int offset_x = 2, offset_y = 2;
+static int defined_bg = 0, defined_x = 0, defined_y = 0, defined_test = 0;
+static int defined_debug = 0;
+
+#define MAX_IMAGE 1000
+typedef struct {
+  Pixmap pixmap;
+  int width;
+  int height;
+} Image;
+static Image *imageBuf = NULL;
+static int maxImage = 0;
+static GC imageGC = NULL;
+
+static void GetOption(int argc, char **argv);
+static void DrawImage(char *buf, int redraw);
+static void ClearImage(void);
+
+/*
+  xterm/kterm/hanterm/cxterm
+    top window (WINDOWID)
+      +- text window
+           +- scrollbar
+  rxvt/aterm/Eterm/wterm
+    top window (WINDOWID)
+      +- text window
+      +- scrollbar
+      +- menubar (etc.)
+  gnome-terminal
+    top window
+      +- text window (WINDOWID)
+      +- scrollbar
+      +- menubar
+  mlterm (-s)
+    top window
+      +- text window (WINDOWID)
+      +- scrollbar
+  mlterm
+    top window = text window (WINDOWID)
+
+  powershell
+    top window
+      +- window
+      |    +- text window
+      |    +- scrollbar
+      +- menubar (etc.)
+  dtterm
+    top window
+      +- window
+           +- window
+           |    +- window
+           |         +- text window
+           |         +- scrollbar
+           +- menubar
+  hpterm
+    top window
+      +- window
+           +- text window
+           +- scrollbar
+           +- (etc.)
+*/
+
+int
+main(int argc, char **argv)
+{
+    Window root, *children;
+    XWindowAttributes attr;
+    XColor screen_def, exact_def;
+    int revert, nchildren, len;
+    char buf[1024 + 128];
+    int i;
+    char *id;
+
+    GetOption(argc, argv);
+    if (! defined_debug)
+	fclose(stderr);
+
+    display = XOpenDisplay(NULL);
+    if (! display) exit(1);
+    if ((id = getenv("WINDOWID")) != NULL)
+       window = (Window)atoi(id);
+    else
+       XGetInputFocus(display, &window, &revert);
+    if (! window) exit(1);
+
+    if (defined_test) exit(0);		/* test OK */
+
+    while (1) {
+	unsigned int size = 0;
+	Window p_window;
+
+	XQueryTree(display, window, &root, &parent, &children, &nchildren);
+	if (defined_debug)
+	    fprintf(stderr, "window=%x root=%x parent=%x nchildren=%d\n",
+		window, root, parent, nchildren);
+	if (! size) {
+	    XGetWindowAttributes(display, window, &attr);
+	    size = attr.width * attr.height;
+	}
+	size *= 0.5;
+	p_window = window;
+	for (i = 0; i < nchildren; i++) {
+	    XGetWindowAttributes(display, children[i], &attr);
+	    if (defined_debug)
+		fprintf(stderr,
+			"children[%d]=%x x=%d y=%d width=%d height=%d\n", i,
+			children[i], attr.x, attr.y, attr.width, attr.height);
+	    if (attr.width * attr.height > size) {
+		/* maybe text window */
+		size = attr.width * attr.height;
+		window = children[i];
+	    }
+	}
+	if (p_window == window)
+	    break;
+    }
+    if (! defined_x) {
+	for (i = 0; i < nchildren; i++) {
+	    XGetWindowAttributes(display, children[i], &attr);
+	    if (defined_debug)
+		fprintf(stderr,
+			"children[%d]=%x x=%d y=%d width=%d height=%d\n", i,
+			children[i], attr.x, attr.y, attr.width, attr.height);
+	    if (attr.x <= 0 && attr.width < 30) {
+		/* scrollbar of xterm/kterm ? */
+		offset_x += attr.x + attr.width + attr.border_width * 2;
+		break;
+	    }
+	}
+    }
+
+    if (defined_bg && XAllocNamedColor(display, DefaultColormap(display, 0),
+	background, &screen_def, &exact_def))
+	background_pixel = screen_def.pixel;
+    else
+	background_pixel = WhitePixel(display, 0);
+
+    while (fgets(buf, sizeof(buf), stdin) != NULL) {
+	if (! (isdigit(buf[0]) && buf[1] == ';')) {
+	    fputc('\n', stdout);
+	    fflush(stdout);
+	    continue;
+	}
+	len = strlen(buf);
+	if (buf[len - 1] == '\n') {
+	    buf[--len] = '\0';
+	    if (buf[len - 1] == '\r')
+		buf[--len] = '\0';
+	}
+	switch(buf[0]) {
+	case '0':
+	    DrawImage(&buf[2], 0);
+	    break;
+	case '1':
+	    DrawImage(&buf[2], 1);
+	    break;
+	case '2':
+	    ClearImage();
+	    break;
+	case '3':
+	    XSync(display, False);
+	    break;
+	case '4':
+	    fputs("\n", stdout);
+	    fflush(stdout);
+	    break;
+	}
+    }
+    ClearImage();
+/*
+    XCloseDisplay(display);
+*/
+    exit(0);
+}
+
+static void
+GetOption(int argc, char **argv)
+{
+    int i;
+
+    for (i = 1; i < argc; i++) {
+	if (! strcmp("-bg", argv[i])) {
+	    if (++i >= argc) exit(1);
+	    background = argv[i];
+	    defined_bg = 1;
+	} else if (! strcmp("-x", argv[i])) {
+	    if (++i >= argc) exit(1);
+	    offset_x = atoi(argv[i]);
+	    defined_x = 1;
+	} else if (! strcmp("-y", argv[i])) {
+	    if (++i >= argc) exit(1);
+	    offset_y = atoi(argv[i]);
+	    defined_y = 1;
+	} else if (! strcmp("-test", argv[i])) {
+	    defined_test = 1;
+	} else if (! strcmp("-debug", argv[i])) {
+	    defined_debug = 1;
+	} else {
+	    exit(1);
+	}
+    }
+}
+
+void
+DrawImage(char *buf, int redraw)
+{
+    static ImlibData *id = NULL;
+    ImlibImage *im;
+    char *p = buf;
+    int n = 0, x = 0, y = 0, w = 0, h = 0, sx = 0, sy = 0, sw = 0, sh = 0;
+
+    if (! p) return;
+    for (; isdigit(*p); p++) n = 10 * n + (*p - '0');
+    if (*(p++) != ';') return;
+    for (; isdigit(*p); p++) x = 10 * x + (*p - '0');
+    if (*(p++) != ';') return;
+    for (; isdigit(*p); p++) y = 10 * y + (*p - '0');
+    if (*(p++) != ';') return;
+    for (; isdigit(*p); p++) w = 10 * w + (*p - '0');
+    if (*(p++) != ';') return;
+    for (; isdigit(*p); p++) h = 10 * h + (*p - '0');
+    if (*(p++) != ';') return;
+    for (; isdigit(*p); p++) sx = 10 * sx + (*p - '0');
+    if (*(p++) != ';') return;
+    for (; isdigit(*p); p++) sy = 10 * sy + (*p - '0');
+    if (*(p++) != ';') return;
+    for (; isdigit(*p); p++) sw = 10 * sw + (*p - '0');
+    if (*(p++) != ';') return;
+    for (; isdigit(*p); p++) sh = 10 * sh + (*p - '0');
+    if (*(p++) != ';') return;
+
+    n--;
+    if (n < 0 || n >= MAX_IMAGE)
+	return;
+    if (redraw) {
+	if (! imageGC || n >= maxImage || ! imageBuf[n].pixmap)
+	    return;
+	goto draw_image;
+    }
+    if (! id) {
+	id = Imlib_init(display);
+	if (! id)
+	    return;
+    }
+    if (! imageGC) {
+	imageGC = XCreateGC(display, parent, 0, NULL);
+	if (! imageGC)
+	    return;
+    }
+    if (n >= maxImage) {
+	int i = maxImage;
+	maxImage = i ? (i * 2) : 2;
+	if (maxImage > MAX_IMAGE)
+	    maxImage = MAX_IMAGE;
+	else if (n >= maxImage)
+	    maxImage = n + 1;
+	imageBuf = (Image *) realloc((void *)imageBuf,
+		sizeof(Image) * maxImage);
+	for (; i < maxImage; i++)
+	    imageBuf[i].pixmap = NULL;
+    }
+    if (imageBuf[n].pixmap) {
+	XFreePixmap(display, imageBuf[n].pixmap);
+	imageBuf[n].pixmap = NULL;
+    }
+
+    im = Imlib_load_image(id, p);
+    if (! im)
+	return;
+    if (! w)
+	w = im->rgb_width;
+    if (! h)
+	h = im->rgb_height;
+    imageBuf[n].pixmap = XCreatePixmap(display, parent, w, h,
+	DefaultDepth(display, 0));
+    if (! imageBuf[n].pixmap)
+	return;
+    XSetForeground(display, imageGC, background_pixel);
+    XFillRectangle(display, imageBuf[n].pixmap, imageGC, 0, 0, w, h);
+    Imlib_paste_image(id, im, imageBuf[n].pixmap, 0, 0, w, h);
+    Imlib_kill_image(id, im);
+    imageBuf[n].width = w;
+    imageBuf[n].height = h;
+draw_image:
+    XCopyArea(display, imageBuf[n].pixmap, window, imageGC,
+	sx, sy, (sw ? sw : imageBuf[n].width), (sh ? sh : imageBuf[n].height),
+	x + offset_x, y + offset_y);
+}
+
+void
+ClearImage(void)
+{
+    if (imageGC) {
+	XFreeGC(display, imageGC);
+	imageGC = NULL;
+    }
+    if (imageBuf) {
+	int i;
+	for (i = 0; i < maxImage; i++) {
+	    if (imageBuf[i].pixmap)
+		XFreePixmap(display, imageBuf[i].pixmap);
+	}
+	free(imageBuf);
+	imageBuf = NULL;
+    }
+    maxImage = 0;
+}
diff -urN -x gc w3m-0.2.1/w3mimgsize.c w3m-0.2.1-img-1.10/w3mimgsize.c
--- w3m-0.2.1/w3mimgsize.c	Thu Jan  1 09:00:00 1970
+++ w3m-0.2.1-img-1.10/w3mimgsize.c	Thu Aug  2 00:43:08 2001
@@ -0,0 +1,27 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <Imlib.h>
+
+int
+main(int argc, char **argv)
+{
+    Display *display;
+    ImlibData *id;
+    ImlibImage *im;
+
+    fclose(stderr);
+    if (argc < 2) exit(1);
+    display = XOpenDisplay(NULL);
+    if (! display) exit(1);
+    id = Imlib_init(display);
+    if (! id) exit(1);
+    im = Imlib_load_image(id, argv[1]);
+    if (! im) exit(1);
+    printf("%d %d\n", im->rgb_width, im->rgb_height);
+/*
+    Imlib_kill_image(id, im);
+    XCloseDisplay(display);
+*/
+    exit(0);
+}
