diff options
| author | Tatsuya Kinoshita <tats@vega.ocn.ne.jp> | 2011-05-04 07:38:07 +0000 | 
|---|---|---|
| committer | Tatsuya Kinoshita <tats@vega.ocn.ne.jp> | 2011-05-04 07:38:07 +0000 | 
| commit | fa32682a5bfdd176e582cf6128a3c40c1c0cd189 (patch) | |
| tree | e53c179239dcfb65582c3bb844896b678c9f61cd | |
| parent | Releasing debian version 0.5.2-6 (diff) | |
| download | w3m-fa32682a5bfdd176e582cf6128a3c40c1c0cd189.tar.gz w3m-fa32682a5bfdd176e582cf6128a3c40c1c0cd189.zip | |
Releasing debian version 0.5.2-7debian/0.5.2-7
| -rw-r--r-- | debian/changelog | 31 | ||||
| -rw-r--r-- | debian/patches/100_download-error-short-write.patch | 188 | ||||
| -rw-r--r-- | debian/patches/110_no-graph-restriction.patch | 11756 | ||||
| -rw-r--r-- | debian/patches/120_config-file-handling.patch | 38 | ||||
| -rw-r--r-- | debian/patches/130_rc-blank-line-fix.patch | 23 | ||||
| -rw-r--r-- | debian/patches/140_pseudo-inlines.patch | 75 | ||||
| -rw-r--r-- | debian/patches/150_numbered-links.patch | 163 | ||||
| -rw-r--r-- | debian/patches/160_tls-sni.patch | 18 | ||||
| -rw-r--r-- | debian/patches/170_number-prefix.patch | 39 | ||||
| -rw-r--r-- | debian/patches/180_non-xterm.patch | 32 | ||||
| -rw-r--r-- | debian/patches/190_codepage.patch | 196 | ||||
| -rw-r--r-- | debian/patches/series | 10 | 
12 files changed, 12569 insertions, 0 deletions
| diff --git a/debian/changelog b/debian/changelog index d70bedb..3a56464 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,34 @@ +w3m (0.5.2-7) unstable; urgency=low + +  * debian/patches/100_download-error-short-write.patch: Patch to tell a +    download failure when full disk, provided by Karsten Schoelzel. +    (Closes: #185006, #206605) +  * debian/patches/110_no-graph-restriction.patch: Patch to restrict table +    and menu borders to ASCII if you use -no-graph, provided by Karsten +    Schoelzel. (Closes: #261174, #394265) +  * debian/patches/120_config-file-handling.patch: Patch to fix segfault +    when changing options if ~/.w3m not accessible, provided by Karsten +    Schoelzel. (Closes: #366284) +  * debian/patches/130_rc-blank-line-fix.patch: Patch to fix .w3m/config +    parser confused by blank lines, provided by Trent W. Buck. +    (Closes: #537706) +  * debian/patches/140_pseudo-inlines.patch: Patch to add a new option +    "pseudo_inlines", provided by Karsten Schoelzel. +    (Closes: #329863) +  * debian/patches/150_numbered-links.patch: Patch to add a new option +    "display_link_number", provided by Karsten Schoelzel. +    (Closes: #329862) +  * debian/patches/160_tls-sni.patch: Patch to add support for TLS SNI, +    provided by Sascha Silbe. (Closes: #523159) +  * debian/patches/170_number-prefix.patch: Patch to make number prefixes +    working when vi_prec_num=0, from upstream. +  * debian/patches/180_non-xterm.patch: Patch to fix segfault on non-xterm, +    from upstream. +  * debian/patches/190_codepage.patch: Patch for handling of codepage with +    wc_codepage, from upstream. + + -- Tatsuya Kinoshita <tats@debian.org>  Sun, 18 Jul 2010 08:17:08 +0900 +  w3m (0.5.2-6) unstable; urgency=low    * debian/patches/070_form-update.patch: Patch to fix a problem of diff --git a/debian/patches/100_download-error-short-write.patch b/debian/patches/100_download-error-short-write.patch new file mode 100644 index 0000000..d1af5aa --- /dev/null +++ b/debian/patches/100_download-error-short-write.patch @@ -0,0 +1,188 @@ +Description: Tell a download failure when full disk +Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=185006#22 +Author: Karsten Schoelzel <kuser@gmx.de> +Bug-Debian: http://bugs.debian.org/185006 + +diff -urNp w3m-0.5.2.orig/file.c w3m-0.5.2/file.c +--- w3m-0.5.2.orig/file.c	2007-05-24 00:06:05.000000000 +0900 ++++ w3m-0.5.2/file.c	2010-07-07 22:12:03.000000000 +0900 +@@ -7749,7 +7749,13 @@ save2tmp(URLFile uf, char *tmpf) +     { + 	Str buf = Strnew_size(SAVE_BUF_SIZE); + 	while (UFread(&uf, buf, SAVE_BUF_SIZE)) { +-	    Strfputs(buf, ff); ++	    if (Strfputs(buf, ff) != buf->length) { ++		bcopy(env_bak, AbortLoading, sizeof(JMP_BUF)); ++		TRAP_OFF; ++		fclose(ff); ++		current_content_length = 0; ++		return -2; ++	    } + 	    linelen += buf->length; + 	    showProgress(&linelen, &trbyte); + 	} +@@ -8078,16 +8084,20 @@ doFileSave(URLFile uf, char *defstr) + 	flush_tty(); + 	pid = fork(); + 	if (!pid) { ++	    int err; + 	    if ((uf.content_encoding != CMP_NOCOMPRESS) && AutoUncompress) { + 		uncompress_stream(&uf, &tmpf); + 		if (tmpf) + 		    unlink(tmpf); + 	    } + 	    setup_child(FALSE, 0, UFfileno(&uf)); +-	    if (!save2tmp(uf, p) && PreserveTimestamp && uf.modtime != -1) ++	    err = save2tmp(uf, p); ++	    if (err == 0 && PreserveTimestamp && uf.modtime != -1) + 		setModtime(p, uf.modtime); + 	    UFclose(&uf); + 	    unlink(lock); ++	    if (err != 0) ++		exit(-err); + 	    exit(0); + 	} + 	addDownloadList(pid, uf.url, p, lock, current_content_length); +diff -urNp w3m-0.5.2.orig/fm.h w3m-0.5.2/fm.h +--- w3m-0.5.2.orig/fm.h	2007-05-30 13:47:24.000000000 +0900 ++++ w3m-0.5.2/fm.h	2010-07-07 21:51:07.000000000 +0900 +@@ -517,7 +517,8 @@ typedef struct _DownloadList { +     char *lock; +     clen_t size; +     time_t time; +-    int ok; ++    int running; ++    int err; +     struct _DownloadList *next; +     struct _DownloadList *prev; + } DownloadList; +diff -urNp w3m-0.5.2.orig/main.c w3m-0.5.2/main.c +--- w3m-0.5.2.orig/main.c	2007-05-31 10:19:50.000000000 +0900 ++++ w3m-0.5.2/main.c	2010-07-07 21:51:07.000000000 +0900 +@@ -323,21 +323,26 @@ static void + sig_chld(int signo) + { +     int p_stat; +-#ifdef HAVE_WAITPID +     pid_t pid; +  ++#ifdef HAVE_WAITPID +     while ((pid = waitpid(-1, &p_stat, WNOHANG)) > 0) { +-	; +-    } + #elif HAVE_WAIT3 +-    int pid; +- +     while ((pid = wait3(&p_stat, WNOHANG, NULL)) > 0) { +-	; +-    } + #else +-    wait(&p_stat); ++    if ((pid = wait(&p_stat)) > 0) { + #endif ++	DownloadList *d; ++ ++	if (WIFEXITED(p_stat)) { ++	    for (d = FirstDL; d != NULL; d = d->next) { ++		if (d->pid == pid) { ++		    d->err = WEXITSTATUS(p_stat); ++		    break; ++		} ++	    } ++	} ++    } +     mySignal(SIGCHLD, sig_chld); +     return; + } +@@ -6355,7 +6360,8 @@ addDownloadList(pid_t pid, char *url, ch +     d->lock = lock; +     d->size = size; +     d->time = time(0); +-    d->ok = FALSE; ++    d->running = TRUE; ++    d->err = 0; +     d->next = NULL; +     d->prev = LastDL; +     if (LastDL) +@@ -6375,7 +6381,7 @@ checkDownloadList(void) +     if (!FirstDL) + 	return FALSE; +     for (d = FirstDL; d != NULL; d = d->next) { +-	if (!d->ok && !lstat(d->lock, &st)) ++	if (d->running && !lstat(d->lock, &st)) + 	    return TRUE; +     } +     return FALSE; +@@ -6415,15 +6421,16 @@ DownloadListBuffer(void) + 		       "<form method=internal action=download><hr>\n"); +     for (d = LastDL; d != NULL; d = d->prev) { + 	if (lstat(d->lock, &st)) +-	    d->ok = TRUE; ++	    d->running = FALSE; + 	Strcat_charp(src, "<pre>\n"); + 	Strcat(src, Sprintf("%s\n  --> %s\n  ", html_quote(d->url), + 			    html_quote(conv_from_system(d->save)))); + 	duration = cur_time - d->time; + 	if (!stat(d->save, &st)) { + 	    size = st.st_size; +-	    if (d->ok) { +-		d->size = size; ++	    if (!d->running) { ++		if (!d->err) ++		    d->size = size; + 		duration = st.st_mtime - d->time; + 	    } + 	} +@@ -6442,7 +6449,7 @@ DownloadListBuffer(void) + 		Strcat_char(src, '_'); + 	    Strcat_char(src, '\n'); + 	} +-	if (!d->ok && size < d->size) ++	if ((d->running || d->err) && size < d->size) + 	    Strcat(src, Sprintf("  %s / %s bytes (%d%%)", + 				convert_size3(size), convert_size3(d->size), + 				(int)(100.0 * size / d->size))); +@@ -6453,20 +6460,28 @@ DownloadListBuffer(void) + 	    Strcat(src, Sprintf("  %02d:%02d:%02d  rate %s/sec", + 				duration / (60 * 60), (duration / 60) % 60, + 				duration % 60, convert_size(rate, 1))); +-	    if (!d->ok && size < d->size && rate) { ++	    if (d->running && size < d->size && rate) { + 		eta = (d->size - size) / rate; + 		Strcat(src, Sprintf("  eta %02d:%02d:%02d", eta / (60 * 60), + 				    (eta / 60) % 60, eta % 60)); + 	    } + 	} + 	Strcat_char(src, '\n'); +-	if (d->ok) { ++	if (!d->running) { + 	    Strcat(src, Sprintf("<input type=submit name=ok%d value=OK>", + 				d->pid)); +-	    if (size < d->size) +-		Strcat_charp(src, " Download incompleted"); +-	    else +-		Strcat_charp(src, " Download completed"); ++	    switch (d->err) { ++	    case 0: if (size < d->size) ++			Strcat_charp(src, " Download ended but probably not complete"); ++		    else ++			Strcat_charp(src, " Download complete"); ++		    break; ++	    case 1: Strcat_charp(src, " Error: could not open destination file"); ++		    break; ++	    case 2: Strcat_charp(src, " Error: could not write to file (disk full)"); ++		    break; ++	    default: Strcat_charp(src, " Error: unknown reason"); ++	    } + 	} + 	else + 	    Strcat(src, Sprintf("<input type=submit name=stop%d value=STOP>", +@@ -6520,7 +6535,7 @@ stopDownload(void) +     if (!FirstDL) + 	return; +     for (d = FirstDL; d != NULL; d = d->next) { +-	if (d->ok) ++	if (!d->running) + 	    continue; + #ifndef __MINGW32_VERSION + 	kill(d->pid, SIGKILL); diff --git a/debian/patches/110_no-graph-restriction.patch b/debian/patches/110_no-graph-restriction.patch new file mode 100644 index 0000000..2e0f499 --- /dev/null +++ b/debian/patches/110_no-graph-restriction.patch @@ -0,0 +1,11756 @@ +Description: Restrict table and menu borders to ASCII if you use -no-graph + Make it possible to restrict table and menu borders to ASCII characters. + This is now done with -no-graph and the old meaning of -no-graph is + accessible through -o graphic_char=0 + The values of graphic_char now have a strange order to be compatible with + older configs. It might be better to make the order natural. +Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=261174#10 +Author: Karsten Schoelzel <kuser@gmx.de> +Bug-Debian: http://bugs.debian.org/261174 + +diff -urN w3m-0.5.2.orig/fm.h w3m-0.5.2/fm.h +--- w3m-0.5.2.orig/fm.h	2007-05-30 13:47:24.000000000 +0900 ++++ w3m-0.5.2/fm.h	2010-07-18 08:13:26.000000000 +0900 +@@ -1055,7 +1055,10 @@ + #define wc_Str_conv_strict(x,charset0,charset1) (x) + #endif + global char UseAltEntity init(TRUE); +-global char UseGraphicChar init(FALSE); ++#define GRAPHIC_CHAR_ASCII 2 ++#define GRAPHIC_CHAR_CHARSET 0 ++#define GRAPHIC_CHAR_ALL 1 ++global char UseGraphicChar init(GRAPHIC_CHAR_ASCII); + extern char *graph_symbol[]; + extern char *graph2_symbol[]; + extern int symbol_width; +diff -urN w3m-0.5.2.orig/fm.h.orig w3m-0.5.2/fm.h.orig +--- w3m-0.5.2.orig/fm.h.orig	1970-01-01 09:00:00.000000000 +0900 ++++ w3m-0.5.2/fm.h.orig	2007-05-30 13:47:24.000000000 +0900 +@@ -0,0 +1,1191 @@ ++/* $Id: fm.h,v 1.138 2007/05/30 04:47:24 inu Exp $ */ ++/*  ++ * w3m: WWW wo Miru utility ++ *  ++ * by A.ITO  Feb. 1995 ++ *  ++ * You can use,copy,modify and distribute this program without any permission. ++ */ ++ ++#ifndef FM_H ++#define FM_H ++ ++ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE		/* strcasestr() */ ++#endif ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <unistd.h> ++#include "config.h" ++#include "history.h" ++ ++#ifdef USE_MENU ++#define MENU_SELECT ++#define MENU_MAP ++#endif				/* USE_MENU */ ++ ++#ifndef USE_COLOR ++#undef USE_ANSI_COLOR ++#undef USE_BG_COLOR ++#endif ++ ++#include "ctrlcode.h" ++#include "html.h" ++#include <gc.h> ++#include "Str.h" ++#ifdef USE_M17N ++#include "wc.h" ++#include "wtf.h" ++#else ++typedef int wc_ces;	/* XXX: not used */ ++#endif ++ ++#ifdef HAVE_LOCALE_H ++#include <locale.h> ++#endif ++#if !HAVE_SETLOCALE ++#define setlocale(category, locale)	/* empty */ ++#endif ++ ++#ifdef ENABLE_NLS ++#include <libintl.h> ++#define _(String) gettext (String) ++#define N_(String) (String) ++#else ++# undef bindtextdomain ++# define bindtextdomain(Domain, Directory)	/* empty */ ++# undef textdomain ++# define textdomain(Domain)	/* empty */ ++# define _(Text) Text ++# define N_(Text) Text ++# define gettext(Text) Text ++#endif ++ ++#include "form.h" ++#include "frame.h" ++#include "parsetag.h" ++#include "parsetagx.h" ++#include "func.h" ++#include "menu.h" ++#include "textlist.h" ++#include "funcname1.h" ++#include "terms.h" ++ ++#ifndef HAVE_BCOPY ++void bcopy(const void *, void *, int); ++void bzero(void *, int); ++#endif				/* HAVE_BCOPY */ ++#ifdef __EMX__ ++#include <strings.h>		/* for bzero() and bcopy() */ ++#endif ++ ++#ifdef MAINPROGRAM ++#define global ++#define init(x) =(x) ++#else				/* not MAINPROGRAM */ ++#define global extern ++#define init(x) ++#endif				/* not MAINPROGRAM */ ++ ++#define DEFUN(funcname, macroname, docstring) void funcname(void) ++ ++/*  ++ * Constants. ++ */ ++#define LINELEN	256		/* Initial line length */ ++#define PAGER_MAX_LINE	10000	/* Maximum line kept as pager */ ++ ++#ifdef USE_IMAGE ++#define MAX_IMAGE 1000 ++#define MAX_IMAGE_SIZE 2048 ++ ++#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 ++ ++#ifdef FALSE ++#undef FALSE ++#endif ++ ++#ifdef TRUE ++#undef TRUE ++#endif ++ ++#define FALSE 0 ++#define TRUE   1 ++ ++#define SHELLBUFFERNAME	"*Shellout*" ++#define PIPEBUFFERNAME	"*stream*" ++#define CPIPEBUFFERNAME	"*stream(closed)*" ++#ifdef USE_DICT ++#define DICTBUFFERNAME "*dictionary*" ++#endif				/* USE_DICT */ ++ ++/*  ++ * Line Property ++ */ ++ ++#define P_CHARTYPE	0x3f00 ++#ifdef USE_M17N ++#define PC_ASCII	(WTF_TYPE_ASCII << 8) ++#define PC_CTRL		(WTF_TYPE_CTRL << 8) ++#define PC_WCHAR1	(WTF_TYPE_WCHAR1 << 8) ++#define PC_WCHAR2	(WTF_TYPE_WCHAR2 << 8) ++#define PC_KANJI	(WTF_TYPE_WIDE << 8) ++#define PC_KANJI1	(PC_WCHAR1 | PC_KANJI) ++#define PC_KANJI2	(PC_WCHAR2 | PC_KANJI) ++#define PC_UNKNOWN	(WTF_TYPE_UNKNOWN << 8) ++#define PC_UNDEF	(WTF_TYPE_UNDEF << 8) ++#else ++#define PC_ASCII	0x0000 ++#define PC_CTRL		0x0100 ++#endif ++#define PC_SYMBOL       0x8000 ++ ++/* Effect ( standout/underline ) */ ++#define P_EFFECT	0x40ff ++#define PE_NORMAL	0x00 ++#define PE_MARK		0x01 ++#define PE_UNDER	0x02 ++#define PE_STAND	0x04 ++#define PE_BOLD		0x08 ++#define PE_ANCHOR       0x10 ++#define PE_EMPH         0x08 ++#define PE_IMAGE        0x20 ++#define PE_FORM         0x40 ++#define PE_ACTIVE	0x80 ++#define PE_VISITED	0x4000 ++ ++/* Extra effect */ ++#define PE_EX_ITALIC	0x01 ++#define PE_EX_INSERT	0x02 ++#define PE_EX_STRIKE	0x04 ++ ++#define PE_EX_ITALIC_E	PE_UNDER ++#define PE_EX_INSERT_E	PE_UNDER ++#define PE_EX_STRIKE_E	PE_STAND ++ ++#define CharType(c)	((c)&P_CHARTYPE) ++#define CharEffect(c)	((c)&(P_EFFECT|PC_SYMBOL)) ++#define SetCharType(v,c)	((v)=(((v)&~P_CHARTYPE)|(c))) ++ ++ ++#define COLPOS(l,c)	calcPosition(l->lineBuf,l->propBuf,l->len,c,0,CP_AUTO) ++ ++/* Flags for displayBuffer() */ ++#define B_NORMAL	0 ++#define B_FORCE_REDRAW	1 ++#define B_REDRAW	2 ++#define B_SCROLL        3 ++#define B_REDRAW_IMAGE	4 ++ ++/* Buffer Property */ ++#define BP_NORMAL	0x0 ++#define BP_PIPE		0x1 ++#define BP_FRAME	0x2 ++#define BP_INTERNAL	0x8 ++#define BP_NO_URL	0x10 ++#define BP_REDIRECTED   0x20 ++#define BP_CLOSE        0x40 ++ ++/* Link Buffer */ ++#define LB_NOLINK	-1 ++#define LB_FRAME	0	/* rFrame() */ ++#define LB_N_FRAME	1 ++#define LB_INFO		2	/* pginfo() */ ++#define LB_N_INFO	3 ++#define LB_SOURCE	4	/* vwSrc() */ ++#define LB_N_SOURCE	LB_SOURCE ++#define MAX_LB		5 ++ ++/* Search Result */ ++#define SR_FOUND       0x1 ++#define SR_NOTFOUND    0x2 ++#define SR_WRAPPED     0x4 ++ ++#ifdef MAINPROGRAM ++int REV_LB[MAX_LB] = { ++    LB_N_FRAME, LB_FRAME, LB_N_INFO, LB_INFO, LB_N_SOURCE, ++}; ++#else				/* not MAINPROGRAM */ ++extern int REV_LB[]; ++#endif				/* not MAINPROGRAM */ ++ ++/* mark URL, Message-ID */ ++#define CHK_URL                1 ++#define CHK_NMID       2 ++ ++/* Flags for calcPosition() */ ++#define CP_AUTO		0 ++#define CP_FORCE	1 ++ ++/* Completion status. */ ++#define CPL_OK		0 ++#define CPL_AMBIG	1 ++#define CPL_FAIL	2 ++#define CPL_MENU	3 ++ ++#define CPL_NEVER	0x0 ++#define CPL_OFF		0x1 ++#define CPL_ON		0x2 ++#define CPL_ALWAYS	0x4 ++#define CPL_URL		0x8 ++ ++/* Flags for inputLine() */ ++#define IN_STRING	0x10 ++#define IN_FILENAME	0x20 ++#define IN_PASSWORD	0x40 ++#define IN_COMMAND	0x80 ++#define IN_URL		0x100 ++#define IN_CHAR		0x200 ++ ++#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 ++#define IMG_FLAG_DONT_REMOVE	4 ++ ++/*  ++ * Macros. ++ */ ++ ++#define inputLineHist(p,d,f,h)	inputLineHistSearch(p,d,f,h,NULL) ++#define inputLine(p,d,f)	inputLineHist(p,d,f,NULL) ++#define inputStr(p,d)		inputLine(p,d,IN_STRING) ++#define inputStrHist(p,d,h)	inputLineHist(p,d,IN_STRING,h) ++#define inputFilename(p,d)	inputLine(p,d,IN_FILENAME) ++#define inputFilenameHist(p,d,h)	inputLineHist(p,d,IN_FILENAME,h) ++#define inputChar(p)		inputLine(p,"",IN_CHAR) ++ ++#define free(x)  GC_free(x)	/* let GC do it. */ ++ ++#ifdef __EMX__ ++#define HAVE_STRCASECMP ++#define strcasecmp	stricmp ++#define strncasecmp	strnicmp ++#endif				/* __EMX__ */ ++ ++ ++#define SKIP_BLANKS(p) {while(*(p)&&IS_SPACE(*(p)))(p)++;} ++#define SKIP_NON_BLANKS(p) {while(*(p)&&!IS_SPACE(*(p)))(p)++;} ++#define IS_ENDL(c) ((c)=='\0'||(c)=='\r'||(c)=='\n') ++#define IS_ENDT(c) (IS_ENDL(c)||(c)==';') ++ ++#define bpcmp(a,b) \ ++  (((a).line - (b).line) ? ((a).line - (b).line) : ((a).pos - (b).pos)) ++ ++#define RELATIVE_WIDTH(w)   (((w)>=0)?(int)((w)/pixel_per_char):(w)) ++#define REAL_WIDTH(w,limit) (((w)>=0)?(int)((w)/pixel_per_char):-(w)*(limit)/100) ++ ++#define EOL(l) (&(l)->ptr[(l)->length]) ++#define IS_EOL(p,l) ((p)==&(l)->ptr[(l)->length]) ++ ++/*  ++ * Types. ++ */ ++ ++typedef unsigned short Lineprop; ++#ifdef USE_ANSI_COLOR ++typedef unsigned char Linecolor; ++#endif ++ ++typedef struct _MapArea { ++    char *url; ++    char *target; ++    char *alt; ++#ifdef USE_IMAGE ++    char shape; ++    short *coords; ++    int ncoords; ++    short center_x; ++    short center_y; ++#endif ++} MapArea; ++ ++typedef struct _MapList { ++    Str name; ++    GeneralList *area; ++    struct _MapList *next; ++} MapList; ++ ++typedef struct _Line { ++    char *lineBuf; ++    Lineprop *propBuf; ++#ifdef USE_ANSI_COLOR ++    Linecolor *colorBuf; ++#endif ++    struct _Line *next; ++    struct _Line *prev; ++    int len; ++    int width; ++    long linenumber;		/* on buffer */ ++    long real_linenumber;	/* on file */ ++    unsigned short usrflags; ++    int size; ++    int bpos; ++    int bwidth; ++} Line; ++ ++typedef struct { ++    int line; ++    int pos; ++    int invalid; ++} BufferPoint; ++ ++#ifdef USE_IMAGE ++typedef struct _imageCache { ++    char *url; ++    ParsedURL *current; ++    char *file; ++    char *touch; ++    pid_t pid; ++    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; ++    char *referer; ++    char *title; ++    unsigned char accesskey; ++    BufferPoint start; ++    BufferPoint end; ++    int hseq; ++    char slave; ++    short y; ++    short rows; ++#ifdef USE_IMAGE ++    Image *image; ++#endif ++} Anchor; ++ ++#define NO_REFERER ((char*)-1) ++ ++typedef struct _anchorList { ++    Anchor *anchors; ++    int nanchor; ++    int anchormax; ++    int acache; ++} AnchorList; ++ ++typedef struct { ++    BufferPoint *marks; ++    int nmark; ++    int markmax; ++    int prevhseq; ++} HmarkerList; ++ ++#define LINK_TYPE_NONE 0 ++#define LINK_TYPE_REL  1 ++#define LINK_TYPE_REV  2 ++typedef struct _LinkList { ++    char *url; ++    char *title;		/* Next, Contents, ... */ ++    char *ctype;		/* Content-Type */ ++    char type;			/* Rel, Rev */ ++    struct _LinkList *next; ++} LinkList; ++ ++typedef struct _Buffer { ++    char *filename; ++    char *buffername; ++    Line *firstLine; ++    Line *topLine; ++    Line *currentLine; ++    Line *lastLine; ++    struct _Buffer *nextBuffer; ++    struct _Buffer *linkBuffer[MAX_LB]; ++    short width; ++    short height; ++    char *type; ++    char *real_type; ++    int allLine; ++    short bufferprop; ++    int currentColumn; ++    short cursorX; ++    short cursorY; ++    int pos; ++    int visualpos; ++    short rootX; ++    short rootY; ++    short COLS; ++    short LINES; ++    InputStream pagerSource; ++    AnchorList *href; ++    AnchorList *name; ++    AnchorList *img; ++    AnchorList *formitem; ++    LinkList *linklist; ++    FormList *formlist; ++    MapList *maplist; ++    HmarkerList *hmarklist; ++    HmarkerList *imarklist; ++    ParsedURL currentURL; ++    ParsedURL *baseURL; ++    char *baseTarget; ++    int real_scheme; ++    char *sourcefile; ++    struct frameset *frameset; ++    struct frameset_queue *frameQ; ++    int *clone; ++    size_t trbyte; ++    char check_url; ++#ifdef USE_M17N ++    wc_ces document_charset; ++    wc_uint8 auto_detect; ++#endif ++    TextList *document_header; ++    FormItemList *form_submit; ++    char *savecache; ++    char *edit; ++    struct mailcap *mailcap; ++    char *mailcap_source; ++    char *header_source; ++    char search_header; ++#ifdef USE_SSL ++    char *ssl_certificate; ++#endif ++    char image_flag; ++    char image_loaded; ++    char need_reshape; ++    Anchor *submit; ++    struct _BufferPos *undo; ++#ifdef USE_ALARM ++    struct _AlarmEvent *event; ++#endif ++} Buffer; ++ ++typedef struct _BufferPos { ++    long top_linenumber; ++    long cur_linenumber; ++    int currentColumn; ++    int pos; ++    int bpos; ++    struct _BufferPos *next; ++    struct _BufferPos *prev; ++} BufferPos; ++ ++typedef struct _TabBuffer { ++    struct _TabBuffer *nextTab; ++    struct _TabBuffer *prevTab; ++    Buffer *currentBuffer; ++    Buffer *firstBuffer; ++    short x1; ++    short x2; ++    short y; ++} TabBuffer; ++ ++typedef struct _DownloadList { ++    pid_t pid; ++    char *url; ++    char *save; ++    char *lock; ++    clen_t size; ++    time_t time; ++    int ok; ++    struct _DownloadList *next; ++    struct _DownloadList *prev; ++} DownloadList; ++#define DOWNLOAD_LIST_TITLE "Download List Panel" ++ ++#define COPY_BUFROOT(dstbuf, srcbuf) {\ ++ (dstbuf)->rootX = (srcbuf)->rootX; \ ++ (dstbuf)->rootY = (srcbuf)->rootY; \ ++ (dstbuf)->COLS = (srcbuf)->COLS; \ ++ (dstbuf)->LINES = (srcbuf)->LINES; \ ++} ++ ++#define COPY_BUFPOSITION(dstbuf, srcbuf) {\ ++ (dstbuf)->topLine = (srcbuf)->topLine; \ ++ (dstbuf)->currentLine = (srcbuf)->currentLine; \ ++ (dstbuf)->pos = (srcbuf)->pos; \ ++ (dstbuf)->cursorX = (srcbuf)->cursorX; \ ++ (dstbuf)->cursorY = (srcbuf)->cursorY; \ ++ (dstbuf)->visualpos = (srcbuf)->visualpos; \ ++ (dstbuf)->currentColumn = (srcbuf)->currentColumn; \ ++} ++#define SAVE_BUFPOSITION(sbufp) COPY_BUFPOSITION(sbufp, Currentbuf) ++#define RESTORE_BUFPOSITION(sbufp) COPY_BUFPOSITION(Currentbuf, sbufp) ++#define TOP_LINENUMBER(buf) ((buf)->topLine ? (buf)->topLine->linenumber : 1) ++#define CUR_LINENUMBER(buf) ((buf)->currentLine ? (buf)->currentLine->linenumber : 1) ++ ++#define NO_BUFFER ((Buffer*)1) ++ ++#define RB_STACK_SIZE 10 ++ ++#define TAG_STACK_SIZE 10 ++ ++#define FONT_STACK_SIZE 5 ++ ++#define FONTSTAT_SIZE 7 ++ ++#define _INIT_BUFFER_WIDTH (COLS - (showLineNum ? 6 : 1)) ++#define INIT_BUFFER_WIDTH ((_INIT_BUFFER_WIDTH > 0) ? _INIT_BUFFER_WIDTH : 0) ++#define FOLD_BUFFER_WIDTH (FoldLine ? (INIT_BUFFER_WIDTH + 1) : -1) ++ ++typedef struct { ++    int pos; ++    int len; ++    int tlen; ++    long flag; ++    Anchor anchor; ++    Str img_alt; ++    char fontstat[FONTSTAT_SIZE]; ++    short nobr_level; ++    Lineprop prev_ctype; ++    char init_flag; ++    short top_margin; ++    short bottom_margin; ++} Breakpoint; ++ ++struct readbuffer { ++    Str line; ++    Lineprop cprop; ++    short pos; ++    Str prevchar; ++    long flag; ++    long flag_stack[RB_STACK_SIZE]; ++    int flag_sp; ++    int status; ++    unsigned char end_tag; ++    short table_level; ++    short nobr_level; ++    Anchor anchor; ++    Str img_alt; ++    char fontstat[FONTSTAT_SIZE]; ++    char fontstat_stack[FONT_STACK_SIZE][FONTSTAT_SIZE]; ++    int fontstat_sp; ++    Lineprop prev_ctype; ++    Breakpoint bp; ++    struct cmdtable *tag_stack[TAG_STACK_SIZE]; ++    int tag_sp; ++    short top_margin; ++    short bottom_margin; ++}; ++ ++#define in_bold fontstat[0] ++#define in_under fontstat[1] ++#define in_italic fontstat[2] ++#define in_strike fontstat[3] ++#define in_ins fontstat[4] ++#define in_stand fontstat[5] ++ ++#define RB_PRE		0x01 ++#define RB_SCRIPT	0x02 ++#define RB_STYLE	0x04 ++#define RB_PLAIN	0x08 ++#define RB_LEFT		0x10 ++#define RB_CENTER	0x20 ++#define RB_RIGHT	0x40 ++#define RB_ALIGN	(RB_LEFT| RB_CENTER | RB_RIGHT) ++#define RB_NOBR		0x80 ++#define RB_P		0x100 ++#define RB_PRE_INT	0x200 ++#define RB_IN_DT	0x400 ++#define RB_INTXTA	0x800 ++#define RB_INSELECT	0x1000 ++#define RB_IGNORE_P	0x2000 ++#define RB_TITLE	0x4000 ++#define RB_NFLUSHED	0x8000 ++#define RB_NOFRAMES	0x10000 ++#define RB_INTABLE	0x20000 ++#define RB_PREMODE	(RB_PRE | RB_PRE_INT | RB_SCRIPT | RB_STYLE | RB_PLAIN | RB_INTXTA) ++#define RB_SPECIAL	(RB_PRE | RB_PRE_INT | RB_SCRIPT | RB_STYLE | RB_PLAIN | RB_NOBR) ++#define RB_PLAIN_PRE	0x40000 ++ ++#ifdef FORMAT_NICE ++#define RB_FILL		0x80000 ++#endif				/* FORMAT_NICE */ ++#define RB_DEL		0x100000 ++#define RB_S		0x200000 ++ ++#define RB_GET_ALIGN(obuf) ((obuf)->flag&RB_ALIGN) ++#define RB_SET_ALIGN(obuf,align) {(obuf)->flag &= ~RB_ALIGN; (obuf)->flag |= (align); } ++#define RB_SAVE_FLAG(obuf) {\ ++  if ((obuf)->flag_sp < RB_STACK_SIZE) \ ++    (obuf)->flag_stack[(obuf)->flag_sp++] = RB_GET_ALIGN(obuf); \ ++} ++#define RB_RESTORE_FLAG(obuf) {\ ++  if ((obuf)->flag_sp > 0) \ ++   RB_SET_ALIGN(obuf,(obuf)->flag_stack[--(obuf)->flag_sp]); \ ++} ++ ++/* status flags */ ++#define R_ST_NORMAL 0		/* normal */ ++#define R_ST_TAG0   1		/* within tag, just after < */ ++#define R_ST_TAG    2		/* within tag */ ++#define R_ST_QUOTE  3		/* within single quote */ ++#define R_ST_DQUOTE 4		/* within double quote */ ++#define R_ST_EQL    5		/* = */ ++#define R_ST_AMP    6		/* within ampersand quote */ ++#define R_ST_EOL    7		/* end of file */ ++#define R_ST_CMNT1  8		/* <!  */ ++#define R_ST_CMNT2  9		/* <!- */ ++#define R_ST_CMNT   10		/* within comment */ ++#define R_ST_NCMNT1 11		/* comment - */ ++#define R_ST_NCMNT2 12		/* comment -- */ ++#define R_ST_NCMNT3 13		/* comment -- space */ ++#define R_ST_IRRTAG 14		/* within irregular tag */ ++#define R_ST_VALUE  15		/* within tag attribule value */ ++ ++#define ST_IS_REAL_TAG(s)   ((s)==R_ST_TAG||(s)==R_ST_TAG0||(s)==R_ST_EQL||(s)==R_ST_VALUE) ++ ++/* is this '<' really means the beginning of a tag? */ ++#define REALLY_THE_BEGINNING_OF_A_TAG(p) \ ++	  (IS_ALPHA(p[1]) || p[1] == '/' || p[1] == '!' || p[1] == '?' || p[1] == '\0' || p[1] == '_') ++ ++/* flags for loadGeneralFile */ ++#define RG_NOCACHE   1 ++#define RG_FRAME     2 ++#define RG_FRAME_SRC 4 ++ ++struct html_feed_environ { ++    struct readbuffer *obuf; ++    TextLineList *buf; ++    FILE *f; ++    Str tagbuf; ++    int limit; ++    int maxlimit; ++    struct environment *envs; ++    int nenv; ++    int envc; ++    int envc_real; ++    char *title; ++    int blank_lines; ++}; ++ ++#ifdef USE_COOKIE ++struct portlist { ++    unsigned short port; ++    struct portlist *next; ++}; ++ ++struct cookie { ++    ParsedURL url; ++    Str name; ++    Str value; ++    time_t expires; ++    Str path; ++    Str domain; ++    Str comment; ++    Str commentURL; ++    struct portlist *portl; ++    char version; ++    char flag; ++    struct cookie *next; ++}; ++#define COO_USE		1 ++#define COO_SECURE	2 ++#define COO_DOMAIN	4 ++#define COO_PATH	8 ++#define COO_DISCARD	16 ++#define COO_OVERRIDE	32	/* user chose to override security checks */ ++ ++#define COO_OVERRIDE_OK	32	/* flag to specify that an error is overridable */ ++						/* version 0 refers to the original cookie_spec.html */ ++						/* version 1 refers to RFC 2109 */ ++						/* version 1' refers to the Internet draft to obsolete RFC 2109 */ ++#define COO_EINTERNAL	(1)	/* unknown error; probably forgot to convert "return 1" in cookie.c */ ++#define COO_ETAIL	(2 | COO_OVERRIDE_OK)	/* tail match failed (version 0) */ ++#define COO_ESPECIAL	(3)	/* special domain check failed (version 0) */ ++#define COO_EPATH	(4)	/* Path attribute mismatch (version 1 case 1) */ ++#define COO_ENODOT	(5 | COO_OVERRIDE_OK)	/* no embedded dots in Domain (version 1 case 2.1) */ ++#define COO_ENOTV1DOM	(6 | COO_OVERRIDE_OK)	/* Domain does not start with a dot (version 1 case 2.2) */ ++#define COO_EDOM	(7 | COO_OVERRIDE_OK)	/* domain-match failed (version 1 case 3) */ ++#define COO_EBADHOST	(8 | COO_OVERRIDE_OK)	/* dot in matched host name in FQDN (version 1 case 4) */ ++#define COO_EPORT	(9)	/* Port match failed (version 1' case 5) */ ++#define COO_EMAX	COO_EPORT ++#endif				/* USE_COOKIE */ ++ ++/* modes for align() */ ++ ++#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 ++#define VALIGN_BOTTOM 2 ++ ++typedef struct http_request { ++    char command; ++    char flag; ++    char *referer; ++    FormList *request; ++} HRequest; ++ ++#define HR_COMMAND_GET		0 ++#define HR_COMMAND_POST		1 ++#define HR_COMMAND_CONNECT	2 ++#define HR_COMMAND_HEAD		3 ++ ++#define HR_FLAG_LOCAL		1 ++#define HR_FLAG_PROXY		2 ++ ++#define HTST_UNKNOWN		255 ++#define HTST_MISSING		254 ++#define HTST_NORMAL		0 ++#define HTST_CONNECT		1 ++ ++#define TMPF_DFL	0 ++#define TMPF_SRC	1 ++#define TMPF_FRAME	2 ++#define TMPF_CACHE	3 ++#define TMPF_COOKIE	4 ++#define MAX_TMPF_TYPE	5 ++ ++#define set_no_proxy(domains) (NO_proxy_domains=make_domain_list(domains)) ++ ++/*  ++ * Globals. ++ */ ++ ++extern int LINES, COLS; ++#if defined(__CYGWIN__) ++extern int LASTLINE; ++#else				/* not defined(__CYGWIN__) */ ++#define LASTLINE (LINES-1) ++#endif				/* not defined(__CYGWIN__) */ ++ ++global int Tabstop init(8); ++global int IndentIncr init(4); ++global int ShowEffect init(TRUE); ++global int PagerMax init(PAGER_MAX_LINE); ++ ++global char SearchHeader init(FALSE); ++global char *DefaultType init(NULL); ++global char RenderFrame init(FALSE); ++global char TargetSelf init(FALSE); ++global char PermitSaveToPipe init(FALSE); ++global char DecodeCTE init(FALSE); ++global char AutoUncompress init(FALSE); ++global char PreserveTimestamp init(TRUE); ++global char ArgvIsURL init(FALSE); ++global char MetaRefresh init(FALSE); ++ ++global char fmInitialized init(FALSE); ++global char QuietMessage init(FALSE); ++global char TrapSignal init(TRUE); ++#define TRAP_ON if (TrapSignal) { \ ++    prevtrap = mySignal(SIGINT, KeyAbort); \ ++    if (fmInitialized) \ ++	term_cbreak(); \ ++} ++#define TRAP_OFF if (TrapSignal) { \ ++    if (fmInitialized) \ ++	term_raw(); \ ++    if (prevtrap) \ ++	mySignal(SIGINT, prevtrap); \ ++} ++ ++extern unsigned char GlobalKeymap[]; ++extern unsigned char EscKeymap[]; ++extern unsigned char EscBKeymap[]; ++extern unsigned char EscDKeymap[]; ++#ifdef __EMX__ ++extern unsigned char PcKeymap[]; ++#endif ++extern FuncList w3mFuncList[]; ++ ++global char *HTTP_proxy init(NULL); ++#ifdef USE_SSL ++global char *HTTPS_proxy init(NULL); ++#endif				/* USE_SSL */ ++#ifdef USE_GOPHER ++global char *GOPHER_proxy init(NULL); ++#endif				/* USE_GOPHER */ ++global char *FTP_proxy init(NULL); ++global ParsedURL HTTP_proxy_parsed; ++#ifdef USE_SSL ++global ParsedURL HTTPS_proxy_parsed; ++#endif				/* USE_SSL */ ++#ifdef USE_GOPHER ++global ParsedURL GOPHER_proxy_parsed; ++#endif				/* USE_GOPHER */ ++global ParsedURL FTP_proxy_parsed; ++global char *NO_proxy init(NULL); ++global int NOproxy_netaddr init(TRUE); ++#ifdef INET6 ++#define DNS_ORDER_UNSPEC     0 ++#define DNS_ORDER_INET_INET6 1 ++#define DNS_ORDER_INET6_INET 2 ++#define DNS_ORDER_INET_ONLY  4 ++#define DNS_ORDER_INET6_ONLY 6 ++global int DNS_order init(DNS_ORDER_UNSPEC); ++extern int ai_family_order_table[7][3];	/* XXX */ ++#endif				/* INET6 */ ++global TextList *NO_proxy_domains; ++global char NoCache init(FALSE); ++global char use_proxy init(TRUE); ++#define Do_not_use_proxy (!use_proxy) ++global int Do_not_use_ti_te init(FALSE); ++#ifdef USE_NNTP ++global char *NNTP_server init(NULL); ++global char *NNTP_mode init(NULL); ++global int MaxNewsMessage init(50); ++#endif ++ ++global char *document_root init(NULL); ++global char *personal_document_root init(NULL); ++global char *cgi_bin init(NULL); ++global char *index_file init(NULL); ++ ++global char *CurrentDir; ++global int CurrentPid; ++/* ++ * global Buffer *Currentbuf; ++ * global Buffer *Firstbuf; ++ */ ++global TabBuffer *CurrentTab; ++global TabBuffer *FirstTab; ++global TabBuffer *LastTab; ++global int open_tab_blank init(FALSE); ++global int open_tab_dl_list init(FALSE); ++global int close_tab_back init(FALSE); ++global int nTab; ++global int TabCols init(10); ++#define NO_TABBUFFER ((TabBuffer *)1) ++#define Currentbuf (CurrentTab->currentBuffer) ++#define Firstbuf (CurrentTab->firstBuffer) ++global DownloadList *FirstDL init(NULL); ++global DownloadList *LastDL init(NULL); ++global int CurrentKey; ++global char *CurrentKeyData; ++global char *CurrentCmdData; ++global char *w3m_reqlog; ++extern char *w3m_version; ++ ++#define DUMP_BUFFER   0x01 ++#define DUMP_HEAD     0x02 ++#define DUMP_SOURCE   0x04 ++#define DUMP_EXTRA    0x08 ++#define DUMP_HALFDUMP 0x10 ++#define DUMP_FRAME    0x20 ++global int w3m_debug; ++global int w3m_dump init(0); ++#define w3m_halfdump (w3m_dump & DUMP_HALFDUMP) ++global int w3m_halfload init(FALSE); ++global Str header_string init(NULL); ++global int override_content_type init(FALSE); ++ ++#ifdef USE_COLOR ++global int useColor init(TRUE); ++global int basic_color init(8);	/* don't change */ ++global int anchor_color init(4);	/* blue  */ ++global int image_color init(2);	/* green */ ++global int form_color init(1);	/* red   */ ++#ifdef USE_BG_COLOR ++global int bg_color init(8);	/* don't change */ ++global int mark_color init(6);	/* cyan */ ++#endif				/* USE_BG_COLOR */ ++global int useActiveColor init(FALSE); ++global int active_color init(6);	/* cyan */ ++global int useVisitedColor init(FALSE); ++global int visited_color init(5);	/* magenta  */ ++#endif				/* USE_COLOR */ ++global int confirm_on_quit init(TRUE); ++#ifdef USE_MARK ++global int use_mark init(FALSE); ++#endif ++global int emacs_like_lineedit init(FALSE); ++global int vi_prec_num init(FALSE); ++global int label_topline init(FALSE); ++global int nextpage_topline init(FALSE); ++global char *displayTitleTerm init(NULL); ++global int displayLink init(FALSE); ++global int displayLineInfo init(FALSE); ++global int DecodeURL init(FALSE); ++global int retryAsHttp init(TRUE); ++global int showLineNum init(FALSE); ++global int show_srch_str init(TRUE); ++#ifdef USE_IMAGE ++global char *Imgdisplay init(IMGDISPLAY); ++global int activeImage init(FALSE); ++global int displayImage init(TRUE); ++global int autoImage init(TRUE); ++global int useExtImageViewer init(TRUE); ++global int maxLoadImage init(4); ++global int image_map_list init(TRUE); ++#else ++global int displayImage init(FALSE);	/* XXX: emacs-w3m use display_image=off */ ++#endif ++global char *Editor init(DEF_EDITOR); ++#ifdef USE_W3MMAILER ++global char *Mailer init(NULL); ++#else ++global char *Mailer init(DEF_MAILER); ++#endif ++global char *ExtBrowser init(DEF_EXT_BROWSER); ++global char *ExtBrowser2 init(NULL); ++global char *ExtBrowser3 init(NULL); ++global int BackgroundExtViewer init(TRUE); ++global int disable_secret_security_check init(FALSE); ++global char *passwd_file init(PASSWD_FILE); ++global char *pre_form_file init(PRE_FORM_FILE); ++global char *ftppasswd init(NULL); ++global int ftppass_hostnamegen init(TRUE); ++global int do_download init(FALSE); ++#ifdef USE_IMAGE ++global char *image_source init(NULL); ++#endif ++global char *UserAgent init(NULL); ++global int NoSendReferer init(FALSE); ++global char *AcceptLang init(NULL); ++global char *AcceptEncoding init(NULL); ++global char *AcceptMedia init(NULL); ++global int WrapDefault init(FALSE); ++global int IgnoreCase init(TRUE); ++global int WrapSearch init(FALSE); ++global int squeezeBlankLine init(FALSE); ++global char *BookmarkFile init(NULL); ++global char *pauth init(NULL); ++global Str proxy_auth_cookie init(NULL); ++global int UseExternalDirBuffer init(TRUE); ++global char *DirBufferCommand init("file:///$LIB/dirlist" CGI_EXTENSION); ++#ifdef USE_DICT ++global int UseDictCommand init(FALSE); ++global char *DictCommand init("file:///$LIB/w3mdict" CGI_EXTENSION); ++#endif				/* USE_DICT */ ++global int ignore_null_img_alt init(TRUE); ++#define DISPLAY_INS_DEL_SIMPLE	0 ++#define DISPLAY_INS_DEL_NORMAL	1 ++#define DISPLAY_INS_DEL_FONTIFY	2 ++global int displayInsDel init(DISPLAY_INS_DEL_NORMAL); ++global int FoldTextarea init(FALSE); ++global int FoldLine init(FALSE); ++#define DEFAULT_URL_EMPTY	0 ++#define DEFAULT_URL_CURRENT	1 ++#define DEFAULT_URL_LINK	2 ++global int DefaultURLString init(DEFAULT_URL_EMPTY); ++global int MarkAllPages init(FALSE); ++ ++#ifdef USE_MIGEMO ++global int use_migemo init(FALSE); ++global int migemo_active init(0); ++global char *migemo_command init(DEF_MIGEMO_COMMAND); ++#endif				/* USE_MIGEMO */ ++ ++global struct auth_cookie *Auth_cookie init(NULL); ++#ifdef USE_COOKIE ++global struct cookie *First_cookie init(NULL); ++#endif				/* USE_COOKIE */ ++ ++global char *mailcap_files init(USER_MAILCAP ", " SYS_MAILCAP); ++global char *mimetypes_files init(USER_MIMETYPES ", " SYS_MIMETYPES); ++#ifdef USE_EXTERNAL_URI_LOADER ++global char *urimethodmap_files init(USER_URIMETHODMAP ", " SYS_URIMETHODMAP); ++#endif ++ ++global TextList *fileToDelete; ++ ++extern Hist *LoadHist; ++extern Hist *SaveHist; ++extern Hist *URLHist; ++extern Hist *ShellHist; ++extern Hist *TextHist; ++#ifdef USE_HISTORY ++global int UseHistory init(TRUE); ++global int URLHistSize init(100); ++global int SaveURLHist init(TRUE); ++#endif				/* USE_HISTORY */ ++global int multicolList init(FALSE); ++ ++#ifdef USE_M17N ++global wc_ces InnerCharset init(WC_CES_WTF);	/* Don't change */ ++global wc_ces DisplayCharset init(DISPLAY_CHARSET); ++global wc_ces DocumentCharset init(DOCUMENT_CHARSET); ++global wc_ces SystemCharset init(SYSTEM_CHARSET); ++global wc_ces BookmarkCharset init(SYSTEM_CHARSET); ++global char ExtHalfdump init(FALSE); ++global char FollowLocale init(TRUE); ++global char UseContentCharset init(TRUE); ++global char SearchConv init(TRUE); ++#define Str_conv_from_system(x) wc_Str_conv((x), SystemCharset, InnerCharset) ++#define Str_conv_to_system(x) wc_Str_conv_strict((x), InnerCharset, SystemCharset) ++#define Str_conv_to_halfdump(x) (ExtHalfdump ? wc_Str_conv((x), InnerCharset, DisplayCharset) : (x)) ++#define conv_from_system(x) wc_conv((x), SystemCharset, InnerCharset)->ptr ++#define conv_to_system(x) wc_conv_strict((x), InnerCharset, SystemCharset)->ptr ++#define url_quote_conv(x,c) url_quote(wc_conv_strict((x), InnerCharset, (c))->ptr) ++#else ++#define Str_conv_from_system(x) (x) ++#define Str_conv_to_system(x) (x) ++#define Str_conv_to_halfdump(x) (x) ++#define conv_from_system(x) (x) ++#define conv_to_system(x) (x) ++#define url_quote_conv(x,c) url_quote(x) ++#define wc_Str_conv(x,charset0,charset1) (x) ++#define wc_Str_conv_strict(x,charset0,charset1) (x) ++#endif ++global char UseAltEntity init(TRUE); ++global char UseGraphicChar init(FALSE); ++extern char *graph_symbol[]; ++extern char *graph2_symbol[]; ++extern int symbol_width; ++extern int symbol_width0; ++#define N_GRAPH_SYMBOL 32 ++#define SYMBOL_BASE 0x20 ++global int no_rc_dir init(FALSE); ++global char *rc_dir init(NULL); ++global char *tmp_dir; ++global char *config_file init(NULL); ++ ++#ifdef USE_MOUSE ++global int use_mouse init(TRUE); ++extern int mouseActive; ++global int reverse_mouse init(FALSE); ++global int relative_wheel_scroll init(FALSE); ++global int fixed_wheel_scroll_count init(5); ++global int relative_wheel_scroll_ratio init(30); ++typedef struct _MouseActionMap { ++    void (*func) (); ++    char *data; ++} MouseActionMap; ++typedef struct _MouseAction { ++    char *menu_str; ++    char *lastline_str; ++    int menu_width; ++    int lastline_width; ++    int in_action; ++    int cursorX; ++    int cursorY; ++    MouseActionMap default_map[3]; ++    MouseActionMap anchor_map[3]; ++    MouseActionMap active_map[3]; ++    MouseActionMap tab_map[3]; ++    MouseActionMap *menu_map[3]; ++    MouseActionMap *lastline_map[3]; ++} MouseAction; ++global MouseAction mouse_action; ++#define LIMIT_MOUSE_MENU 100 ++#endif				/* USE_MOUSE */ ++ ++#ifdef USE_COOKIE ++global int default_use_cookie init(TRUE); ++global int use_cookie init(FALSE); ++global int show_cookie init(TRUE); ++global int accept_cookie init(FALSE); ++#define ACCEPT_BAD_COOKIE_DISCARD	0 ++#define ACCEPT_BAD_COOKIE_ACCEPT	1 ++#define ACCEPT_BAD_COOKIE_ASK		2 ++global int accept_bad_cookie init(ACCEPT_BAD_COOKIE_DISCARD); ++global char *cookie_reject_domains init(NULL); ++global char *cookie_accept_domains init(NULL); ++global TextList *Cookie_reject_domains; ++global TextList *Cookie_accept_domains; ++#endif				/* USE_COOKIE */ ++ ++#ifdef USE_IMAGE ++global int view_unseenobject init(FALSE); ++#else ++global int view_unseenobject init(TRUE); ++#endif ++ ++#if defined(USE_SSL) && defined(USE_SSL_VERIFY) ++global int ssl_verify_server init(FALSE); ++global char *ssl_cert_file init(NULL); ++global char *ssl_key_file init(NULL); ++global char *ssl_ca_path init(NULL); ++global char *ssl_ca_file init(NULL); ++global int ssl_path_modified init(FALSE); ++#endif				/* defined(USE_SSL) && ++				 * defined(USE_SSL_VERIFY) */ ++#ifdef USE_SSL ++global char *ssl_forbid_method init(NULL); ++#endif ++ ++global int is_redisplay init(FALSE); ++global int clear_buffer init(TRUE); ++global double pixel_per_char init(DEFAULT_PIXEL_PER_CHAR); ++global int set_pixel_per_char init(FALSE); ++#ifdef USE_IMAGE ++global double pixel_per_line init(DEFAULT_PIXEL_PER_LINE); ++global int set_pixel_per_line init(FALSE); ++global double image_scale init(100); ++#endif ++global int use_lessopen init(FALSE); ++ ++global char *keymap_file init(KEYMAP_FILE); ++ ++#ifdef USE_M17N ++#define get_mctype(c) ((Lineprop)wtf_type((wc_uchar *)(c)) << 8) ++#define get_mclen(c) wtf_len1((wc_uchar *)(c)) ++#define get_mcwidth(c) wtf_width((wc_uchar *)(c)) ++#define get_strwidth(c) wtf_strwidth((wc_uchar *)(c)) ++#define get_Str_strwidth(c) wtf_strwidth((wc_uchar *)((c)->ptr)) ++#else ++#define get_mctype(c) (IS_CNTRL(*(c)) ? PC_CTRL : PC_ASCII) ++#define get_mclen(c) 1 ++#define get_mcwidth(c) 1 ++#define get_strwidth(c) strlen(c) ++#define get_Str_strwidth(c) ((c)->length) ++#endif ++ ++global int FollowRedirection init(10); ++ ++global int w3m_backend init(FALSE); ++global TextLineList *backend_halfdump_buf; ++global TextList *backend_batch_commands init(NULL); ++int backend(void); ++extern void deleteFiles(void); ++void w3m_exit(int i); ++ ++#ifdef USE_ALARM ++#define AL_UNSET         0 ++#define AL_EXPLICIT      1 ++#define AL_IMPLICIT      2 ++#define AL_IMPLICIT_ONCE 3 ++ ++typedef struct _AlarmEvent { ++    int sec; ++    short status; ++    int cmd; ++    void *data; ++} AlarmEvent; ++#endif ++ ++/*  ++ * Externals ++ */ ++ ++#include "table.h" ++#include "proto.h" ++ ++#endif				/* not FM_H */ +diff -urN w3m-0.5.2.orig/main.c w3m-0.5.2/main.c +--- w3m-0.5.2.orig/main.c	2007-05-31 10:19:50.000000000 +0900 ++++ w3m-0.5.2/main.c	2010-07-18 08:13:26.000000000 +0900 +@@ -557,9 +557,9 @@ + 	    } + #endif + 	    else if (!strcmp("-graph", argv[i])) +-		UseGraphicChar = TRUE; ++		UseGraphicChar = GRAPHIC_CHAR_ALL; + 	    else if (!strcmp("-no-graph", argv[i])) +-		UseGraphicChar = FALSE; ++		UseGraphicChar = GRAPHIC_CHAR_ASCII; + 	    else if (!strcmp("-T", argv[i])) { + 		if (++i >= argc) + 		    usage(); +diff -urN w3m-0.5.2.orig/main.c.orig w3m-0.5.2/main.c.orig +--- w3m-0.5.2.orig/main.c.orig	1970-01-01 09:00:00.000000000 +0900 ++++ w3m-0.5.2/main.c.orig	2007-05-31 10:19:50.000000000 +0900 +@@ -0,0 +1,6650 @@ ++/* $Id: main.c,v 1.258 2007/05/31 01:19:50 inu Exp $ */ ++#define MAINPROGRAM ++#include "fm.h" ++#include <signal.h> ++#include <setjmp.h> ++#include <sys/stat.h> ++#include <sys/types.h> ++#include <unistd.h> ++#include <fcntl.h> ++#if defined(HAVE_WAITPID) || defined(HAVE_WAIT3) ++#include <sys/wait.h> ++#endif ++#include <time.h> ++#include "terms.h" ++#include "myctype.h" ++#include "regex.h" ++#ifdef USE_MOUSE ++#ifdef USE_GPM ++#include <gpm.h> ++#endif				/* USE_GPM */ ++#if defined(USE_GPM) || defined(USE_SYSMOUSE) ++extern int do_getch(); ++#define getch()	do_getch() ++#endif				/* defined(USE_GPM) || defined(USE_SYSMOUSE) */ ++#endif ++ ++#ifdef __MINGW32_VERSION ++#include <winsock.h> ++ ++WSADATA WSAData; ++#endif ++ ++#define DSTR_LEN	256 ++ ++Hist *LoadHist; ++Hist *SaveHist; ++Hist *URLHist; ++Hist *ShellHist; ++Hist *TextHist; ++ ++typedef struct _Event { ++    int cmd; ++    void *data; ++    struct _Event *next; ++} Event; ++static Event *CurrentEvent = NULL; ++static Event *LastEvent = NULL; ++ ++#ifdef USE_ALARM ++static AlarmEvent DefaultAlarm = { ++    0, AL_UNSET, FUNCNAME_nulcmd, NULL ++}; ++static AlarmEvent *CurrentAlarm = &DefaultAlarm; ++static MySignalHandler SigAlarm(SIGNAL_ARG); ++#endif ++ ++#ifdef SIGWINCH ++static int need_resize_screen = FALSE; ++static MySignalHandler resize_hook(SIGNAL_ARG); ++static void resize_screen(void); ++#endif ++ ++#ifdef SIGPIPE ++static MySignalHandler SigPipe(SIGNAL_ARG); ++#endif ++ ++#ifdef USE_MARK ++static char *MarkString = NULL; ++#endif ++static char *SearchString = NULL; ++int (*searchRoutine) (Buffer *, char *); ++ ++#ifndef __MINGW32_VERSION ++JMP_BUF IntReturn; ++#else ++_JBTYPE IntReturn[_JBLEN]; ++#endif /* __MINGW32_VERSION */ ++ ++static void delBuffer(Buffer *buf); ++static void cmd_loadfile(char *path); ++static void cmd_loadURL(char *url, ParsedURL *current, char *referer, ++			FormList *request); ++static void cmd_loadBuffer(Buffer *buf, int prop, int linkid); ++static void keyPressEventProc(int c); ++int show_params_p = 0; ++void show_params(FILE * fp); ++ ++static char *getCurWord(Buffer *buf, int *spos, int *epos, ++			const char *badchars); ++ ++static int display_ok = FALSE; ++static void do_dump(Buffer *); ++int prec_num = 0; ++int prev_key = -1; ++int on_target = 1; ++static int add_download_list = FALSE; ++ ++void set_buffer_environ(Buffer *); ++static void save_buffer_position(Buffer *buf); ++ ++static void _followForm(int); ++static void _goLine(char *); ++static void _newT(void); ++static void followTab(TabBuffer * tab); ++static void moveTab(TabBuffer * t, TabBuffer * t2, int right); ++static void _nextA(int); ++static void _prevA(int); ++static int check_target = TRUE; ++#define PREC_NUM (prec_num ? prec_num : 1) ++#define PREC_LIMIT 10000 ++static int searchKeyNum(void); ++ ++#define help() fusage(stdout, 0) ++#define usage() fusage(stderr, 1) ++ ++static void ++fversion(FILE * f) ++{ ++    fprintf(f, "w3m version %s, options %s\n", w3m_version, ++#if LANG == JA ++	    "lang=ja" ++#else ++	    "lang=en" ++#endif ++#ifdef USE_M17N ++	    ",m17n" ++#endif ++#ifdef USE_IMAGE ++	    ",image" ++#endif ++#ifdef USE_COLOR ++	    ",color" ++#ifdef USE_ANSI_COLOR ++	    ",ansi-color" ++#endif ++#endif ++#ifdef USE_MOUSE ++	    ",mouse" ++#ifdef USE_GPM ++	    ",gpm" ++#endif ++#ifdef USE_SYSMOUSE ++	    ",sysmouse" ++#endif ++#endif ++#ifdef USE_MENU ++	    ",menu" ++#endif ++#ifdef USE_COOKIE ++	    ",cookie" ++#endif ++#ifdef USE_SSL ++	    ",ssl" ++#ifdef USE_SSL_VERIFY ++	    ",ssl-verify" ++#endif ++#endif ++#ifdef USE_EXTERNAL_URI_LOADER ++	    ",external-uri-loader" ++#endif ++#ifdef USE_W3MMAILER ++	    ",w3mmailer" ++#endif ++#ifdef USE_NNTP ++	    ",nntp" ++#endif ++#ifdef USE_GOPHER ++	    ",gopher" ++#endif ++#ifdef INET6 ++	    ",ipv6" ++#endif ++#ifdef USE_ALARM ++	    ",alarm" ++#endif ++#ifdef USE_MARK ++	    ",mark" ++#endif ++#ifdef USE_MIGEMO ++	    ",migemo" ++#endif ++	); ++} ++ ++static void ++fusage(FILE * f, int err) ++{ ++    fversion(f); ++    /* FIXME: gettextize? */ ++    fprintf(f, "usage: w3m [options] [URL or filename]\noptions:\n"); ++    fprintf(f, "    -t tab           set tab width\n"); ++    fprintf(f, "    -r               ignore backspace effect\n"); ++    fprintf(f, "    -l line          # of preserved line (default 10000)\n"); ++#ifdef USE_M17N ++    fprintf(f, "    -I charset       document charset\n"); ++    fprintf(f, "    -O charset       display/output charset\n"); ++#ifndef DEBIAN			/* disabled by ukai: -s is used for squeeze multi lines */ ++    fprintf(f, "    -e               EUC-JP\n"); ++    fprintf(f, "    -s               Shift_JIS\n"); ++    fprintf(f, "    -j               JIS\n"); ++#endif ++#endif ++    fprintf(f, "    -B               load bookmark\n"); ++    fprintf(f, "    -bookmark file   specify bookmark file\n"); ++    fprintf(f, "    -T type          specify content-type\n"); ++    fprintf(f, "    -m               internet message mode\n"); ++    fprintf(f, "    -v               visual startup mode\n"); ++#ifdef USE_COLOR ++    fprintf(f, "    -M               monochrome display\n"); ++#endif				/* USE_COLOR */ ++    fprintf(f, ++	    "    -N               open URL of command line on each new tab\n"); ++    fprintf(f, "    -F               automatically render frame\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            dump formatted page into stdout\n"); ++    fprintf(f, ++	    "    -dump_head       dump response of HEAD request into stdout\n"); ++    fprintf(f, "    -dump_source     dump page source into stdout\n"); ++    fprintf(f, "    -dump_both       dump HEAD and source into stdout\n"); ++    fprintf(f, ++	    "    -dump_extra      dump HEAD, source, and extra information into stdout\n"); ++    fprintf(f, "    -post file       use POST method with file content\n"); ++    fprintf(f, "    -header string   insert string as a header\n"); ++    fprintf(f, "    +<num>           goto <num> line\n"); ++    fprintf(f, "    -num             show line number\n"); ++    fprintf(f, "    -no-proxy        don't use proxy\n"); ++#ifdef INET6 ++    fprintf(f, "    -4               IPv4 only (-o dns_order=4)\n"); ++    fprintf(f, "    -6               IPv6 only (-o dns_order=6)\n"); ++#endif ++#ifdef USE_MOUSE ++    fprintf(f, "    -no-mouse        don't use mouse\n"); ++#endif				/* USE_MOUSE */ ++#ifdef USE_COOKIE ++    fprintf(f, ++	    "    -cookie          use cookie (-no-cookie: don't use cookie)\n"); ++#endif				/* USE_COOKIE */ ++    fprintf(f, "    -pauth user:pass proxy authentication\n"); ++    fprintf(f, "    -graph           use graphic character\n"); ++    fprintf(f, "    -no-graph        don't use graphic character\n"); ++#ifdef DEBIAN			/* replaced by ukai: pager requires -s */ ++    fprintf(f, "    -s               squeeze multiple blank lines\n"); ++#else ++    fprintf(f, "    -S               squeeze multiple blank lines\n"); ++#endif ++    fprintf(f, "    -W               toggle wrap search mode\n"); ++    fprintf(f, "    -X               don't use termcap init/deinit\n"); ++    fprintf(f, ++	    "    -title[=TERM]    set buffer name to terminal title string\n"); ++    fprintf(f, "    -o opt=value     assign value to config option\n"); ++    fprintf(f, "    -show-option     print all config options\n"); ++    fprintf(f, "    -config file     specify config file\n"); ++    fprintf(f, "    -help            print this usage message\n"); ++    fprintf(f, "    -version         print w3m version\n"); ++    fprintf(f, "    -reqlog          write request logfile\n"); ++    fprintf(f, "    -debug           DO NOT USE\n"); ++    if (show_params_p) ++	show_params(f); ++    exit(err); ++} ++ ++#ifdef USE_M17N ++#ifdef __EMX__ ++static char *getCodePage(void); ++#endif ++#endif ++ ++static GC_warn_proc orig_GC_warn_proc = NULL; ++#define GC_WARN_KEEP_MAX (20) ++ ++static void ++wrap_GC_warn_proc(char *msg, GC_word arg) ++{ ++    if (fmInitialized) { ++	/* *INDENT-OFF* */ ++	static struct { ++	    char *msg; ++	    GC_word arg; ++	} msg_ring[GC_WARN_KEEP_MAX]; ++	/* *INDENT-ON* */ ++	static int i = 0; ++	static int n = 0; ++	static int lock = 0; ++	int j; ++ ++	j = (i + n) % (sizeof(msg_ring) / sizeof(msg_ring[0])); ++	msg_ring[j].msg = msg; ++	msg_ring[j].arg = arg; ++ ++	if (n < sizeof(msg_ring) / sizeof(msg_ring[0])) ++	    ++n; ++	else ++	    ++i; ++ ++	if (!lock) { ++	    lock = 1; ++ ++	    for (; n > 0; --n, ++i) { ++		i %= sizeof(msg_ring) / sizeof(msg_ring[0]); ++ ++		printf(msg_ring[i].msg,	(unsigned long)msg_ring[i].arg); ++		sleep_till_anykey(1, 1); ++	    } ++ ++	    lock = 0; ++	} ++    } ++    else if (orig_GC_warn_proc) ++	orig_GC_warn_proc(msg, arg); ++    else ++	fprintf(stderr, msg, (unsigned long)arg); ++} ++ ++#ifdef SIGCHLD ++static void ++sig_chld(int signo) ++{ ++    int p_stat; ++#ifdef HAVE_WAITPID ++    pid_t pid; ++ ++    while ((pid = waitpid(-1, &p_stat, WNOHANG)) > 0) { ++	; ++    } ++#elif HAVE_WAIT3 ++    int pid; ++ ++    while ((pid = wait3(&p_stat, WNOHANG, NULL)) > 0) { ++	; ++    } ++#else ++    wait(&p_stat); ++#endif ++    mySignal(SIGCHLD, sig_chld); ++    return; ++} ++#endif ++ ++Str ++make_optional_header_string(char *s) ++{ ++    char *p; ++    Str hs; ++ ++    if (strchr(s, '\n') || strchr(s, '\r')) ++	return NULL; ++    for (p = s; *p && *p != ':'; p++) ; ++    if (*p != ':' || p == s) ++	return NULL; ++    hs = Strnew_size(strlen(s) + 3); ++    Strcopy_charp_n(hs, s, p - s); ++    if (!Strcasecmp_charp(hs, "content-type")) ++	override_content_type = TRUE; ++    Strcat_charp(hs, ": "); ++    if (*(++p)) {		/* not null header */ ++	SKIP_BLANKS(p);		/* skip white spaces */ ++	Strcat_charp(hs, p); ++    } ++    Strcat_charp(hs, "\r\n"); ++    return hs; ++} ++ ++int ++main(int argc, char **argv, char **envp) ++{ ++    Buffer *newbuf = NULL; ++    char *p, c; ++    int i; ++    InputStream redin; ++    char *line_str = NULL; ++    char **load_argv; ++    FormList *request; ++    int load_argc = 0; ++    int load_bookmark = FALSE; ++    int visual_start = FALSE; ++    int open_new_tab = FALSE; ++    char search_header = FALSE; ++    char *default_type = NULL; ++    char *post_file = NULL; ++    Str err_msg; ++#ifdef USE_M17N ++    char *Locale = NULL; ++    wc_uint8 auto_detect; ++#ifdef __EMX__ ++    wc_ces CodePage; ++#endif ++#endif ++    GC_INIT(); ++#if defined(ENABLE_NLS) || (defined(USE_M17N) && defined(HAVE_LANGINFO_CODESET)) ++    setlocale(LC_ALL, ""); ++#endif ++#ifdef ENABLE_NLS ++    bindtextdomain(PACKAGE, LOCALEDIR); ++    textdomain(PACKAGE); ++#endif ++ ++#ifndef HAVE_SYS_ERRLIST ++    prepare_sys_errlist(); ++#endif				/* not HAVE_SYS_ERRLIST */ ++ ++    NO_proxy_domains = newTextList(); ++    fileToDelete = newTextList(); ++ ++    load_argv = New_N(char *, argc - 1); ++    load_argc = 0; ++ ++    CurrentDir = currentdir(); ++    CurrentPid = (int)getpid(); ++    BookmarkFile = NULL; ++    config_file = NULL; ++ ++    /* argument search 1 */ ++    for (i = 1; i < argc; i++) { ++	if (*argv[i] == '-') { ++	    if (!strcmp("-config", argv[i])) { ++		argv[i] = "-dummy"; ++		if (++i >= argc) ++		    usage(); ++		config_file = argv[i]; ++		argv[i] = "-dummy"; ++	    } ++	    else if (!strcmp("-h", argv[i]) || !strcmp("-help", argv[i])) ++		help(); ++	    else if (!strcmp("-V", argv[i]) || !strcmp("-version", argv[i])) { ++		fversion(stdout); ++		exit(0); ++	    } ++	} ++    } ++ ++#ifdef USE_M17N ++    if (non_null(Locale = getenv("LC_ALL")) || ++	non_null(Locale = getenv("LC_CTYPE")) || ++	non_null(Locale = getenv("LANG"))) { ++	DisplayCharset = wc_guess_locale_charset(Locale, DisplayCharset); ++	DocumentCharset = wc_guess_locale_charset(Locale, DocumentCharset); ++	SystemCharset = wc_guess_locale_charset(Locale, SystemCharset); ++    } ++#ifdef __EMX__ ++    CodePage = wc_guess_charset(getCodePage(), 0); ++    if (CodePage) ++	DisplayCharset = DocumentCharset = SystemCharset = CodePage; ++#endif ++#endif ++ ++    /* initializations */ ++    init_rc(); ++ ++    LoadHist = newHist(); ++    SaveHist = newHist(); ++    ShellHist = newHist(); ++    TextHist = newHist(); ++    URLHist = newHist(); ++ ++#ifdef USE_M17N ++    if (FollowLocale && Locale) { ++	DisplayCharset = wc_guess_locale_charset(Locale, DisplayCharset); ++	SystemCharset = wc_guess_locale_charset(Locale, SystemCharset); ++    } ++    auto_detect = WcOption.auto_detect; ++    BookmarkCharset = DocumentCharset; ++#endif ++ ++    if (!non_null(HTTP_proxy) && ++	((p = getenv("HTTP_PROXY")) || ++	 (p = getenv("http_proxy")) || (p = getenv("HTTP_proxy")))) ++	HTTP_proxy = p; ++#ifdef USE_SSL ++    if (!non_null(HTTPS_proxy) && ++	((p = getenv("HTTPS_PROXY")) || ++	 (p = getenv("https_proxy")) || (p = getenv("HTTPS_proxy")))) ++	HTTPS_proxy = p; ++    if (HTTPS_proxy == NULL && non_null(HTTP_proxy)) ++	HTTPS_proxy = HTTP_proxy; ++#endif				/* USE_SSL */ ++#ifdef USE_GOPHER ++    if (!non_null(GOPHER_proxy) && ++	((p = getenv("GOPHER_PROXY")) || ++	 (p = getenv("gopher_proxy")) || (p = getenv("GOPHER_proxy")))) ++	GOPHER_proxy = p; ++#endif				/* USE_GOPHER */ ++    if (!non_null(FTP_proxy) && ++	((p = getenv("FTP_PROXY")) || ++	 (p = getenv("ftp_proxy")) || (p = getenv("FTP_proxy")))) ++	FTP_proxy = p; ++    if (!non_null(NO_proxy) && ++	((p = getenv("NO_PROXY")) || ++	 (p = getenv("no_proxy")) || (p = getenv("NO_proxy")))) ++	NO_proxy = p; ++#ifdef USE_NNTP ++    if (!non_null(NNTP_server) && (p = getenv("NNTPSERVER")) != NULL) ++	NNTP_server = p; ++    if (!non_null(NNTP_mode) && (p = getenv("NNTPMODE")) != NULL) ++	NNTP_mode = p; ++#endif ++ ++    if (!non_null(Editor) && (p = getenv("EDITOR")) != NULL) ++	Editor = p; ++    if (!non_null(Mailer) && (p = getenv("MAILER")) != NULL) ++	Mailer = p; ++ ++    /* argument search 2 */ ++    i = 1; ++    while (i < argc) { ++	if (*argv[i] == '-') { ++	    if (!strcmp("-t", argv[i])) { ++		if (++i >= argc) ++		    usage(); ++		if (atoi(argv[i]) > 0) ++		    Tabstop = atoi(argv[i]); ++	    } ++	    else if (!strcmp("-r", argv[i])) ++		ShowEffect = FALSE; ++	    else if (!strcmp("-l", argv[i])) { ++		if (++i >= argc) ++		    usage(); ++		if (atoi(argv[i]) > 0) ++		    PagerMax = atoi(argv[i]); ++	    } ++#ifdef USE_M17N ++#ifndef DEBIAN			/* XXX: use -o kanjicode={S|J|E} */ ++	    else if (!strcmp("-s", argv[i])) ++		DisplayCharset = WC_CES_SHIFT_JIS; ++	    else if (!strcmp("-j", argv[i])) ++		DisplayCharset = WC_CES_ISO_2022_JP; ++	    else if (!strcmp("-e", argv[i])) ++		DisplayCharset = WC_CES_EUC_JP; ++#endif ++	    else if (!strncmp("-I", argv[i], 2)) { ++		if (argv[i][2] != '\0') ++		    p = argv[i] + 2; ++		else { ++		    if (++i >= argc) ++			usage(); ++		    p = argv[i]; ++		} ++		DocumentCharset = wc_guess_charset_short(p, DocumentCharset); ++		WcOption.auto_detect = WC_OPT_DETECT_OFF; ++		UseContentCharset = FALSE; ++	    } ++	    else if (!strncmp("-O", argv[i], 2)) { ++		if (argv[i][2] != '\0') ++		    p = argv[i] + 2; ++		else { ++		    if (++i >= argc) ++			usage(); ++		    p = argv[i]; ++		} ++		DisplayCharset = wc_guess_charset_short(p, DisplayCharset); ++	    } ++#endif ++	    else if (!strcmp("-graph", argv[i])) ++		UseGraphicChar = TRUE; ++	    else if (!strcmp("-no-graph", argv[i])) ++		UseGraphicChar = FALSE; ++	    else if (!strcmp("-T", argv[i])) { ++		if (++i >= argc) ++		    usage(); ++		DefaultType = default_type = argv[i]; ++	    } ++	    else if (!strcmp("-m", argv[i])) ++		SearchHeader = search_header = TRUE; ++	    else if (!strcmp("-v", argv[i])) ++		visual_start = TRUE; ++	    else if (!strcmp("-N", argv[i])) ++		open_new_tab = TRUE; ++#ifdef USE_COLOR ++	    else if (!strcmp("-M", argv[i])) ++		useColor = FALSE; ++#endif				/* USE_COLOR */ ++	    else if (!strcmp("-B", argv[i])) ++		load_bookmark = TRUE; ++	    else if (!strcmp("-bookmark", argv[i])) { ++		if (++i >= argc) ++		    usage(); ++		BookmarkFile = argv[i]; ++		if (BookmarkFile[0] != '~' && BookmarkFile[0] != '/') { ++		    Str tmp = Strnew_charp(CurrentDir); ++		    if (Strlastchar(tmp) != '/') ++			Strcat_char(tmp, '/'); ++		    Strcat_charp(tmp, BookmarkFile); ++		    BookmarkFile = cleanupName(tmp->ptr); ++		} ++	    } ++	    else if (!strcmp("-F", argv[i])) ++		RenderFrame = TRUE; ++	    else if (!strcmp("-W", argv[i])) { ++		if (WrapDefault) ++		    WrapDefault = FALSE; ++		else ++		    WrapDefault = TRUE; ++	    } ++	    else if (!strcmp("-dump", argv[i])) ++		w3m_dump = DUMP_BUFFER; ++	    else if (!strcmp("-dump_source", argv[i])) ++		w3m_dump = DUMP_SOURCE; ++	    else if (!strcmp("-dump_head", argv[i])) ++		w3m_dump = DUMP_HEAD; ++	    else if (!strcmp("-dump_both", argv[i])) ++		w3m_dump = (DUMP_HEAD | DUMP_SOURCE); ++	    else if (!strcmp("-dump_extra", argv[i])) ++		w3m_dump = (DUMP_HEAD | DUMP_SOURCE | DUMP_EXTRA); ++	    else if (!strcmp("-halfdump", argv[i])) ++		w3m_dump = DUMP_HALFDUMP; ++	    else if (!strcmp("-halfload", argv[i])) { ++		w3m_dump = 0; ++		w3m_halfload = TRUE; ++		DefaultType = default_type = "text/html"; ++	    } ++	    else if (!strcmp("-backend", argv[i])) { ++		w3m_backend = TRUE; ++	    } ++	    else if (!strcmp("-backend_batch", argv[i])) { ++		w3m_backend = TRUE; ++		if (++i >= argc) ++		    usage(); ++		if (!backend_batch_commands) ++		    backend_batch_commands = newTextList(); ++		pushText(backend_batch_commands, argv[i]); ++	    } ++	    else if (!strcmp("-cols", argv[i])) { ++		if (++i >= argc) ++		    usage(); ++		COLS = atoi(argv[i]); ++	    } ++	    else if (!strcmp("-ppc", argv[i])) { ++		double ppc; ++		if (++i >= argc) ++		    usage(); ++		ppc = atof(argv[i]); ++		if (ppc >= MINIMUM_PIXEL_PER_CHAR && ++		    ppc <= MAXIMUM_PIXEL_PER_CHAR) { ++		    pixel_per_char = ppc; ++		    set_pixel_per_char = TRUE; ++		} ++	    } ++#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; ++		    set_pixel_per_line = TRUE; ++		} ++	    } ++#endif ++	    else if (!strcmp("-num", argv[i])) ++		showLineNum = TRUE; ++	    else if (!strcmp("-no-proxy", argv[i])) ++		use_proxy = FALSE; ++#ifdef INET6 ++	    else if (!strcmp("-4", argv[i]) || !strcmp("-6", argv[i])) ++		set_param_option(Sprintf("dns_order=%c", argv[i][1])->ptr); ++#endif ++	    else if (!strcmp("-post", argv[i])) { ++		if (++i >= argc) ++		    usage(); ++		post_file = argv[i]; ++	    } ++	    else if (!strcmp("-header", argv[i])) { ++		Str hs; ++		if (++i >= argc) ++		    usage(); ++		if ((hs = make_optional_header_string(argv[i])) != NULL) { ++		    if (header_string == NULL) ++			header_string = hs; ++		    else ++			Strcat(header_string, hs); ++		} ++		while (argv[i][0]) { ++		    argv[i][0] = '\0'; ++		    argv[i]++; ++		} ++	    } ++#ifdef USE_MOUSE ++	    else if (!strcmp("-no-mouse", argv[i])) { ++		use_mouse = FALSE; ++	    } ++#endif				/* USE_MOUSE */ ++#ifdef USE_COOKIE ++	    else if (!strcmp("-no-cookie", argv[i])) { ++		use_cookie = FALSE; ++		accept_cookie = FALSE; ++	    } ++	    else if (!strcmp("-cookie", argv[i])) { ++		use_cookie = TRUE; ++		accept_cookie = TRUE; ++	    } ++#endif				/* USE_COOKIE */ ++	    else if (!strcmp("-pauth", argv[i])) { ++		if (++i >= argc) ++		    usage(); ++		proxy_auth_cookie = Strnew_m_charp("Basic ", ++						   encodeB(argv[i])->ptr, ++						   NULL); ++		while (argv[i][0]) { ++		    argv[i][0] = '\0'; ++		    argv[i]++; ++		} ++	    } ++#ifdef DEBIAN ++	    else if (!strcmp("-s", argv[i])) ++#else ++	    else if (!strcmp("-S", argv[i])) ++#endif ++		squeezeBlankLine = TRUE; ++	    else if (!strcmp("-X", argv[i])) ++		Do_not_use_ti_te = TRUE; ++	    else if (!strcmp("-title", argv[i])) ++		displayTitleTerm = getenv("TERM"); ++	    else if (!strncmp("-title=", argv[i], 7)) ++		displayTitleTerm = argv[i] + 7; ++	    else if (!strcmp("-o", argv[i]) || ++		     !strcmp("-show-option", argv[i])) { ++		if (!strcmp("-show-option", argv[i]) || ++i >= argc || ++		    !strcmp(argv[i], "?")) { ++		    show_params(stdout); ++		    exit(0); ++		} ++		if (!set_param_option(argv[i])) { ++		    /* option set failed */ ++		    /* FIXME: gettextize? */ ++		    fprintf(stderr, "%s: bad option\n", argv[i]); ++		    show_params_p = 1; ++		    usage(); ++		} ++	    } ++	    else if (!strcmp("-dummy", argv[i])) { ++		/* do nothing */ ++	    } ++	    else if (!strcmp("-debug", argv[i])) { ++		w3m_debug = TRUE; ++	    } ++	    else if (!strcmp("-reqlog",argv[i])) { ++		w3m_reqlog=rcFile("request.log"); ++	    } ++	    else { ++		usage(); ++	    } ++	} ++	else if (*argv[i] == '+') { ++	    line_str = argv[i] + 1; ++	} ++	else { ++	    load_argv[load_argc++] = argv[i]; ++	} ++	i++; ++    } ++ ++#ifdef	__WATT32__ ++    if (w3m_debug) ++	dbug_init(); ++    sock_init(); ++#endif ++ ++#ifdef __MINGW32_VERSION ++    { ++      int err; ++      WORD wVerReq; ++ ++      wVerReq = MAKEWORD(1, 1); ++ ++      err = WSAStartup(wVerReq, &WSAData); ++      if (err != 0) ++        { ++	  fprintf(stderr, "Can't find winsock\n"); ++	  return 1; ++        } ++      _fmode = _O_BINARY; ++    } ++#endif ++ ++    FirstTab = NULL; ++    LastTab = NULL; ++    nTab = 0; ++    CurrentTab = NULL; ++    CurrentKey = -1; ++    if (BookmarkFile == NULL) ++	BookmarkFile = rcFile(BOOKMARK); ++ ++    if (!isatty(1) && !w3m_dump) { ++	/* redirected output */ ++	w3m_dump = DUMP_BUFFER; ++    } ++    if (w3m_dump) { ++	if (COLS == 0) ++	    COLS = 80; ++    } ++ ++#ifdef USE_BINMODE_STREAM ++    setmode(fileno(stdout), O_BINARY); ++#endif ++    if (!w3m_dump && !w3m_backend) { ++	fmInit(); ++#ifdef SIGWINCH ++	mySignal(SIGWINCH, resize_hook); ++#else				/* not SIGWINCH */ ++	setlinescols(); ++	setupscreen(); ++#endif				/* not SIGWINCH */ ++    } ++#ifdef USE_IMAGE ++    else if (w3m_halfdump && displayImage) ++	activeImage = TRUE; ++#endif ++ ++    sync_with_option(); ++#ifdef USE_COOKIE ++    initCookie(); ++#endif				/* USE_COOKIE */ ++#ifdef USE_HISTORY ++    if (UseHistory) ++	loadHistory(URLHist); ++#endif				/* not USE_HISTORY */ ++ ++#ifdef USE_M17N ++    wtf_init(DocumentCharset, DisplayCharset); ++    /*  if (w3m_dump) ++     *    WcOption.pre_conv = WC_TRUE;  ++     */ ++#endif ++ ++    if (w3m_backend) ++	backend(); ++ ++    if (w3m_dump) ++	mySignal(SIGINT, SIG_IGN); ++#ifdef SIGCHLD ++    mySignal(SIGCHLD, sig_chld); ++#endif ++#ifdef SIGPIPE ++    mySignal(SIGPIPE, SigPipe); ++#endif ++ ++    orig_GC_warn_proc = GC_set_warn_proc(wrap_GC_warn_proc); ++    err_msg = Strnew(); ++    if (load_argc == 0) { ++	/* no URL specified */ ++	if (!isatty(0)) { ++	    redin = newFileStream(fdopen(dup(0), "rb"), (void (*)())pclose); ++	    newbuf = openGeneralPagerBuffer(redin); ++	    dup2(1, 0); ++	} ++	else if (load_bookmark) { ++	    newbuf = loadGeneralFile(BookmarkFile, NULL, NO_REFERER, 0, NULL); ++	    if (newbuf == NULL) ++		Strcat_charp(err_msg, "w3m: Can't load bookmark.\n"); ++	} ++	else if (visual_start) { ++	    /* FIXME: gettextize? */ ++	    Str s_page; ++	    s_page = ++		Strnew_charp ++		("<title>W3M startup page</title><center><b>Welcome to "); ++	    Strcat_charp(s_page, "<a href='http://w3m.sourceforge.net/'>"); ++	    Strcat_m_charp(s_page, ++			   "w3m</a>!<p><p>This is w3m version ", ++			   w3m_version, ++			   "<br>Written by <a href='mailto:aito@fw.ipsj.or.jp'>Akinori Ito</a>", ++			   NULL); ++#ifdef DEBIAN ++	    Strcat_m_charp(s_page, ++			   "<p>Debian package is maintained by <a href='mailto:ukai@debian.or.jp'>Fumitoshi UKAI</a>.", ++			   "You can read <a href='file:///usr/share/doc/w3m/'>w3m documents on your local system</a>.", ++			   NULL); ++#endif				/* DEBIAN */ ++	    newbuf = loadHTMLString(s_page); ++	    if (newbuf == NULL) ++		Strcat_charp(err_msg, "w3m: Can't load string.\n"); ++	    else if (newbuf != NO_BUFFER) ++		newbuf->bufferprop |= (BP_INTERNAL | BP_NO_URL); ++	} ++	else if ((p = getenv("HTTP_HOME")) != NULL || ++		 (p = getenv("WWW_HOME")) != NULL) { ++	    newbuf = loadGeneralFile(p, NULL, NO_REFERER, 0, NULL); ++	    if (newbuf == NULL) ++		Strcat(err_msg, Sprintf("w3m: Can't load %s.\n", p)); ++	    else if (newbuf != NO_BUFFER) ++		pushHashHist(URLHist, parsedURL2Str(&newbuf->currentURL)->ptr); ++	} ++	else { ++	    if (fmInitialized) ++		fmTerm(); ++	    usage(); ++	} ++	if (newbuf == NULL) { ++	    if (fmInitialized) ++		fmTerm(); ++	    if (err_msg->length) ++		fprintf(stderr, "%s", err_msg->ptr); ++	    w3m_exit(2); ++	} ++	i = -1; ++    } ++    else { ++	i = 0; ++    } ++    for (; i < load_argc; i++) { ++	if (i >= 0) { ++	    SearchHeader = search_header; ++	    DefaultType = default_type; ++	    if (w3m_dump == DUMP_HEAD) { ++		request = New(FormList); ++		request->method = FORM_METHOD_HEAD; ++		newbuf = ++		    loadGeneralFile(load_argv[i], NULL, NO_REFERER, 0, ++				    request); ++	    } ++	    else { ++		if (post_file && i == 0) { ++		    FILE *fp; ++		    Str body; ++		    if (!strcmp(post_file, "-")) ++			fp = stdin; ++		    else ++			fp = fopen(post_file, "r"); ++		    if (fp == NULL) { ++			/* FIXME: gettextize? */ ++			Strcat(err_msg, ++			       Sprintf("w3m: Can't open %s.\n", post_file)); ++			continue; ++		    } ++		    body = Strfgetall(fp); ++		    if (fp != stdin) ++			fclose(fp); ++		    request = ++			newFormList(NULL, "post", NULL, NULL, NULL, NULL, ++				    NULL); ++		    request->body = body->ptr; ++		    request->boundary = NULL; ++		    request->length = body->length; ++		} ++		else { ++		    request = NULL; ++		} ++		newbuf = ++		    loadGeneralFile(load_argv[i], NULL, NO_REFERER, 0, ++				    request); ++	    } ++	    if (newbuf == NULL) { ++		/* FIXME: gettextize? */ ++		Strcat(err_msg, ++		       Sprintf("w3m: Can't load %s.\n", load_argv[i])); ++		continue; ++	    } ++	    else if (newbuf == NO_BUFFER) ++		continue; ++	    switch (newbuf->real_scheme) { ++	    case SCM_MAILTO: ++		break; ++	    case SCM_LOCAL: ++	    case SCM_LOCAL_CGI: ++		unshiftHist(LoadHist, conv_from_system(load_argv[i])); ++	    default: ++		pushHashHist(URLHist, parsedURL2Str(&newbuf->currentURL)->ptr); ++		break; ++	    } ++	} ++	else if (newbuf == NO_BUFFER) ++	    continue; ++	if (newbuf->pagerSource || ++	    (newbuf->real_scheme == SCM_LOCAL && newbuf->header_source && ++	     newbuf->currentURL.file && strcmp(newbuf->currentURL.file, "-"))) ++	    newbuf->search_header = search_header; ++	if (CurrentTab == NULL) { ++	    FirstTab = LastTab = CurrentTab = newTab(); ++	    nTab = 1; ++	    Firstbuf = Currentbuf = newbuf; ++	} ++	else if (open_new_tab) { ++	    _newT(); ++	    Currentbuf->nextBuffer = newbuf; ++	    delBuffer(Currentbuf); ++	} ++	else { ++	    Currentbuf->nextBuffer = newbuf; ++	    Currentbuf = newbuf; ++	} ++	if (!w3m_dump || w3m_dump == DUMP_BUFFER) { ++	    if (Currentbuf->frameset != NULL && RenderFrame) ++		rFrame(); ++	} ++	if (w3m_dump) ++	    do_dump(Currentbuf); ++	else { ++	    Currentbuf = newbuf; ++#ifdef USE_BUFINFO ++	    saveBufferInfo(); ++#endif ++	} ++    } ++    if (w3m_dump) { ++	if (err_msg->length) ++	    fprintf(stderr, "%s", err_msg->ptr); ++#ifdef USE_COOKIE ++	save_cookies(); ++#endif				/* USE_COOKIE */ ++	w3m_exit(0); ++    } ++ ++    if (add_download_list) { ++	add_download_list = FALSE; ++	CurrentTab = LastTab; ++	if (!FirstTab) { ++	    FirstTab = LastTab = CurrentTab = newTab(); ++	    nTab = 1; ++	} ++	if (!Firstbuf || Firstbuf == NO_BUFFER) { ++	    Firstbuf = Currentbuf = newBuffer(INIT_BUFFER_WIDTH); ++	    Currentbuf->bufferprop = BP_INTERNAL | BP_NO_URL; ++	    Currentbuf->buffername = DOWNLOAD_LIST_TITLE; ++	} ++	else ++	    Currentbuf = Firstbuf; ++	ldDL(); ++    } ++    else ++	CurrentTab = FirstTab; ++    if (!FirstTab || !Firstbuf || Firstbuf == NO_BUFFER) { ++	if (newbuf == NO_BUFFER) { ++	    if (fmInitialized) ++		/* FIXME: gettextize? */ ++		inputChar("Hit any key to quit w3m:"); ++	} ++	if (fmInitialized) ++	    fmTerm(); ++	if (err_msg->length) ++	    fprintf(stderr, "%s", err_msg->ptr); ++	if (newbuf == NO_BUFFER) { ++#ifdef USE_COOKIE ++	    save_cookies(); ++#endif				/* USE_COOKIE */ ++	    if (!err_msg->length) ++		w3m_exit(0); ++	} ++	w3m_exit(2); ++    } ++    if (err_msg->length) ++	disp_message_nsec(err_msg->ptr, FALSE, 1, TRUE, FALSE); ++ ++    SearchHeader = FALSE; ++    DefaultType = NULL; ++#ifdef USE_M17N ++    UseContentCharset = TRUE; ++    WcOption.auto_detect = auto_detect; ++#endif ++ ++    Currentbuf = Firstbuf; ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++    if (line_str) { ++	_goLine(line_str); ++    } ++    for (;;) { ++	if (add_download_list) { ++	    add_download_list = FALSE; ++	    ldDL(); ++	} ++	if (Currentbuf->submit) { ++	    Anchor *a = Currentbuf->submit; ++	    Currentbuf->submit = NULL; ++	    gotoLine(Currentbuf, a->start.line); ++	    Currentbuf->pos = a->start.pos; ++	    _followForm(TRUE); ++	    continue; ++	} ++	/* event processing */ ++	if (CurrentEvent) { ++	    CurrentKey = -1; ++	    CurrentKeyData = NULL; ++	    CurrentCmdData = (char *)CurrentEvent->data; ++	    w3mFuncList[CurrentEvent->cmd].func(); ++	    CurrentCmdData = NULL; ++	    CurrentEvent = CurrentEvent->next; ++	    continue; ++	} ++	/* get keypress event */ ++#ifdef USE_ALARM ++	if (Currentbuf->event) { ++	    if (Currentbuf->event->status != AL_UNSET) { ++		CurrentAlarm = Currentbuf->event; ++		if (CurrentAlarm->sec == 0) {	/* refresh (0sec) */ ++		    Currentbuf->event = NULL; ++		    CurrentKey = -1; ++		    CurrentKeyData = NULL; ++		    CurrentCmdData = (char *)CurrentAlarm->data; ++		    w3mFuncList[CurrentAlarm->cmd].func(); ++		    CurrentCmdData = NULL; ++		    continue; ++		} ++	    } ++	    else ++		Currentbuf->event = NULL; ++	} ++	if (!Currentbuf->event) ++	    CurrentAlarm = &DefaultAlarm; ++#endif ++#ifdef USE_MOUSE ++	mouse_action.in_action = FALSE; ++	if (use_mouse) ++	    mouse_active(); ++#endif				/* USE_MOUSE */ ++#ifdef USE_ALARM ++	if (CurrentAlarm->sec > 0) { ++	    mySignal(SIGALRM, SigAlarm); ++	    alarm(CurrentAlarm->sec); ++	} ++#endif ++#ifdef SIGWINCH ++	mySignal(SIGWINCH, resize_hook); ++#endif ++#ifdef USE_IMAGE ++	if (activeImage && displayImage && Currentbuf->img && ++	    !Currentbuf->image_loaded) { ++	    do { ++#ifdef SIGWINCH ++		if (need_resize_screen) ++		    resize_screen(); ++#endif ++		loadImage(Currentbuf, IMG_FLAG_NEXT); ++	    } while (sleep_till_anykey(1, 0) <= 0); ++	} ++#ifdef SIGWINCH ++	else ++#endif ++#endif ++#ifdef SIGWINCH ++	{ ++	    do { ++		if (need_resize_screen) ++		    resize_screen(); ++	    } while (sleep_till_anykey(1, 0) <= 0); ++	} ++#endif ++	c = getch(); ++#ifdef USE_ALARM ++	if (CurrentAlarm->sec > 0) { ++	    alarm(0); ++	} ++#endif ++#ifdef USE_MOUSE ++	if (use_mouse) ++	    mouse_inactive(); ++#endif				/* USE_MOUSE */ ++	if (IS_ASCII(c)) {	/* Ascii */ ++	    if( vi_prec_num ){ ++		if(((prec_num && c == '0') || '1' <= c) && (c <= '9')) { ++		    prec_num = prec_num * 10 + (int)(c - '0'); ++		    if (prec_num > PREC_LIMIT) ++			prec_num = PREC_LIMIT; ++		} ++		else { ++		    set_buffer_environ(Currentbuf); ++		    save_buffer_position(Currentbuf); ++		    keyPressEventProc((int)c); ++		    prec_num = 0; ++		} ++	    } ++	    else { ++		set_buffer_environ(Currentbuf); ++		save_buffer_position(Currentbuf); ++		keyPressEventProc((int)c); ++		prec_num = 0; ++	    } ++	} ++	prev_key = CurrentKey; ++	CurrentKey = -1; ++	CurrentKeyData = NULL; ++    } ++} ++ ++static void ++keyPressEventProc(int c) ++{ ++    CurrentKey = c; ++    w3mFuncList[(int)GlobalKeymap[c]].func(); ++} ++ ++void ++pushEvent(int cmd, void *data) ++{ ++    Event *event; ++ ++    event = New(Event); ++    event->cmd = cmd; ++    event->data = data; ++    event->next = NULL; ++    if (CurrentEvent) ++	LastEvent->next = event; ++    else ++	CurrentEvent = event; ++    LastEvent = event; ++} ++ ++static void ++dump_source(Buffer *buf) ++{ ++    FILE *f; ++    char c; ++    if (buf->sourcefile == NULL) ++	return; ++    f = fopen(buf->sourcefile, "r"); ++    if (f == NULL) ++	return; ++    while (c = fgetc(f), !feof(f)) { ++	putchar(c); ++    } ++    fclose(f); ++} ++ ++static void ++dump_head(Buffer *buf) ++{ ++    TextListItem *ti; ++ ++    if (buf->document_header == NULL) { ++	if (w3m_dump & DUMP_EXTRA) ++	    printf("\n"); ++	return; ++    } ++    for (ti = buf->document_header->first; ti; ti = ti->next) { ++#ifdef USE_M17N ++	printf("%s", ++	       wc_conv_strict(ti->ptr, InnerCharset, ++			      buf->document_charset)->ptr); ++#else ++	printf("%s", ti->ptr); ++#endif ++    } ++    puts(""); ++} ++ ++static void ++dump_extra(Buffer *buf) ++{ ++    printf("W3m-current-url: %s\n", parsedURL2Str(&buf->currentURL)->ptr); ++    if (buf->baseURL) ++	printf("W3m-base-url: %s\n", parsedURL2Str(buf->baseURL)->ptr); ++#ifdef USE_M17N ++    printf("W3m-document-charset: %s\n", ++	   wc_ces_to_charset(buf->document_charset)); ++#endif ++#ifdef USE_SSL ++    if (buf->ssl_certificate) { ++	Str tmp = Strnew(); ++	char *p; ++	for (p = buf->ssl_certificate; *p; p++) { ++	    Strcat_char(tmp, *p); ++	    if (*p == '\n') { ++		for (; *(p + 1) == '\n'; p++) ; ++		if (*(p + 1)) ++		    Strcat_char(tmp, '\t'); ++	    } ++	} ++	if (Strlastchar(tmp) != '\n') ++	    Strcat_char(tmp, '\n'); ++	printf("W3m-ssl-certificate: %s", tmp->ptr); ++    } ++#endif ++} ++ ++static void ++do_dump(Buffer *buf) ++{ ++    MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL; ++ ++    prevtrap = mySignal(SIGINT, intTrap); ++    if (SETJMP(IntReturn) != 0) { ++	mySignal(SIGINT, prevtrap); ++	return; ++    } ++    if (w3m_dump & DUMP_EXTRA) ++	dump_extra(buf); ++    if (w3m_dump & DUMP_HEAD) ++	dump_head(buf); ++    if (w3m_dump & DUMP_SOURCE) ++	dump_source(buf); ++    if (w3m_dump == DUMP_BUFFER) ++	saveBuffer(buf, stdout, FALSE); ++    mySignal(SIGINT, prevtrap); ++} ++ ++DEFUN(nulcmd, NOTHING NULL @@@, "Do nothing") ++{				/* do nothing */ ++} ++ ++#ifdef __EMX__ ++DEFUN(pcmap, PCMAP, "pcmap") ++{ ++    w3mFuncList[(int)PcKeymap[(int)getch()]].func(); ++} ++#else				/* not __EMX__ */ ++void ++pcmap(void) ++{ ++} ++#endif ++ ++static void ++escKeyProc(int c, int esc, unsigned char *map) ++{ ++    if (CurrentKey >= 0 && CurrentKey & K_MULTI) { ++	unsigned char **mmap; ++	mmap = (unsigned char **)getKeyData(MULTI_KEY(CurrentKey)); ++	if (!mmap) ++	    return; ++	switch (esc) { ++	case K_ESCD: ++	    map = mmap[3]; ++	    break; ++	case K_ESCB: ++	    map = mmap[2]; ++	    break; ++	case K_ESC: ++	    map = mmap[1]; ++	    break; ++	default: ++	    map = mmap[0]; ++	    break; ++	} ++	esc |= (CurrentKey & ~0xFFFF); ++    } ++    CurrentKey = esc | c; ++    w3mFuncList[(int)map[c]].func(); ++} ++ ++DEFUN(escmap, ESCMAP, "ESC map") ++{ ++    char c; ++    c = getch(); ++    if (IS_ASCII(c)) ++	escKeyProc((int)c, K_ESC, EscKeymap); ++} ++ ++DEFUN(escbmap, ESCBMAP, "ESC [ map") ++{ ++    char c; ++    c = getch(); ++    if (IS_DIGIT(c)) { ++	escdmap(c); ++	return; ++    } ++    if (IS_ASCII(c)) ++	escKeyProc((int)c, K_ESCB, EscBKeymap); ++} ++ ++void ++escdmap(char c) ++{ ++    int d; ++    d = (int)c - (int)'0'; ++    c = getch(); ++    if (IS_DIGIT(c)) { ++	d = d * 10 + (int)c - (int)'0'; ++	c = getch(); ++    } ++    if (c == '~') ++	escKeyProc((int)d, K_ESCD, EscDKeymap); ++} ++ ++DEFUN(multimap, MULTIMAP, "multimap") ++{ ++    char c; ++    c = getch(); ++    if (IS_ASCII(c)) { ++	CurrentKey = K_MULTI | (CurrentKey << 16) | c; ++	escKeyProc((int)c, 0, NULL); ++    } ++} ++ ++void ++tmpClearBuffer(Buffer *buf) ++{ ++    if (buf->pagerSource == NULL && writeBufferCache(buf) == 0) { ++	buf->firstLine = NULL; ++	buf->topLine = NULL; ++	buf->currentLine = NULL; ++	buf->lastLine = NULL; ++    } ++} ++ ++static Str currentURL(void); ++ ++#ifdef USE_BUFINFO ++void ++saveBufferInfo() ++{ ++    FILE *fp; ++ ++    if (w3m_dump) ++	return; ++    if ((fp = fopen(rcFile("bufinfo"), "w")) == NULL) { ++	return; ++    } ++    fprintf(fp, "%s\n", currentURL()->ptr); ++    fclose(fp); ++} ++#endif ++ ++static void ++pushBuffer(Buffer *buf) ++{ ++    Buffer *b; ++ ++#ifdef USE_IMAGE ++    deleteImage(Currentbuf); ++#endif ++    if (clear_buffer) ++	tmpClearBuffer(Currentbuf); ++    if (Firstbuf == Currentbuf) { ++	buf->nextBuffer = Firstbuf; ++	Firstbuf = Currentbuf = buf; ++    } ++    else if ((b = prevBuffer(Firstbuf, Currentbuf)) != NULL) { ++	b->nextBuffer = buf; ++	buf->nextBuffer = Currentbuf; ++	Currentbuf = buf; ++    } ++#ifdef USE_BUFINFO ++    saveBufferInfo(); ++#endif ++ ++} ++ ++static void ++delBuffer(Buffer *buf) ++{ ++    if (buf == NULL) ++	return; ++    if (Currentbuf == buf) ++	Currentbuf = buf->nextBuffer; ++    Firstbuf = deleteBuffer(Firstbuf, buf); ++    if (!Currentbuf) ++	Currentbuf = Firstbuf; ++} ++ ++static void ++repBuffer(Buffer *oldbuf, Buffer *buf) ++{ ++    Firstbuf = replaceBuffer(Firstbuf, oldbuf, buf); ++    Currentbuf = buf; ++} ++ ++ ++MySignalHandler ++intTrap(SIGNAL_ARG) ++{				/* Interrupt catcher */ ++    LONGJMP(IntReturn, 0); ++    SIGNAL_RETURN; ++} ++ ++#ifdef SIGWINCH ++static MySignalHandler ++resize_hook(SIGNAL_ARG) ++{ ++    need_resize_screen = TRUE; ++    mySignal(SIGWINCH, resize_hook); ++    SIGNAL_RETURN; ++} ++ ++static void ++resize_screen(void) ++{ ++    need_resize_screen = FALSE; ++    setlinescols(); ++    setupscreen(); ++    if (CurrentTab) ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++#endif				/* SIGWINCH */ ++ ++#ifdef SIGPIPE ++static MySignalHandler ++SigPipe(SIGNAL_ARG) ++{ ++#ifdef USE_MIGEMO ++    init_migemo(); ++#endif ++    mySignal(SIGPIPE, SigPipe); ++    SIGNAL_RETURN; ++} ++#endif ++ ++/*  ++ * Command functions: These functions are called with a keystroke. ++ */ ++ ++static void ++nscroll(int n, int mode) ++{ ++    Buffer *buf = Currentbuf; ++    Line *top = buf->topLine, *cur = buf->currentLine; ++    int lnum, tlnum, llnum, diff_n; ++ ++    if (buf->firstLine == NULL) ++	return; ++    lnum = cur->linenumber; ++    buf->topLine = lineSkip(buf, top, n, FALSE); ++    if (buf->topLine == top) { ++	lnum += n; ++	if (lnum < buf->topLine->linenumber) ++	    lnum = buf->topLine->linenumber; ++	else if (lnum > buf->lastLine->linenumber) ++	    lnum = buf->lastLine->linenumber; ++    } ++    else { ++	tlnum = buf->topLine->linenumber; ++	llnum = buf->topLine->linenumber + buf->LINES - 1; ++	if (nextpage_topline) ++	    diff_n = 0; ++	else ++	    diff_n = n - (tlnum - top->linenumber); ++	if (lnum < tlnum) ++	    lnum = tlnum + diff_n; ++	if (lnum > llnum) ++	    lnum = llnum + diff_n; ++    } ++    gotoLine(buf, lnum); ++    arrangeLine(buf); ++    if (n > 0) { ++	if (buf->currentLine->bpos && ++	    buf->currentLine->bwidth >= buf->currentColumn + buf->visualpos) ++	    cursorDown(buf, 1); ++	else { ++	    while (buf->currentLine->next && buf->currentLine->next->bpos && ++		   buf->currentLine->bwidth + buf->currentLine->width < ++		   buf->currentColumn + buf->visualpos) ++		cursorDown0(buf, 1); ++	} ++    } ++    else { ++	if (buf->currentLine->bwidth + buf->currentLine->width < ++	    buf->currentColumn + buf->visualpos) ++	    cursorUp(buf, 1); ++	else { ++	    while (buf->currentLine->prev && buf->currentLine->bpos && ++		   buf->currentLine->bwidth >= ++		   buf->currentColumn + buf->visualpos) ++		cursorUp0(buf, 1); ++	} ++    } ++    displayBuffer(buf, mode); ++} ++ ++/* Move page forward */ ++DEFUN(pgFore, NEXT_PAGE, "Move to next page") ++{ ++    if (vi_prec_num) ++	nscroll(searchKeyNum() * (Currentbuf->LINES - 1), B_NORMAL); ++    else ++	nscroll(prec_num ? searchKeyNum() : searchKeyNum() ++		* (Currentbuf->LINES - 1), prec_num ? B_SCROLL : B_NORMAL); ++} ++ ++/* Move page backward */ ++DEFUN(pgBack, PREV_PAGE, "Move to previous page") ++{ ++    if (vi_prec_num) ++	nscroll(-searchKeyNum() * (Currentbuf->LINES - 1), B_NORMAL); ++    else ++	nscroll(-(prec_num ? searchKeyNum() : searchKeyNum() ++		  * (Currentbuf->LINES - 1)), prec_num ? B_SCROLL : B_NORMAL); ++} ++ ++/* 1 line up */ ++DEFUN(lup1, UP, "Scroll up one line") ++{ ++    nscroll(searchKeyNum(), B_SCROLL); ++} ++ ++/* 1 line down */ ++DEFUN(ldown1, DOWN, "Scroll down one line") ++{ ++    nscroll(-searchKeyNum(), B_SCROLL); ++} ++ ++/* move cursor position to the center of screen */ ++DEFUN(ctrCsrV, CENTER_V, "Move to the center column") ++{ ++    int offsety; ++    if (Currentbuf->firstLine == NULL) ++	return; ++    offsety = Currentbuf->LINES / 2 - Currentbuf->cursorY; ++    if (offsety != 0) { ++#if 0 ++	Currentbuf->currentLine = lineSkip(Currentbuf, ++					   Currentbuf->currentLine, offsety, ++					   FALSE); ++#endif ++	Currentbuf->topLine = ++	    lineSkip(Currentbuf, Currentbuf->topLine, -offsety, FALSE); ++	arrangeLine(Currentbuf); ++	displayBuffer(Currentbuf, B_NORMAL); ++    } ++} ++ ++DEFUN(ctrCsrH, CENTER_H, "Move to the center line") ++{ ++    int offsetx; ++    if (Currentbuf->firstLine == NULL) ++	return; ++    offsetx = Currentbuf->cursorX - Currentbuf->COLS / 2; ++    if (offsetx != 0) { ++	columnSkip(Currentbuf, offsetx); ++	arrangeCursor(Currentbuf); ++	displayBuffer(Currentbuf, B_NORMAL); ++    } ++} ++ ++/* Redraw screen */ ++DEFUN(rdrwSc, REDRAW, "Redraw screen") ++{ ++    clear(); ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++static void ++clear_mark(Line *l) ++{ ++    int pos; ++    if (!l) ++	return; ++    for (pos = 0; pos < l->size; pos++) ++	l->propBuf[pos] &= ~PE_MARK; ++} ++ ++/* search by regular expression */ ++static int ++srchcore(char *volatile str, int (*func) (Buffer *, char *)) ++{ ++    MySignalHandler(*prevtrap) (); ++    volatile int i, result = SR_NOTFOUND; ++ ++    if (str != NULL && str != SearchString) ++	SearchString = str; ++    if (SearchString == NULL || *SearchString == '\0') ++	return SR_NOTFOUND; ++ ++    str = conv_search_string(SearchString, DisplayCharset); ++    prevtrap = mySignal(SIGINT, intTrap); ++    crmode(); ++    if (SETJMP(IntReturn) == 0) { ++	for (i = 0; i < PREC_NUM; i++) { ++	    result = func(Currentbuf, str); ++	    if (i < PREC_NUM - 1 && result & SR_FOUND) ++		clear_mark(Currentbuf->currentLine); ++	} ++    } ++    mySignal(SIGINT, prevtrap); ++    term_raw(); ++    return result; ++} ++ ++static void ++disp_srchresult(int result, char *prompt, char *str) ++{ ++    if (str == NULL) ++	str = ""; ++    if (result & SR_NOTFOUND) ++	disp_message(Sprintf("Not found: %s", str)->ptr, TRUE); ++    else if (result & SR_WRAPPED) ++	disp_message(Sprintf("Search wrapped: %s", str)->ptr, TRUE); ++    else if (show_srch_str) ++	disp_message(Sprintf("%s%s", prompt, str)->ptr, TRUE); ++} ++ ++static int ++dispincsrch(int ch, Str buf, Lineprop *prop) ++{ ++    static Buffer sbuf; ++    static Line *currentLine; ++    static int pos; ++    char *str; ++    int do_next_search = FALSE; ++ ++    if (ch == 0 && buf == NULL) { ++	SAVE_BUFPOSITION(&sbuf);	/* search starting point */ ++	currentLine = sbuf.currentLine; ++	pos = sbuf.pos; ++	return -1; ++    } ++ ++    str = buf->ptr; ++    switch (ch) { ++    case 022:			/* C-r */ ++	searchRoutine = backwardSearch; ++	do_next_search = TRUE; ++	break; ++    case 023:			/* C-s */ ++	searchRoutine = forwardSearch; ++	do_next_search = TRUE; ++	break; ++ ++#ifdef USE_MIGEMO ++    case 034: ++	migemo_active = -migemo_active; ++	goto done; ++#endif ++ ++    default: ++	if (ch >= 0) ++	    return ch;		/* use InputKeymap */ ++    } ++ ++    if (do_next_search) { ++	if (*str) { ++	    if (searchRoutine == forwardSearch) ++		Currentbuf->pos += 1; ++	    SAVE_BUFPOSITION(&sbuf); ++	    if (srchcore(str, searchRoutine) == SR_NOTFOUND ++		&& searchRoutine == forwardSearch) { ++		Currentbuf->pos -= 1; ++		SAVE_BUFPOSITION(&sbuf); ++	    } ++	    arrangeCursor(Currentbuf); ++	    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	    clear_mark(Currentbuf->currentLine); ++	    return -1; ++	} ++	else ++	    return 020;		/* _prev completion for C-s C-s */ ++    } ++    else if (*str) { ++	RESTORE_BUFPOSITION(&sbuf); ++	arrangeCursor(Currentbuf); ++	srchcore(str, searchRoutine); ++	arrangeCursor(Currentbuf); ++	currentLine = Currentbuf->currentLine; ++	pos = Currentbuf->pos; ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++    clear_mark(Currentbuf->currentLine); ++#ifdef USE_MIGEMO ++  done: ++    while (*str++ != '\0') { ++	if (migemo_active > 0) ++	    *prop++ |= PE_UNDER; ++	else ++	    *prop++ &= ~PE_UNDER; ++    } ++#endif ++    return -1; ++} ++ ++void ++isrch(int (*func) (Buffer *, char *), char *prompt) ++{ ++    char *str; ++    Buffer sbuf; ++    SAVE_BUFPOSITION(&sbuf); ++    dispincsrch(0, NULL, NULL);	/* initialize incremental search state */ ++ ++    searchRoutine = func; ++    str = inputLineHistSearch(prompt, NULL, IN_STRING, TextHist, dispincsrch); ++    if (str == NULL) { ++	RESTORE_BUFPOSITION(&sbuf); ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++void ++srch(int (*func) (Buffer *, char *), char *prompt) ++{ ++    char *str; ++    int result; ++    int disp = FALSE; ++    int pos; ++ ++    str = searchKeyData(); ++    if (str == NULL || *str == '\0') { ++	str = inputStrHist(prompt, NULL, TextHist); ++	if (str != NULL && *str == '\0') ++	    str = SearchString; ++	if (str == NULL) { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++	disp = TRUE; ++    } ++    pos = Currentbuf->pos; ++    if (func == forwardSearch) ++	Currentbuf->pos += 1; ++    result = srchcore(str, func); ++    if (result & SR_FOUND) ++	clear_mark(Currentbuf->currentLine); ++    else ++	Currentbuf->pos = pos; ++    displayBuffer(Currentbuf, B_NORMAL); ++    if (disp) ++	disp_srchresult(result, prompt, str); ++    searchRoutine = func; ++} ++ ++/* Search regular expression forward */ ++ ++DEFUN(srchfor, SEARCH SEARCH_FORE WHEREIS, "Search forward") ++{ ++    srch(forwardSearch, "Forward: "); ++} ++ ++DEFUN(isrchfor, ISEARCH, "Incremental search forward") ++{ ++    isrch(forwardSearch, "I-search: "); ++} ++ ++/* Search regular expression backward */ ++ ++DEFUN(srchbak, SEARCH_BACK, "Search backward") ++{ ++    srch(backwardSearch, "Backward: "); ++} ++ ++DEFUN(isrchbak, ISEARCH_BACK, "Incremental search backward") ++{ ++    isrch(backwardSearch, "I-search backward: "); ++} ++ ++static void ++srch_nxtprv(int reverse) ++{ ++    int result; ++    /* *INDENT-OFF* */ ++    static int (*routine[2]) (Buffer *, char *) = { ++	forwardSearch, backwardSearch ++    }; ++    /* *INDENT-ON* */ ++ ++    if (searchRoutine == NULL) { ++	/* FIXME: gettextize? */ ++	disp_message("No previous regular expression", TRUE); ++	return; ++    } ++    if (reverse != 0) ++	reverse = 1; ++    if (searchRoutine == backwardSearch) ++	reverse ^= 1; ++    if (reverse == 0) ++	Currentbuf->pos += 1; ++    result = srchcore(SearchString, routine[reverse]); ++    if (result & SR_FOUND) ++	clear_mark(Currentbuf->currentLine); ++    displayBuffer(Currentbuf, B_NORMAL); ++    disp_srchresult(result, (reverse ? "Backward: " : "Forward: "), ++		    SearchString); ++} ++ ++/* Search next matching */ ++DEFUN(srchnxt, SEARCH_NEXT, "Search next regexp") ++{ ++    srch_nxtprv(0); ++} ++ ++/* Search previous matching */ ++DEFUN(srchprv, SEARCH_PREV, "Search previous regexp") ++{ ++    srch_nxtprv(1); ++} ++ ++static void ++shiftvisualpos(Buffer *buf, int shift) ++{ ++    Line *l = buf->currentLine; ++    buf->visualpos -= shift; ++    if (buf->visualpos - l->bwidth >= buf->COLS) ++	buf->visualpos = l->bwidth + buf->COLS - 1; ++    else if (buf->visualpos - l->bwidth < 0) ++	buf->visualpos = l->bwidth; ++    arrangeLine(buf); ++    if (buf->visualpos - l->bwidth == -shift && buf->cursorX == 0) ++	buf->visualpos = l->bwidth; ++} ++ ++/* Shift screen left */ ++DEFUN(shiftl, SHIFT_LEFT, "Shift screen left") ++{ ++    int column; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    column = Currentbuf->currentColumn; ++    columnSkip(Currentbuf, searchKeyNum() * (-Currentbuf->COLS + 1) + 1); ++    shiftvisualpos(Currentbuf, Currentbuf->currentColumn - column); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* Shift screen right */ ++DEFUN(shiftr, SHIFT_RIGHT, "Shift screen right") ++{ ++    int column; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    column = Currentbuf->currentColumn; ++    columnSkip(Currentbuf, searchKeyNum() * (Currentbuf->COLS - 1) - 1); ++    shiftvisualpos(Currentbuf, Currentbuf->currentColumn - column); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++DEFUN(col1R, RIGHT, "Shift screen one column right") ++{ ++    Buffer *buf = Currentbuf; ++    Line *l = buf->currentLine; ++    int j, column, n = searchKeyNum(); ++ ++    if (l == NULL) ++	return; ++    for (j = 0; j < n; j++) { ++	column = buf->currentColumn; ++	columnSkip(Currentbuf, 1); ++	if (column == buf->currentColumn) ++	    break; ++	shiftvisualpos(Currentbuf, 1); ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++DEFUN(col1L, LEFT, "Shift screen one column") ++{ ++    Buffer *buf = Currentbuf; ++    Line *l = buf->currentLine; ++    int j, n = searchKeyNum(); ++ ++    if (l == NULL) ++	return; ++    for (j = 0; j < n; j++) { ++	if (buf->currentColumn == 0) ++	    break; ++	columnSkip(Currentbuf, -1); ++	shiftvisualpos(Currentbuf, -1); ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++DEFUN(setEnv, SETENV, "Set environment variable") ++{ ++    char *env; ++    char *var, *value; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    env = searchKeyData(); ++    if (env == NULL || *env == '\0' || strchr(env, '=') == NULL) { ++	if (env != NULL && *env != '\0') ++	    env = Sprintf("%s=", env)->ptr; ++	env = inputStrHist("Set environ: ", env, TextHist); ++	if (env == NULL || *env == '\0') { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++    } ++    if ((value = strchr(env, '=')) != NULL && value > env) { ++	var = allocStr(env, value - env); ++	value++; ++	set_environ(var, value); ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++DEFUN(pipeBuf, PIPE_BUF, "Send rendered document to pipe") ++{ ++    Buffer *buf; ++    char *cmd, *tmpf; ++    FILE *f; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    cmd = searchKeyData(); ++    if (cmd == NULL || *cmd == '\0') { ++	/* FIXME: gettextize? */ ++	cmd = inputLineHist("Pipe buffer to: ", "", IN_COMMAND, ShellHist); ++    } ++    if (cmd != NULL) ++	cmd = conv_to_system(cmd); ++    if (cmd == NULL || *cmd == '\0') { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    tmpf = tmpfname(TMPF_DFL, NULL)->ptr; ++    f = fopen(tmpf, "w"); ++    if (f == NULL) { ++	/* FIXME: gettextize? */ ++	disp_message(Sprintf("Can't save buffer to %s", cmd)->ptr, TRUE); ++	return; ++    } ++    saveBuffer(Currentbuf, f, TRUE); ++    fclose(f); ++    buf = getpipe(myExtCommand(cmd, shell_quote(tmpf), TRUE)->ptr); ++    if (buf == NULL) { ++	disp_message("Execution failed", TRUE); ++	return; ++    } ++    else { ++	buf->filename = cmd; ++	buf->buffername = Sprintf("%s %s", PIPEBUFFERNAME, ++				  conv_from_system(cmd))->ptr; ++	buf->bufferprop |= (BP_INTERNAL | BP_NO_URL); ++	if (buf->type == NULL) ++	    buf->type = "text/plain"; ++	buf->currentURL.file = "-"; ++	pushBuffer(buf); ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* Execute shell command and read output ac pipe. */ ++DEFUN(pipesh, PIPE_SHELL, "Execute shell command and browse") ++{ ++    Buffer *buf; ++    char *cmd; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    cmd = searchKeyData(); ++    if (cmd == NULL || *cmd == '\0') { ++	cmd = inputLineHist("(read shell[pipe])!", "", IN_COMMAND, ShellHist); ++    } ++    if (cmd != NULL) ++	cmd = conv_to_system(cmd); ++    if (cmd == NULL || *cmd == '\0') { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    buf = getpipe(cmd); ++    if (buf == NULL) { ++	disp_message("Execution failed", TRUE); ++	return; ++    } ++    else { ++	buf->bufferprop |= (BP_INTERNAL | BP_NO_URL); ++	if (buf->type == NULL) ++	    buf->type = "text/plain"; ++	pushBuffer(buf); ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* Execute shell command and load entire output to buffer */ ++DEFUN(readsh, READ_SHELL, "Execute shell command and load") ++{ ++    Buffer *buf; ++    MySignalHandler(*prevtrap) (); ++    char *cmd; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    cmd = searchKeyData(); ++    if (cmd == NULL || *cmd == '\0') { ++	cmd = inputLineHist("(read shell)!", "", IN_COMMAND, ShellHist); ++    } ++    if (cmd != NULL) ++	cmd = conv_to_system(cmd); ++    if (cmd == NULL || *cmd == '\0') { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    prevtrap = mySignal(SIGINT, intTrap); ++    crmode(); ++    buf = getshell(cmd); ++    mySignal(SIGINT, prevtrap); ++    term_raw(); ++    if (buf == NULL) { ++	/* FIXME: gettextize? */ ++	disp_message("Execution failed", TRUE); ++	return; ++    } ++    else { ++	buf->bufferprop |= (BP_INTERNAL | BP_NO_URL); ++	if (buf->type == NULL) ++	    buf->type = "text/plain"; ++	pushBuffer(buf); ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* Execute shell command */ ++DEFUN(execsh, EXEC_SHELL SHELL, "Execute shell command") ++{ ++    char *cmd; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    cmd = searchKeyData(); ++    if (cmd == NULL || *cmd == '\0') { ++	cmd = inputLineHist("(exec shell)!", "", IN_COMMAND, ShellHist); ++    } ++    if (cmd != NULL) ++	cmd = conv_to_system(cmd); ++    if (cmd != NULL && *cmd != '\0') { ++	fmTerm(); ++	printf("\n"); ++	system(cmd); ++	/* FIXME: gettextize? */ ++	printf("\n[Hit any key]"); ++	fflush(stdout); ++	fmInit(); ++	getch(); ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* Load file */ ++DEFUN(ldfile, LOAD, "Load local file") ++{ ++    char *fn; ++ ++    fn = searchKeyData(); ++    if (fn == NULL || *fn == '\0') { ++	/* FIXME: gettextize? */ ++	fn = inputFilenameHist("(Load)Filename? ", NULL, LoadHist); ++    } ++    if (fn != NULL) ++	fn = conv_to_system(fn); ++    if (fn == NULL || *fn == '\0') { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    cmd_loadfile(fn); ++} ++ ++/* Load help file */ ++DEFUN(ldhelp, HELP, "View help") ++{ ++#ifdef USE_HELP_CGI ++    char *lang; ++    int n; ++    Str tmp; ++ ++    lang = AcceptLang; ++    n = strcspn(lang, ";, \t"); ++    tmp = Sprintf("file:///$LIB/" HELP_CGI CGI_EXTENSION "?version=%s&lang=%s", ++		  Str_form_quote(Strnew_charp(w3m_version))->ptr, ++		  Str_form_quote(Strnew_charp_n(lang, n))->ptr); ++    cmd_loadURL(tmp->ptr, NULL, NO_REFERER, NULL); ++#else ++    cmd_loadURL(helpFile(HELP_FILE), NULL, NO_REFERER, NULL); ++#endif ++} ++ ++static void ++cmd_loadfile(char *fn) ++{ ++    Buffer *buf; ++ ++    buf = loadGeneralFile(file_to_url(fn), NULL, NO_REFERER, 0, NULL); ++    if (buf == NULL) { ++	/* FIXME: gettextize? */ ++	char *emsg = Sprintf("%s not found", conv_from_system(fn))->ptr; ++	disp_err_message(emsg, FALSE); ++    } ++    else if (buf != NO_BUFFER) { ++	pushBuffer(buf); ++	if (RenderFrame && Currentbuf->frameset != NULL) ++	    rFrame(); ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* Move cursor left */ ++static void ++_movL(int n) ++{ ++    int i, m = searchKeyNum(); ++    if (Currentbuf->firstLine == NULL) ++	return; ++    for (i = 0; i < m; i++) ++	cursorLeft(Currentbuf, n); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++DEFUN(movL, MOVE_LEFT, ++      "Move cursor left (a half screen shift at the left edge)") ++{ ++    _movL(Currentbuf->COLS / 2); ++} ++ ++DEFUN(movL1, MOVE_LEFT1, "Move cursor left (1 columns shift at the left edge)") ++{ ++    _movL(1); ++} ++ ++/* Move cursor downward */ ++static void ++_movD(int n) ++{ ++    int i, m = searchKeyNum(); ++    if (Currentbuf->firstLine == NULL) ++	return; ++    for (i = 0; i < m; i++) ++	cursorDown(Currentbuf, n); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++DEFUN(movD, MOVE_DOWN, ++      "Move cursor down (a half screen scroll at the end of screen)") ++{ ++    _movD((Currentbuf->LINES + 1) / 2); ++} ++ ++DEFUN(movD1, MOVE_DOWN1, ++      "Move cursor down (1 line scroll at the end of screen)") ++{ ++    _movD(1); ++} ++ ++/* move cursor upward */ ++static void ++_movU(int n) ++{ ++    int i, m = searchKeyNum(); ++    if (Currentbuf->firstLine == NULL) ++	return; ++    for (i = 0; i < m; i++) ++	cursorUp(Currentbuf, n); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++DEFUN(movU, MOVE_UP, ++      "Move cursor up (a half screen scroll at the top of screen)") ++{ ++    _movU((Currentbuf->LINES + 1) / 2); ++} ++ ++DEFUN(movU1, MOVE_UP1, "Move cursor up (1 line scrol at the top of screen)") ++{ ++    _movU(1); ++} ++ ++/* Move cursor right */ ++static void ++_movR(int n) ++{ ++    int i, m = searchKeyNum(); ++    if (Currentbuf->firstLine == NULL) ++	return; ++    for (i = 0; i < m; i++) ++	cursorRight(Currentbuf, n); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++DEFUN(movR, MOVE_RIGHT, ++      "Move cursor right (a half screen shift at the right edge)") ++{ ++    _movR(Currentbuf->COLS / 2); ++} ++ ++DEFUN(movR1, MOVE_RIGHT1, ++      "Move cursor right (1 columns shift at the right edge)") ++{ ++    _movR(1); ++} ++ ++/* movLW, movRW */ ++/*  ++ * From: Takashi Nishimoto <g96p0935@mse.waseda.ac.jp> Date: Mon, 14 Jun ++ * 1999 09:29:56 +0900  ++ */ ++#define IS_WORD_CHAR(c,p) (IS_ALNUM(c) && CharType(p) == PC_ASCII) ++ ++static int ++prev_nonnull_line(Line *line) ++{ ++    Line *l; ++ ++    for (l = line; l != NULL && l->len == 0; l = l->prev) ; ++    if (l == NULL || l->len == 0) ++	return -1; ++ ++    Currentbuf->currentLine = l; ++    if (l != line) ++	Currentbuf->pos = Currentbuf->currentLine->len; ++    return 0; ++} ++ ++DEFUN(movLW, PREV_WORD, "Move to previous word") ++{ ++    char *lb; ++    Lineprop *pb; ++    Line *pline; ++    int ppos; ++    int i, n = searchKeyNum(); ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++ ++    for (i = 0; i < n; i++) { ++	pline = Currentbuf->currentLine; ++	ppos = Currentbuf->pos; ++ ++	if (prev_nonnull_line(Currentbuf->currentLine) < 0) ++	    goto end; ++ ++	while (1) { ++	    lb = Currentbuf->currentLine->lineBuf; ++	    pb = Currentbuf->currentLine->propBuf; ++	    while (Currentbuf->pos > 0 && ++		   !IS_WORD_CHAR(lb[Currentbuf->pos - 1], ++				 pb[Currentbuf->pos - 1])) { ++		Currentbuf->pos--; ++	    } ++	    if (Currentbuf->pos > 0) ++		break; ++	    if (prev_nonnull_line(Currentbuf->currentLine->prev) < 0) { ++		Currentbuf->currentLine = pline; ++		Currentbuf->pos = ppos; ++		goto end; ++	    } ++	    Currentbuf->pos = Currentbuf->currentLine->len; ++	} ++ ++	lb = Currentbuf->currentLine->lineBuf; ++	pb = Currentbuf->currentLine->propBuf; ++	while (Currentbuf->pos > 0 && ++	       IS_WORD_CHAR(lb[Currentbuf->pos - 1], ++			    pb[Currentbuf->pos - 1])) { ++	    Currentbuf->pos--; ++	} ++    } ++  end: ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++static int ++next_nonnull_line(Line *line) ++{ ++    Line *l; ++ ++    for (l = line; l != NULL && l->len == 0; l = l->next) ; ++ ++    if (l == NULL || l->len == 0) ++	return -1; ++ ++    Currentbuf->currentLine = l; ++    if (l != line) ++	Currentbuf->pos = 0; ++    return 0; ++} ++ ++DEFUN(movRW, NEXT_WORD, "Move to next word") ++{ ++    char *lb; ++    Lineprop *pb; ++    Line *pline; ++    int ppos; ++    int i, n = searchKeyNum(); ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++ ++    for (i = 0; i < n; i++) { ++	pline = Currentbuf->currentLine; ++	ppos = Currentbuf->pos; ++ ++	if (next_nonnull_line(Currentbuf->currentLine) < 0) ++	    goto end; ++ ++	lb = Currentbuf->currentLine->lineBuf; ++	pb = Currentbuf->currentLine->propBuf; ++ ++	while (lb[Currentbuf->pos] && ++	       IS_WORD_CHAR(lb[Currentbuf->pos], pb[Currentbuf->pos])) ++	    Currentbuf->pos++; ++ ++	while (1) { ++	    while (lb[Currentbuf->pos] && ++		   !IS_WORD_CHAR(lb[Currentbuf->pos], pb[Currentbuf->pos])) ++		Currentbuf->pos++; ++	    if (lb[Currentbuf->pos]) ++		break; ++	    if (next_nonnull_line(Currentbuf->currentLine->next) < 0) { ++		Currentbuf->currentLine = pline; ++		Currentbuf->pos = ppos; ++		goto end; ++	    } ++	    Currentbuf->pos = 0; ++	    lb = Currentbuf->currentLine->lineBuf; ++	    pb = Currentbuf->currentLine->propBuf; ++	} ++    } ++  end: ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++static void ++_quitfm(int confirm) ++{ ++    char *ans = "y"; ++ ++    if (checkDownloadList()) ++	/* FIXME: gettextize? */ ++	ans = inputChar("Download process retains. " ++			"Do you want to exit w3m? (y/n)"); ++    else if (confirm) ++	/* FIXME: gettextize? */ ++	ans = inputChar("Do you want to exit w3m? (y/n)"); ++    if (!(ans && TOLOWER(*ans) == 'y')) { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++ ++    term_title("");		/* XXX */ ++#ifdef USE_IMAGE ++    if (activeImage) ++	termImage(); ++#endif ++    fmTerm(); ++#ifdef USE_COOKIE ++    save_cookies(); ++#endif				/* USE_COOKIE */ ++#ifdef USE_HISTORY ++    if (UseHistory && SaveURLHist) ++	saveHistory(URLHist, URLHistSize); ++#endif				/* USE_HISTORY */ ++    w3m_exit(0); ++} ++ ++/* Quit */ ++DEFUN(quitfm, ABORT EXIT, "Quit w3m without confirmation") ++{ ++    _quitfm(FALSE); ++} ++ ++/* Question and Quit */ ++DEFUN(qquitfm, QUIT, "Quit w3m") ++{ ++    _quitfm(confirm_on_quit); ++} ++ ++/* Select buffer */ ++DEFUN(selBuf, SELECT, "Go to buffer selection panel") ++{ ++    Buffer *buf; ++    int ok; ++    char cmd; ++ ++    ok = FALSE; ++    do { ++	buf = selectBuffer(Firstbuf, Currentbuf, &cmd); ++	switch (cmd) { ++	case 'B': ++	    ok = TRUE; ++	    break; ++	case '\n': ++	case ' ': ++	    Currentbuf = buf; ++	    ok = TRUE; ++	    break; ++	case 'D': ++	    delBuffer(buf); ++	    if (Firstbuf == NULL) { ++		/* No more buffer */ ++		Firstbuf = nullBuffer(); ++		Currentbuf = Firstbuf; ++	    } ++	    break; ++	case 'q': ++	    qquitfm(); ++	    break; ++	case 'Q': ++	    quitfm(); ++	    break; ++	} ++    } while (!ok); ++ ++    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); ++} ++ ++/* Suspend (on BSD), or run interactive shell (on SysV) */ ++DEFUN(susp, INTERRUPT SUSPEND, "Stop loading document") ++{ ++#ifndef SIGSTOP ++    char *shell; ++#endif				/* not SIGSTOP */ ++    move(LASTLINE, 0); ++    clrtoeolx(); ++    refresh(); ++    fmTerm(); ++#ifndef SIGSTOP ++    shell = getenv("SHELL"); ++    if (shell == NULL) ++	shell = "/bin/sh"; ++    system(shell); ++#else				/* SIGSTOP */ ++    kill((pid_t) 0, SIGSTOP); ++#endif				/* SIGSTOP */ ++    fmInit(); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* Go to specified line */ ++static void ++_goLine(char *l) ++{ ++    if (l == NULL || *l == '\0' || Currentbuf->currentLine == NULL) { ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	return; ++    } ++    Currentbuf->pos = 0; ++    if (((*l == '^') || (*l == '$')) && prec_num) { ++	gotoRealLine(Currentbuf, prec_num); ++    } ++    else if (*l == '^') { ++	Currentbuf->topLine = Currentbuf->currentLine = Currentbuf->firstLine; ++    } ++    else if (*l == '$') { ++	Currentbuf->topLine = ++	    lineSkip(Currentbuf, Currentbuf->lastLine, ++		     -(Currentbuf->LINES + 1) / 2, TRUE); ++	Currentbuf->currentLine = Currentbuf->lastLine; ++    } ++    else ++	gotoRealLine(Currentbuf, atoi(l)); ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(goLine, GOTO_LINE, "Go to specified line") ++{ ++ ++    char *str = searchKeyData(); ++    if (prec_num) ++	_goLine("^"); ++    else if (str) ++	_goLine(str); ++    else ++	/* FIXME: gettextize? */ ++	_goLine(inputStr("Goto line: ", "")); ++} ++ ++ ++DEFUN(goLineF, BEGIN, "Go to the first line") ++{ ++    _goLine("^"); ++} ++ ++DEFUN(goLineL, END, "Go to the last line") ++{ ++    _goLine("$"); ++} ++ ++/* Go to the beginning of the line */ ++DEFUN(linbeg, LINE_BEGIN, "Go to the beginning of line") ++{ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    while (Currentbuf->currentLine->prev && Currentbuf->currentLine->bpos) ++	cursorUp0(Currentbuf, 1); ++    Currentbuf->pos = 0; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* Go to the bottom of the line */ ++DEFUN(linend, LINE_END, "Go to the end of line") ++{ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    while (Currentbuf->currentLine->next ++	   && Currentbuf->currentLine->next->bpos) ++	cursorDown0(Currentbuf, 1); ++    Currentbuf->pos = Currentbuf->currentLine->len - 1; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++static int ++cur_real_linenumber(Buffer *buf) ++{ ++    Line *l, *cur = buf->currentLine; ++    int n; ++ ++    if (!cur) ++	return 1; ++    n = cur->real_linenumber ? cur->real_linenumber : 1; ++    for (l = buf->firstLine; l && l != cur && l->real_linenumber == 0; l = l->next) {	/* header */ ++	if (l->bpos == 0) ++	    n++; ++    } ++    return n; ++} ++ ++/* Run editor on the current buffer */ ++DEFUN(editBf, EDIT, "Edit current document") ++{ ++    char *fn = Currentbuf->filename; ++    Str cmd; ++ ++    if (fn == NULL || Currentbuf->pagerSource != NULL ||	/* Behaving as a pager */ ++	(Currentbuf->type == NULL && Currentbuf->edit == NULL) ||	/* Reading shell */ ++	Currentbuf->real_scheme != SCM_LOCAL || !strcmp(Currentbuf->currentURL.file, "-") ||	/* file is std input  */ ++	Currentbuf->bufferprop & BP_FRAME) {	/* Frame */ ++	disp_err_message("Can't edit other than local file", TRUE); ++	return; ++    } ++    if (Currentbuf->edit) ++	cmd = unquote_mailcap(Currentbuf->edit, Currentbuf->real_type, fn, ++			      checkHeader(Currentbuf, "Content-Type:"), NULL); ++    else ++	cmd = myEditor(Editor, shell_quote(fn), ++		       cur_real_linenumber(Currentbuf)); ++    fmTerm(); ++    system(cmd->ptr); ++    fmInit(); ++ ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++    reload(); ++} ++ ++/* Run editor on the current screen */ ++DEFUN(editScr, EDIT_SCREEN, "Edit currently rendered document") ++{ ++    char *tmpf; ++    FILE *f; ++ ++    tmpf = tmpfname(TMPF_DFL, NULL)->ptr; ++    f = fopen(tmpf, "w"); ++    if (f == NULL) { ++	/* FIXME: gettextize? */ ++	disp_err_message(Sprintf("Can't open %s", tmpf)->ptr, TRUE); ++	return; ++    } ++    saveBuffer(Currentbuf, f, TRUE); ++    fclose(f); ++    fmTerm(); ++    system(myEditor(Editor, shell_quote(tmpf), ++		    cur_real_linenumber(Currentbuf))->ptr); ++    fmInit(); ++    unlink(tmpf); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++#ifdef USE_MARK ++ ++/* Set / unset mark */ ++DEFUN(_mark, MARK, "Set/unset mark") ++{ ++    Line *l; ++    if (!use_mark) ++	return; ++    if (Currentbuf->firstLine == NULL) ++	return; ++    l = Currentbuf->currentLine; ++    l->propBuf[Currentbuf->pos] ^= PE_MARK; ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* Go to next mark */ ++DEFUN(nextMk, NEXT_MARK, "Move to next word") ++{ ++    Line *l; ++    int i; ++ ++    if (!use_mark) ++	return; ++    if (Currentbuf->firstLine == NULL) ++	return; ++    i = Currentbuf->pos + 1; ++    l = Currentbuf->currentLine; ++    if (i >= l->len) { ++	i = 0; ++	l = l->next; ++    } ++    while (l != NULL) { ++	for (; i < l->len; i++) { ++	    if (l->propBuf[i] & PE_MARK) { ++		Currentbuf->currentLine = l; ++		Currentbuf->pos = i; ++		arrangeCursor(Currentbuf); ++		displayBuffer(Currentbuf, B_NORMAL); ++		return; ++	    } ++	} ++	l = l->next; ++	i = 0; ++    } ++    /* FIXME: gettextize? */ ++    disp_message("No mark exist after here", TRUE); ++} ++ ++/* Go to previous mark */ ++DEFUN(prevMk, PREV_MARK, "Move to previous mark") ++{ ++    Line *l; ++    int i; ++ ++    if (!use_mark) ++	return; ++    if (Currentbuf->firstLine == NULL) ++	return; ++    i = Currentbuf->pos - 1; ++    l = Currentbuf->currentLine; ++    if (i < 0) { ++	l = l->prev; ++	if (l != NULL) ++	    i = l->len - 1; ++    } ++    while (l != NULL) { ++	for (; i >= 0; i--) { ++	    if (l->propBuf[i] & PE_MARK) { ++		Currentbuf->currentLine = l; ++		Currentbuf->pos = i; ++		arrangeCursor(Currentbuf); ++		displayBuffer(Currentbuf, B_NORMAL); ++		return; ++	    } ++	} ++	l = l->prev; ++	if (l != NULL) ++	    i = l->len - 1; ++    } ++    /* FIXME: gettextize? */ ++    disp_message("No mark exist before here", TRUE); ++} ++ ++/* Mark place to which the regular expression matches */ ++DEFUN(reMark, REG_MARK, "Set mark using regexp") ++{ ++    Line *l; ++    char *str; ++    char *p, *p1, *p2; ++ ++    if (!use_mark) ++	return; ++    str = searchKeyData(); ++    if (str == NULL || *str == '\0') { ++	str = inputStrHist("(Mark)Regexp: ", MarkString, TextHist); ++	if (str == NULL || *str == '\0') { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++    } ++    str = conv_search_string(str, DisplayCharset); ++    if ((str = regexCompile(str, 1)) != NULL) { ++	disp_message(str, TRUE); ++	return; ++    } ++    MarkString = str; ++    for (l = Currentbuf->firstLine; l != NULL; l = l->next) { ++	p = l->lineBuf; ++	for (;;) { ++	    if (regexMatch(p, &l->lineBuf[l->len] - p, p == l->lineBuf) == 1) { ++		matchedPosition(&p1, &p2); ++		l->propBuf[p1 - l->lineBuf] |= PE_MARK; ++		p = p2; ++	    } ++	    else ++		break; ++	} ++    } ++ ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++#endif				/* USE_MARK */ ++ ++static Buffer * ++loadNormalBuf(Buffer *buf, int renderframe) ++{ ++    pushBuffer(buf); ++    if (renderframe && RenderFrame && Currentbuf->frameset != NULL) ++	rFrame(); ++    return buf; ++} ++ ++static Buffer * ++loadLink(char *url, char *target, char *referer, FormList *request) ++{ ++    Buffer *buf, *nfbuf; ++    union frameset_element *f_element = NULL; ++    int flag = 0; ++    ParsedURL *base, pu; ++ ++    message(Sprintf("loading %s", url)->ptr, 0, 0); ++    refresh(); ++ ++    base = baseURL(Currentbuf); ++    if (base == NULL || ++	base->scheme == SCM_LOCAL || base->scheme == SCM_LOCAL_CGI) ++	referer = NO_REFERER; ++    if (referer == NULL) ++	referer = parsedURL2Str(&Currentbuf->currentURL)->ptr; ++    buf = loadGeneralFile(url, baseURL(Currentbuf), referer, flag, request); ++    if (buf == NULL) { ++	char *emsg = Sprintf("Can't load %s", url)->ptr; ++	disp_err_message(emsg, FALSE); ++	return NULL; ++    } ++ ++    parseURL2(url, &pu, base); ++    pushHashHist(URLHist, parsedURL2Str(&pu)->ptr); ++ ++    if (buf == NO_BUFFER) { ++	return NULL; ++    } ++    if (!on_target)		/* open link as an indivisual page */ ++	return loadNormalBuf(buf, TRUE); ++ ++    if (do_download)		/* download (thus no need to render frame) */ ++	return loadNormalBuf(buf, FALSE); ++ ++    if (target == NULL ||	/* no target specified (that means this page is not a frame page) */ ++	!strcmp(target, "_top") ||	/* this link is specified to be opened as an indivisual * page */ ++	!(Currentbuf->bufferprop & BP_FRAME)	/* This page is not a frame page */ ++	) { ++	return loadNormalBuf(buf, TRUE); ++    } ++    nfbuf = Currentbuf->linkBuffer[LB_N_FRAME]; ++    if (nfbuf == NULL) { ++	/* original page (that contains <frameset> tag) doesn't exist */ ++	return loadNormalBuf(buf, TRUE); ++    } ++ ++    f_element = search_frame(nfbuf->frameset, target); ++    if (f_element == NULL) { ++	/* specified target doesn't exist in this frameset */ ++	return loadNormalBuf(buf, TRUE); ++    } ++ ++    /* frame page */ ++ ++    /* stack current frameset */ ++    pushFrameTree(&(nfbuf->frameQ), copyFrameSet(nfbuf->frameset), Currentbuf); ++    /* delete frame view buffer */ ++    delBuffer(Currentbuf); ++    Currentbuf = nfbuf; ++    /* nfbuf->frameset = copyFrameSet(nfbuf->frameset); */ ++    resetFrameElement(f_element, buf, referer, request); ++    discardBuffer(buf); ++    rFrame(); ++    { ++	Anchor *al = NULL; ++	char *label = pu.label; ++ ++	if (label && f_element->element->attr == F_BODY) { ++	    al = searchAnchor(f_element->body->nameList, label); ++	} ++	if (!al) { ++	    label = Strnew_m_charp("_", target, NULL)->ptr; ++	    al = searchURLLabel(Currentbuf, label); ++	} ++	if (al) { ++	    gotoLine(Currentbuf, al->start.line); ++	    if (label_topline) ++		Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->topLine, ++					       Currentbuf->currentLine-> ++					       linenumber - ++					       Currentbuf->topLine->linenumber, ++					       FALSE); ++	    Currentbuf->pos = al->start.pos; ++	    arrangeCursor(Currentbuf); ++	} ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++    return buf; ++} ++ ++static void ++gotoLabel(char *label) ++{ ++    Buffer *buf; ++    Anchor *al; ++    int i; ++ ++    al = searchURLLabel(Currentbuf, label); ++    if (al == NULL) { ++	/* FIXME: gettextize? */ ++	disp_message(Sprintf("%s is not found", label)->ptr, TRUE); ++	return; ++    } ++    buf = newBuffer(Currentbuf->width); ++    copyBuffer(buf, Currentbuf); ++    for (i = 0; i < MAX_LB; i++) ++	buf->linkBuffer[i] = NULL; ++    buf->currentURL.label = allocStr(label, -1); ++    pushHashHist(URLHist, parsedURL2Str(&buf->currentURL)->ptr); ++    (*buf->clone)++; ++    pushBuffer(buf); ++    gotoLine(Currentbuf, al->start.line); ++    if (label_topline) ++	Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->topLine, ++				       Currentbuf->currentLine->linenumber ++				       - Currentbuf->topLine->linenumber, ++				       FALSE); ++    Currentbuf->pos = al->start.pos; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++    return; ++} ++ ++/* follow HREF link */ ++DEFUN(followA, GOTO_LINK, "Go to current link") ++{ ++    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, a, &x, &y); ++	map = 1; ++    } ++#else ++    a = retrieveCurrentMap(Currentbuf); ++    if (a) { ++	_followForm(FALSE); ++	return; ++    } ++#endif ++    a = retrieveCurrentAnchor(Currentbuf); ++    if (a == NULL) { ++	_followForm(FALSE); ++	return; ++    } ++    if (*a->url == '#') {	/* index within this buffer */ ++	gotoLabel(a->url + 1); ++	return; ++    } ++    parseURL2(a->url, &u, baseURL(Currentbuf)); ++    if (Strcmp(parsedURL2Str(&u), parsedURL2Str(&Currentbuf->currentURL)) == 0) { ++	/* index within this buffer */ ++	if (u.label) { ++	    gotoLabel(u.label); ++	    return; ++	} ++    } ++    if (!strncasecmp(a->url, "mailto:", 7) ++#ifdef USE_W3MMAILER ++	&& non_null(Mailer) && strchr(a->url, '?') == NULL ++#endif ++	) { ++	/* invoke external mailer */ ++	Str to = Strnew_charp(a->url + 7); ++#ifndef USE_W3MMAILER ++	char *pos; ++	if (!non_null(Mailer)) { ++	    /* FIXME: gettextize? */ ++	    disp_err_message("no mailer is specified", TRUE); ++	    return; ++	} ++	if ((pos = strchr(to->ptr, '?')) != NULL) ++	    Strtruncate(to, pos - to->ptr); ++#endif ++	fmTerm(); ++	system(myExtCommand(Mailer, shell_quote(file_unquote(to->ptr)), ++			    FALSE)->ptr); ++	fmInit(); ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	pushHashHist(URLHist, a->url); ++	return; ++    } ++#if 0 ++    else if (!strncasecmp(a->url, "news:", 5) && strchr(a->url, '@') == NULL) { ++	/* news:newsgroup is not supported */ ++	/* FIXME: gettextize? */ ++	disp_err_message("news:newsgroup_name is not supported", TRUE); ++	return; ++    } ++#endif				/* USE_NNTP */ ++    url = a->url; ++#ifdef USE_IMAGE ++    if (map) ++	url = Sprintf("%s?%d,%d", a->url, x, y)->ptr; ++#endif ++ ++    if (check_target && open_tab_blank && a->target && ++	(!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) { ++	Buffer *buf; ++ ++	_newT(); ++	buf = Currentbuf; ++	loadLink(url, a->target, a->referer, NULL); ++	if (buf != Currentbuf) ++	    delBuffer(buf); ++	else ++	    deleteTab(CurrentTab); ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	return; ++    } ++    loadLink(url, a->target, a->referer, NULL); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* follow HREF link in the buffer */ ++void ++bufferA(void) ++{ ++    on_target = FALSE; ++    followA(); ++    on_target = TRUE; ++} ++ ++/* view inline image */ ++DEFUN(followI, VIEW_IMAGE, "View image") ++{ ++    Line *l; ++    Anchor *a; ++    Buffer *buf; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    l = Currentbuf->currentLine; ++ ++    a = retrieveCurrentImg(Currentbuf); ++    if (a == NULL) ++	return; ++    /* FIXME: gettextize? */ ++    message(Sprintf("loading %s", a->url)->ptr, 0, 0); ++    refresh(); ++    buf = loadGeneralFile(a->url, baseURL(Currentbuf), NULL, 0, NULL); ++    if (buf == NULL) { ++	/* FIXME: gettextize? */ ++	char *emsg = Sprintf("Can't load %s", a->url)->ptr; ++	disp_err_message(emsg, FALSE); ++    } ++    else if (buf != NO_BUFFER) { ++	pushBuffer(buf); ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++static FormItemList * ++save_submit_formlist(FormItemList *src) ++{ ++    FormList *list; ++    FormList *srclist; ++    FormItemList *srcitem; ++    FormItemList *item; ++    FormItemList *ret = NULL; ++#ifdef MENU_SELECT ++    FormSelectOptionItem *opt; ++    FormSelectOptionItem *curopt; ++    FormSelectOptionItem *srcopt; ++#endif				/* MENU_SELECT */ ++ ++    if (src == NULL) ++	return NULL; ++    srclist = src->parent; ++    list = New(FormList); ++    list->method = srclist->method; ++    list->action = Strdup(srclist->action); ++#ifdef USE_M17N ++    list->charset = srclist->charset; ++#endif ++    list->enctype = srclist->enctype; ++    list->nitems = srclist->nitems; ++    list->body = srclist->body; ++    list->boundary = srclist->boundary; ++    list->length = srclist->length; ++ ++    for (srcitem = srclist->item; srcitem; srcitem = srcitem->next) { ++	item = New(FormItemList); ++	item->type = srcitem->type; ++	item->name = Strdup(srcitem->name); ++	item->value = Strdup(srcitem->value); ++	item->checked = srcitem->checked; ++	item->accept = srcitem->accept; ++	item->size = srcitem->size; ++	item->rows = srcitem->rows; ++	item->maxlength = srcitem->maxlength; ++	item->readonly = srcitem->readonly; ++#ifdef MENU_SELECT ++	opt = curopt = NULL; ++	for (srcopt = srcitem->select_option; srcopt; srcopt = srcopt->next) { ++	    if (!srcopt->checked) ++		continue; ++	    opt = New(FormSelectOptionItem); ++	    opt->value = Strdup(srcopt->value); ++	    opt->label = Strdup(srcopt->label); ++	    opt->checked = srcopt->checked; ++	    if (item->select_option == NULL) { ++		item->select_option = curopt = opt; ++	    } ++	    else { ++		curopt->next = opt; ++		curopt = curopt->next; ++	    } ++	} ++	item->select_option = opt; ++	if (srcitem->label) ++	    item->label = Strdup(srcitem->label); ++#endif				/* MENU_SELECT */ ++	item->parent = list; ++	item->next = NULL; ++ ++	if (list->lastitem == NULL) { ++	    list->item = list->lastitem = item; ++	} ++	else { ++	    list->lastitem->next = item; ++	    list->lastitem = item; ++	} ++ ++	if (srcitem == src) ++	    ret = item; ++    } ++ ++    return ret; ++} ++ ++#ifdef USE_M17N ++static Str ++conv_form_encoding(Str val, FormItemList *fi, Buffer *buf) ++{ ++    wc_ces charset = SystemCharset; ++ ++    if (fi->parent->charset) ++	charset = fi->parent->charset; ++    else if (buf->document_charset && buf->document_charset != WC_CES_US_ASCII) ++	charset = buf->document_charset; ++    return wc_Str_conv_strict(val, InnerCharset, charset); ++} ++#else ++#define conv_form_encoding(val, fi, buf) (val) ++#endif ++ ++static void ++query_from_followform(Str *query, FormItemList *fi, int multipart) ++{ ++    FormItemList *f2; ++    FILE *body = NULL; ++ ++    if (multipart) { ++	*query = tmpfname(TMPF_DFL, NULL); ++	body = fopen((*query)->ptr, "w"); ++	if (body == NULL) { ++	    return; ++	} ++	fi->parent->body = (*query)->ptr; ++	fi->parent->boundary = ++	    Sprintf("------------------------------%d%ld%ld%ld", CurrentPid, ++		    fi->parent, fi->parent->body, fi->parent->boundary)->ptr; ++    } ++    *query = Strnew(); ++    for (f2 = fi->parent->item; f2; f2 = f2->next) { ++	if (f2->name == NULL) ++	    continue; ++	/* <ISINDEX> is translated into single text form */ ++	if (f2->name->length == 0 && ++	    (multipart || f2->type != FORM_INPUT_TEXT)) ++	    continue; ++	switch (f2->type) { ++	case FORM_INPUT_RESET: ++	    /* do nothing */ ++	    continue; ++	case FORM_INPUT_SUBMIT: ++	case FORM_INPUT_IMAGE: ++	    if (f2 != fi || f2->value == NULL) ++		continue; ++	    break; ++	case FORM_INPUT_RADIO: ++	case FORM_INPUT_CHECKBOX: ++	    if (!f2->checked) ++		continue; ++	} ++	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(conv_form_encoding(f2->name, fi, Currentbuf)); ++		Strcat_charp(*query, ".x"); ++		form_write_data(body, fi->parent->boundary, (*query)->ptr, ++				Sprintf("%d", x)->ptr); ++		*query = Strdup(conv_form_encoding(f2->name, fi, Currentbuf)); ++		Strcat_charp(*query, ".y"); ++		form_write_data(body, fi->parent->boundary, (*query)->ptr, ++				Sprintf("%d", y)->ptr); ++	    } ++	    else if (f2->name && f2->name->length > 0 && f2->value != NULL) { ++		/* not IMAGE */ ++		*query = conv_form_encoding(f2->value, fi, Currentbuf); ++		if (f2->type == FORM_INPUT_FILE) ++		    form_write_from_file(body, fi->parent->boundary, ++					 conv_form_encoding(f2->name, fi, ++							    Currentbuf)->ptr, ++					 (*query)->ptr, ++					 Str_conv_to_system(f2->value)->ptr); ++		else ++		    form_write_data(body, fi->parent->boundary, ++				    conv_form_encoding(f2->name, fi, ++						       Currentbuf)->ptr, ++				    (*query)->ptr); ++	    } ++	} ++	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, ++		       Str_form_quote(conv_form_encoding ++				      (f2->name, fi, Currentbuf))); ++		Strcat(*query, Sprintf(".x=%d&", x)); ++		Strcat(*query, ++		       Str_form_quote(conv_form_encoding ++				      (f2->name, fi, Currentbuf))); ++		Strcat(*query, Sprintf(".y=%d", y)); ++	    } ++	    else { ++		/* not IMAGE */ ++		if (f2->name && f2->name->length > 0) { ++		    Strcat(*query, ++			   Str_form_quote(conv_form_encoding ++					  (f2->name, fi, Currentbuf))); ++		    Strcat_char(*query, '='); ++		} ++		if (f2->value != NULL) { ++		    if (fi->parent->method == FORM_METHOD_INTERNAL) ++			Strcat(*query, Str_form_quote(f2->value)); ++		    else { ++			Strcat(*query, ++			       Str_form_quote(conv_form_encoding ++					      (f2->value, fi, Currentbuf))); ++		    } ++		} ++	    } ++	    if (f2->next) ++		Strcat_char(*query, '&'); ++	} ++    } ++    if (multipart) { ++	fprintf(body, "--%s--\r\n", fi->parent->boundary); ++	fclose(body); ++    } ++    else { ++	/* remove trailing & */ ++	while (Strlastchar(*query) == '&') ++	    Strshrink(*query, 1); ++    } ++} ++ ++/* submit form */ ++DEFUN(submitForm, SUBMIT, "Submit form") ++{ ++    _followForm(TRUE); ++} ++ ++/* process form */ ++void ++followForm(void) ++{ ++    _followForm(FALSE); ++} ++ ++static void ++_followForm(int submit) ++{ ++    Line *l; ++    Anchor *a, *a2; ++    char *p; ++    FormItemList *fi, *f2; ++    Str tmp, tmp2; ++    int multipart = 0, i; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    l = Currentbuf->currentLine; ++ ++    a = retrieveCurrentForm(Currentbuf); ++    if (a == NULL) ++	return; ++    fi = (FormItemList *)a->url; ++    switch (fi->type) { ++    case FORM_INPUT_TEXT: ++	if (submit) ++	    goto do_submit; ++	if (fi->readonly) ++	    /* FIXME: gettextize? */ ++	    disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE); ++	/* FIXME: gettextize? */ ++	p = inputStrHist("TEXT:", fi->value ? fi->value->ptr : NULL, TextHist); ++	if (p == NULL || fi->readonly) ++	    break; ++	fi->value = Strnew_charp(p); ++	formUpdateBuffer(a, Currentbuf, fi); ++	if (fi->accept || fi->parent->nitems == 1) ++	    goto do_submit; ++	break; ++    case FORM_INPUT_FILE: ++	if (submit) ++	    goto do_submit; ++	if (fi->readonly) ++	    /* FIXME: gettextize? */ ++	    disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE); ++	/* FIXME: gettextize? */ ++	p = inputFilenameHist("Filename:", fi->value ? fi->value->ptr : NULL, ++			      NULL); ++	if (p == NULL || fi->readonly) ++	    break; ++	fi->value = Strnew_charp(p); ++	formUpdateBuffer(a, Currentbuf, fi); ++	if (fi->accept || fi->parent->nitems == 1) ++	    goto do_submit; ++	break; ++    case FORM_INPUT_PASSWORD: ++	if (submit) ++	    goto do_submit; ++	if (fi->readonly) { ++	    /* FIXME: gettextize? */ ++	    disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE); ++	    break; ++	} ++	/* FIXME: gettextize? */ ++	p = inputLine("Password:", fi->value ? fi->value->ptr : NULL, ++		      IN_PASSWORD); ++	if (p == NULL) ++	    break; ++	fi->value = Strnew_charp(p); ++	formUpdateBuffer(a, Currentbuf, fi); ++	if (fi->accept) ++	    goto do_submit; ++	break; ++    case FORM_TEXTAREA: ++	if (submit) ++	    goto do_submit; ++	if (fi->readonly) ++	    /* FIXME: gettextize? */ ++	    disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE); ++	input_textarea(fi); ++	formUpdateBuffer(a, Currentbuf, fi); ++	break; ++    case FORM_INPUT_RADIO: ++	if (submit) ++	    goto do_submit; ++	if (fi->readonly) { ++	    /* FIXME: gettextize? */ ++	    disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE); ++	    break; ++	} ++	formRecheckRadio(a, Currentbuf, fi); ++	break; ++    case FORM_INPUT_CHECKBOX: ++	if (submit) ++	    goto do_submit; ++	if (fi->readonly) { ++	    /* FIXME: gettextize? */ ++	    disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE); ++	    break; ++	} ++	fi->checked = !fi->checked; ++	formUpdateBuffer(a, Currentbuf, fi); ++	break; ++#ifdef MENU_SELECT ++    case FORM_SELECT: ++	if (submit) ++	    goto do_submit; ++	if (!formChooseOptionByMenu(fi, ++				    Currentbuf->cursorX - Currentbuf->pos + ++				    a->start.pos + Currentbuf->rootX, ++				    Currentbuf->cursorY + Currentbuf->rootY)) ++	    break; ++	formUpdateBuffer(a, Currentbuf, fi); ++	if (fi->parent->nitems == 1) ++	    goto do_submit; ++	break; ++#endif				/* MENU_SELECT */ ++    case FORM_INPUT_IMAGE: ++    case FORM_INPUT_SUBMIT: ++    case FORM_INPUT_BUTTON: ++      do_submit: ++	tmp = Strnew(); ++	tmp2 = Strnew(); ++	multipart = (fi->parent->method == FORM_METHOD_POST && ++		     fi->parent->enctype == FORM_ENCTYPE_MULTIPART); ++	query_from_followform(&tmp, fi, multipart); ++ ++	tmp2 = Strdup(fi->parent->action); ++	if (!Strcmp_charp(tmp2, "!CURRENT_URL!")) { ++	    /* It means "current URL" */ ++	    tmp2 = parsedURL2Str(&Currentbuf->currentURL); ++	    if ((p = strchr(tmp2->ptr, '?')) != NULL) ++		Strshrink(tmp2, (tmp2->ptr + tmp2->length) - p); ++	} ++ ++	if (fi->parent->method == FORM_METHOD_GET) { ++	    if ((p = strchr(tmp2->ptr, '?')) != NULL) ++		Strshrink(tmp2, (tmp2->ptr + tmp2->length) - p); ++	    Strcat_charp(tmp2, "?"); ++	    Strcat(tmp2, tmp); ++	    loadLink(tmp2->ptr, a->target, NULL, NULL); ++	} ++	else if (fi->parent->method == FORM_METHOD_POST) { ++	    Buffer *buf; ++	    if (multipart) { ++		struct stat st; ++		stat(fi->parent->body, &st); ++		fi->parent->length = st.st_size; ++	    } ++	    else { ++		fi->parent->body = tmp->ptr; ++		fi->parent->length = tmp->length; ++	    } ++	    buf = loadLink(tmp2->ptr, a->target, NULL, fi->parent); ++	    if (multipart) { ++		unlink(fi->parent->body); ++	    } ++	    if (buf && !(buf->bufferprop & BP_REDIRECTED)) {	/* buf must be Currentbuf */ ++		/* BP_REDIRECTED means that the buffer is obtained through ++		 * Location: header. In this case, buf->form_submit must not be set ++		 * because the page is not loaded by POST method but GET method. ++		 */ ++		buf->form_submit = save_submit_formlist(fi); ++	    } ++	} ++	else if ((fi->parent->method == FORM_METHOD_INTERNAL && (!Strcmp_charp(fi->parent->action, "map") || !Strcmp_charp(fi->parent->action, "none"))) || Currentbuf->bufferprop & BP_INTERNAL) {	/* internal */ ++	    do_internal(tmp2->ptr, tmp->ptr); ++	} ++	else { ++	    disp_err_message("Can't send form because of illegal method.", ++			     FALSE); ++	} ++	break; ++    case FORM_INPUT_RESET: ++	for (i = 0; i < Currentbuf->formitem->nanchor; i++) { ++	    a2 = &Currentbuf->formitem->anchors[i]; ++	    f2 = (FormItemList *)a2->url; ++	    if (f2->parent == fi->parent && ++		f2->name && f2->value && ++		f2->type != FORM_INPUT_SUBMIT && ++		f2->type != FORM_INPUT_HIDDEN && ++		f2->type != FORM_INPUT_RESET) { ++		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(a2, Currentbuf, f2); ++	    } ++	} ++	break; ++    case FORM_INPUT_HIDDEN: ++    default: ++	break; ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* go to the top anchor */ ++DEFUN(topA, LINK_BEGIN, "Go to the first link") ++{ ++    HmarkerList *hl = Currentbuf->hmarklist; ++    BufferPoint *po; ++    Anchor *an; ++    int hseq = 0; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    if (!hl || hl->nmark == 0) ++	return; ++ ++    if (prec_num > hl->nmark) ++	hseq = hl->nmark - 1; ++    else if (prec_num > 0) ++	hseq = prec_num - 1; ++    do { ++	if (hseq >= hl->nmark) ++	    return; ++	po = hl->marks + hseq; ++	an = retrieveAnchor(Currentbuf->href, po->line, po->pos); ++	if (an == NULL) ++	    an = retrieveAnchor(Currentbuf->formitem, po->line, po->pos); ++	hseq++; ++    } while (an == NULL); ++ ++    gotoLine(Currentbuf, po->line); ++    Currentbuf->pos = po->pos; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* go to the last anchor */ ++DEFUN(lastA, LINK_END, "Go to the last link") ++{ ++    HmarkerList *hl = Currentbuf->hmarklist; ++    BufferPoint *po; ++    Anchor *an; ++    int hseq; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    if (!hl || hl->nmark == 0) ++	return; ++ ++    if (prec_num >= hl->nmark) ++	hseq = 0; ++    else if (prec_num > 0) ++	hseq = hl->nmark - prec_num; ++    else ++	hseq = hl->nmark - 1; ++    do { ++	if (hseq < 0) ++	    return; ++	po = hl->marks + hseq; ++	an = retrieveAnchor(Currentbuf->href, po->line, po->pos); ++	if (an == NULL) ++	    an = retrieveAnchor(Currentbuf->formitem, po->line, po->pos); ++	hseq--; ++    } while (an == NULL); ++ ++    gotoLine(Currentbuf, po->line); ++    Currentbuf->pos = po->pos; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* go to the next anchor */ ++DEFUN(nextA, NEXT_LINK, "Move to next link") ++{ ++    _nextA(FALSE); ++} ++ ++/* go to the previous anchor */ ++DEFUN(prevA, PREV_LINK, "Move to previous link") ++{ ++    _prevA(FALSE); ++} ++ ++/* go to the next visited anchor */ ++DEFUN(nextVA, NEXT_VISITED, "Move to next visited link") ++{ ++    _nextA(TRUE); ++} ++ ++/* go to the previous visited anchor */ ++DEFUN(prevVA, PREV_VISITED, "Move to previous visited link") ++{ ++    _prevA(TRUE); ++} ++ ++/* go to the next [visited] anchor */ ++static void ++_nextA(int visited) ++{ ++    HmarkerList *hl = Currentbuf->hmarklist; ++    BufferPoint *po; ++    Anchor *an, *pan; ++    int i, x, y, n = searchKeyNum(); ++    ParsedURL url; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    if (!hl || hl->nmark == 0) ++	return; ++ ++    an = retrieveCurrentAnchor(Currentbuf); ++    if (visited != TRUE && an == NULL) ++	an = retrieveCurrentForm(Currentbuf); ++ ++    y = Currentbuf->currentLine->linenumber; ++    x = Currentbuf->pos; ++ ++    if (visited == TRUE) { ++	n = hl->nmark; ++    } ++ ++    for (i = 0; i < n; i++) { ++	pan = an; ++	if (an && an->hseq >= 0) { ++	    int hseq = an->hseq + 1; ++	    do { ++		if (hseq >= hl->nmark) { ++		    if (visited == TRUE) ++			return; ++		    an = pan; ++		    goto _end; ++		} ++		po = &hl->marks[hseq]; ++		an = retrieveAnchor(Currentbuf->href, po->line, po->pos); ++		if (visited != TRUE && an == NULL) ++		    an = retrieveAnchor(Currentbuf->formitem, po->line, ++					po->pos); ++		hseq++; ++		if (visited == TRUE && an) { ++		    parseURL2(an->url, &url, baseURL(Currentbuf)); ++		    if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) { ++			goto _end; ++		    } ++		} ++	    } while (an == NULL || an == pan); ++	} ++	else { ++	    an = closest_next_anchor(Currentbuf->href, NULL, x, y); ++	    if (visited != TRUE) ++		an = closest_next_anchor(Currentbuf->formitem, an, x, y); ++	    if (an == NULL) { ++		if (visited == TRUE) ++		    return; ++		an = pan; ++		break; ++	    } ++	    x = an->start.pos; ++	    y = an->start.line; ++	    if (visited == TRUE) { ++		parseURL2(an->url, &url, baseURL(Currentbuf)); ++		if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) { ++		    goto _end; ++		} ++	    } ++	} ++    } ++    if (visited == TRUE) ++	return; ++ ++  _end: ++    if (an == NULL || an->hseq < 0) ++	return; ++    po = &hl->marks[an->hseq]; ++    gotoLine(Currentbuf, po->line); ++    Currentbuf->pos = po->pos; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* go to the previous anchor */ ++static void ++_prevA(int visited) ++{ ++    HmarkerList *hl = Currentbuf->hmarklist; ++    BufferPoint *po; ++    Anchor *an, *pan; ++    int i, x, y, n = searchKeyNum(); ++    ParsedURL url; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    if (!hl || hl->nmark == 0) ++	return; ++ ++    an = retrieveCurrentAnchor(Currentbuf); ++    if (visited != TRUE && an == NULL) ++	an = retrieveCurrentForm(Currentbuf); ++ ++    y = Currentbuf->currentLine->linenumber; ++    x = Currentbuf->pos; ++ ++    if (visited == TRUE) { ++	n = hl->nmark; ++    } ++ ++    for (i = 0; i < n; i++) { ++	pan = an; ++	if (an && an->hseq >= 0) { ++	    int hseq = an->hseq - 1; ++	    do { ++		if (hseq < 0) { ++		    if (visited == TRUE) ++			return; ++		    an = pan; ++		    goto _end; ++		} ++		po = hl->marks + hseq; ++		an = retrieveAnchor(Currentbuf->href, po->line, po->pos); ++		if (visited != TRUE && an == NULL) ++		    an = retrieveAnchor(Currentbuf->formitem, po->line, ++					po->pos); ++		hseq--; ++		if (visited == TRUE && an) { ++		    parseURL2(an->url, &url, baseURL(Currentbuf)); ++		    if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) { ++			goto _end; ++		    } ++		} ++	    } while (an == NULL || an == pan); ++	} ++	else { ++	    an = closest_prev_anchor(Currentbuf->href, NULL, x, y); ++	    if (visited != TRUE) ++		an = closest_prev_anchor(Currentbuf->formitem, an, x, y); ++	    if (an == NULL) { ++		if (visited == TRUE) ++		    return; ++		an = pan; ++		break; ++	    } ++	    x = an->start.pos; ++	    y = an->start.line; ++	    if (visited == TRUE && an) { ++		parseURL2(an->url, &url, baseURL(Currentbuf)); ++		if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) { ++		    goto _end; ++		} ++	    } ++	} ++    } ++    if (visited == TRUE) ++	return; ++ ++  _end: ++    if (an == NULL || an->hseq < 0) ++	return; ++    po = hl->marks + an->hseq; ++    gotoLine(Currentbuf, po->line); ++    Currentbuf->pos = po->pos; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* go to the next left/right anchor */ ++static void ++nextX(int d, int dy) ++{ ++    HmarkerList *hl = Currentbuf->hmarklist; ++    Anchor *an, *pan; ++    Line *l; ++    int i, x, y, n = searchKeyNum(); ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    if (!hl || hl->nmark == 0) ++	return; ++ ++    an = retrieveCurrentAnchor(Currentbuf); ++    if (an == NULL) ++	an = retrieveCurrentForm(Currentbuf); ++ ++    l = Currentbuf->currentLine; ++    x = Currentbuf->pos; ++    y = l->linenumber; ++    pan = NULL; ++    for (i = 0; i < n; i++) { ++	if (an) ++	    x = (d > 0) ? an->end.pos : an->start.pos - 1; ++	an = NULL; ++	while (1) { ++	    for (; x >= 0 && x < l->len; x += d) { ++		an = retrieveAnchor(Currentbuf->href, y, x); ++		if (!an) ++		    an = retrieveAnchor(Currentbuf->formitem, y, x); ++		if (an) { ++		    pan = an; ++		    break; ++		} ++	    } ++	    if (!dy || an) ++		break; ++	    l = (dy > 0) ? l->next : l->prev; ++	    if (!l) ++		break; ++	    x = (d > 0) ? 0 : l->len - 1; ++	    y = l->linenumber; ++	} ++	if (!an) ++	    break; ++    } ++ ++    if (pan == NULL) ++	return; ++    gotoLine(Currentbuf, y); ++    Currentbuf->pos = pan->start.pos; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* go to the next downward/upward anchor */ ++static void ++nextY(int d) ++{ ++    HmarkerList *hl = Currentbuf->hmarklist; ++    Anchor *an, *pan; ++    int i, x, y, n = searchKeyNum(); ++    int hseq; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    if (!hl || hl->nmark == 0) ++	return; ++ ++    an = retrieveCurrentAnchor(Currentbuf); ++    if (an == NULL) ++	an = retrieveCurrentForm(Currentbuf); ++ ++    x = Currentbuf->pos; ++    y = Currentbuf->currentLine->linenumber + d; ++    pan = NULL; ++    hseq = -1; ++    for (i = 0; i < n; i++) { ++	if (an) ++	    hseq = abs(an->hseq); ++	an = NULL; ++	for (; y >= 0 && y <= Currentbuf->lastLine->linenumber; y += d) { ++	    an = retrieveAnchor(Currentbuf->href, y, x); ++	    if (!an) ++		an = retrieveAnchor(Currentbuf->formitem, y, x); ++	    if (an && hseq != abs(an->hseq)) { ++		pan = an; ++		break; ++	    } ++	} ++	if (!an) ++	    break; ++    } ++ ++    if (pan == NULL) ++	return; ++    gotoLine(Currentbuf, pan->start.line); ++    arrangeLine(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* go to the next left anchor */ ++DEFUN(nextL, NEXT_LEFT, "Move to next left link") ++{ ++    nextX(-1, 0); ++} ++ ++/* go to the next left-up anchor */ ++DEFUN(nextLU, NEXT_LEFT_UP, "Move to next left (or upward) link") ++{ ++    nextX(-1, -1); ++} ++ ++/* go to the next right anchor */ ++DEFUN(nextR, NEXT_RIGHT, "Move to next right link") ++{ ++    nextX(1, 0); ++} ++ ++/* go to the next right-down anchor */ ++DEFUN(nextRD, NEXT_RIGHT_DOWN, "Move to next right (or downward) link") ++{ ++    nextX(1, 1); ++} ++ ++/* go to the next downward anchor */ ++DEFUN(nextD, NEXT_DOWN, "Move to next downward link") ++{ ++    nextY(1); ++} ++ ++/* go to the next upward anchor */ ++DEFUN(nextU, NEXT_UP, "Move to next upward link") ++{ ++    nextY(-1); ++} ++ ++/* go to the next bufferr */ ++DEFUN(nextBf, NEXT, "Move to next buffer") ++{ ++    Buffer *buf; ++    int i; ++ ++    for (i = 0; i < PREC_NUM; i++) { ++	buf = prevBuffer(Firstbuf, Currentbuf); ++	if (!buf) { ++	    if (i == 0) ++		return; ++	    break; ++	} ++	Currentbuf = buf; ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* go to the previous bufferr */ ++DEFUN(prevBf, PREV, "Move to previous buffer") ++{ ++    Buffer *buf; ++    int i; ++ ++    for (i = 0; i < PREC_NUM; i++) { ++	buf = Currentbuf->nextBuffer; ++	if (!buf) { ++	    if (i == 0) ++		return; ++	    break; ++	} ++	Currentbuf = buf; ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++static int ++checkBackBuffer(Buffer *buf) ++{ ++    Buffer *fbuf = buf->linkBuffer[LB_N_FRAME]; ++ ++    if (fbuf) { ++	if (fbuf->frameQ) ++	    return TRUE;	/* Currentbuf has stacked frames */ ++	/* when no frames stacked and next is frame source, try next's ++	 * nextBuffer */ ++	if (RenderFrame && fbuf == buf->nextBuffer) { ++	    if (fbuf->nextBuffer != NULL) ++		return TRUE; ++	    else ++		return FALSE; ++	} ++    } ++ ++    if (buf->nextBuffer) ++	return TRUE; ++ ++    return FALSE; ++} ++ ++/* delete current buffer and back to the previous buffer */ ++DEFUN(backBf, BACK, "Back to previous buffer") ++{ ++    Buffer *buf = Currentbuf->linkBuffer[LB_N_FRAME]; ++ ++    if (!checkBackBuffer(Currentbuf)) { ++	if (close_tab_back && nTab >= 1) { ++	    deleteTab(CurrentTab); ++	    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	} ++	else ++	    /* FIXME: gettextize? */ ++	    disp_message("Can't back...", TRUE); ++	return; ++    } ++ ++    delBuffer(Currentbuf); ++ ++    if (buf) { ++	if (buf->frameQ) { ++	    struct frameset *fs; ++	    long linenumber = buf->frameQ->linenumber; ++	    long top = buf->frameQ->top_linenumber; ++	    int pos = buf->frameQ->pos; ++	    int currentColumn = buf->frameQ->currentColumn; ++	    AnchorList *formitem = buf->frameQ->formitem; ++ ++	    fs = popFrameTree(&(buf->frameQ)); ++	    deleteFrameSet(buf->frameset); ++	    buf->frameset = fs; ++ ++	    if (buf == Currentbuf) { ++		rFrame(); ++		Currentbuf->topLine = lineSkip(Currentbuf, ++					       Currentbuf->firstLine, top - 1, ++					       FALSE); ++		gotoLine(Currentbuf, linenumber); ++		Currentbuf->pos = pos; ++		Currentbuf->currentColumn = currentColumn; ++		arrangeCursor(Currentbuf); ++		formResetBuffer(Currentbuf, formitem); ++	    } ++	} ++	else if (RenderFrame && buf == Currentbuf) { ++	    delBuffer(Currentbuf); ++	} ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(deletePrevBuf, DELETE_PREVBUF, ++      "Delete previous buffer (mainly for local-CGI)") ++{ ++    Buffer *buf = Currentbuf->nextBuffer; ++    if (buf) ++	delBuffer(buf); ++} ++ ++static void ++cmd_loadURL(char *url, ParsedURL *current, char *referer, FormList *request) ++{ ++    Buffer *buf; ++ ++    if (!strncasecmp(url, "mailto:", 7) ++#ifdef USE_W3MMAILER ++	&& non_null(Mailer) && strchr(url, '?') == NULL ++#endif ++	) { ++	/* invoke external mailer */ ++	Str to = Strnew_charp(url + 7); ++#ifndef USE_W3MMAILER ++	char *pos; ++	if (!non_null(Mailer)) { ++	    /* FIXME: gettextize? */ ++	    disp_err_message("no mailer is specified", TRUE); ++	    return; ++	} ++	if ((pos = strchr(to->ptr, '?')) != NULL) ++	    Strtruncate(to, pos - to->ptr); ++#endif ++	fmTerm(); ++	system(myExtCommand(Mailer, shell_quote(file_unquote(to->ptr)), ++			    FALSE)->ptr); ++	fmInit(); ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	pushHashHist(URLHist, url); ++	return; ++    } ++#if 0 ++    if (!strncasecmp(url, "news:", 5) && strchr(url, '@') == NULL) { ++	/* news:newsgroup is not supported */ ++	/* FIXME: gettextize? */ ++	disp_err_message("news:newsgroup_name is not supported", TRUE); ++	return; ++    } ++#endif				/* USE_NNTP */ ++ ++    refresh(); ++    buf = loadGeneralFile(url, current, referer, 0, request); ++    if (buf == NULL) { ++	/* FIXME: gettextize? */ ++	char *emsg = Sprintf("Can't load %s", conv_from_system(url))->ptr; ++	disp_err_message(emsg, FALSE); ++    } ++    else if (buf != NO_BUFFER) { ++	pushBuffer(buf); ++	if (RenderFrame && Currentbuf->frameset != NULL) ++	    rFrame(); ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++ ++/* go to specified URL */ ++static void ++goURL0(char *prompt, int relative) ++{ ++    char *url, *referer; ++    ParsedURL p_url, *current; ++    Buffer *cur_buf = Currentbuf; ++ ++    url = searchKeyData(); ++    if (url == NULL) { ++	Hist *hist = copyHist(URLHist); ++	Anchor *a; ++ ++	current = baseURL(Currentbuf); ++	if (current) { ++	    char *c_url = parsedURL2Str(current)->ptr; ++	    if (DefaultURLString == DEFAULT_URL_CURRENT) { ++		url = c_url; ++		if (DecodeURL) ++		    url = url_unquote_conv(url, 0); ++	    } ++	    else ++		pushHist(hist, c_url); ++	} ++	a = retrieveCurrentAnchor(Currentbuf); ++	if (a) { ++	    char *a_url; ++	    parseURL2(a->url, &p_url, current); ++	    a_url = parsedURL2Str(&p_url)->ptr; ++	    if (DefaultURLString == DEFAULT_URL_LINK) { ++		url = a_url; ++		if (DecodeURL) ++		    url = url_unquote_conv(url, Currentbuf->document_charset); ++	    } ++	    else ++		pushHist(hist, a_url); ++	} ++	url = inputLineHist(prompt, url, IN_URL, hist); ++	if (url != NULL) ++	    SKIP_BLANKS(url); ++    } ++#ifdef USE_M17N ++    if (url != NULL) { ++	if ((relative || *url == '#') && Currentbuf->document_charset) ++	    url = wc_conv_strict(url, InnerCharset, ++				 Currentbuf->document_charset)->ptr; ++	else ++	    url = conv_to_system(url); ++    } ++#endif ++    if (url == NULL || *url == '\0') { ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	return; ++    } ++    if (*url == '#') { ++	gotoLabel(url + 1); ++	return; ++    } ++    if (relative) { ++	current = baseURL(Currentbuf); ++	referer = parsedURL2Str(&Currentbuf->currentURL)->ptr; ++    } ++    else { ++	current = NULL; ++	referer = NULL; ++    } ++    parseURL2(url, &p_url, current); ++    pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr); ++    cmd_loadURL(url, current, referer, NULL); ++    if (Currentbuf != cur_buf)	/* success */ ++	pushHashHist(URLHist, parsedURL2Str(&Currentbuf->currentURL)->ptr); ++} ++ ++DEFUN(goURL, GOTO, "Go to URL") ++{ ++    goURL0("Goto URL: ", FALSE); ++} ++ ++DEFUN(gorURL, GOTO_RELATIVE, "Go to relative URL") ++{ ++    goURL0("Goto relative URL: ", TRUE); ++} ++ ++static void ++cmd_loadBuffer(Buffer *buf, int prop, int linkid) ++{ ++    if (buf == NULL) { ++	disp_err_message("Can't load string", FALSE); ++    } ++    else if (buf != NO_BUFFER) { ++	buf->bufferprop |= (BP_INTERNAL | prop); ++	if (!(buf->bufferprop & BP_NO_URL)) ++	    copyParsedURL(&buf->currentURL, &Currentbuf->currentURL); ++	if (linkid != LB_NOLINK) { ++	    buf->linkBuffer[REV_LB[linkid]] = Currentbuf; ++	    Currentbuf->linkBuffer[linkid] = buf; ++	} ++	pushBuffer(buf); ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* load bookmark */ ++DEFUN(ldBmark, BOOKMARK VIEW_BOOKMARK, "Read bookmark") ++{ ++    cmd_loadURL(BookmarkFile, NULL, NO_REFERER, NULL); ++} ++ ++ ++/* Add current to bookmark */ ++DEFUN(adBmark, ADD_BOOKMARK, "Add current page to bookmark") ++{ ++    Str tmp; ++    FormList *request; ++ ++    tmp = Sprintf("mode=panel&cookie=%s&bmark=%s&url=%s&title=%s" ++#ifdef USE_M17N ++		    "&charset=%s" ++#endif ++		    , ++		  (Str_form_quote(localCookie()))->ptr, ++		  (Str_form_quote(Strnew_charp(BookmarkFile)))->ptr, ++		  (Str_form_quote(parsedURL2Str(&Currentbuf->currentURL)))-> ++		  ptr, ++#ifdef USE_M17N ++		  (Str_form_quote(wc_conv_strict(Currentbuf->buffername, ++						 InnerCharset, ++						 BookmarkCharset)))->ptr, ++		  wc_ces_to_charset(BookmarkCharset)); ++#else ++		  (Str_form_quote(Strnew_charp(Currentbuf->buffername)))->ptr); ++#endif ++    request = newFormList(NULL, "post", NULL, NULL, NULL, NULL, NULL); ++    request->body = tmp->ptr; ++    request->length = tmp->length; ++    cmd_loadURL("file:///$LIB/" W3MBOOKMARK_CMDNAME, NULL, NO_REFERER, ++		request); ++} ++ ++/* option setting */ ++DEFUN(ldOpt, OPTIONS, "Option setting panel") ++{ ++    cmd_loadBuffer(load_option_panel(), BP_NO_URL, LB_NOLINK); ++} ++ ++/* set an option */ ++DEFUN(setOpt, SET_OPTION, "Set option") ++{ ++    char *opt; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    opt = searchKeyData(); ++    if (opt == NULL || *opt == '\0' || strchr(opt, '=') == NULL) { ++	if (opt != NULL && *opt != '\0') { ++	    char *v = get_param_option(opt); ++	    opt = Sprintf("%s=%s", opt, v ? v : "")->ptr; ++	} ++	opt = inputStrHist("Set option: ", opt, TextHist); ++	if (opt == NULL || *opt == '\0') { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++    } ++    if (set_param_option(opt)) ++	sync_with_option(); ++    displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++} ++ ++/* error message list */ ++DEFUN(msgs, MSGS, "Display error messages") ++{ ++    cmd_loadBuffer(message_list_panel(), BP_NO_URL, LB_NOLINK); ++} ++ ++/* page info */ ++DEFUN(pginfo, INFO, "View info of current document") ++{ ++    Buffer *buf; ++ ++    if ((buf = Currentbuf->linkBuffer[LB_N_INFO]) != NULL) { ++	Currentbuf = buf; ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    if ((buf = Currentbuf->linkBuffer[LB_INFO]) != NULL) ++	delBuffer(buf); ++    buf = page_info_panel(Currentbuf); ++    cmd_loadBuffer(buf, BP_NORMAL, LB_INFO); ++} ++ ++void ++follow_map(struct parsed_tagarg *arg) ++{ ++    char *name = tag_get_value(arg, "link"); ++#if defined(MENU_MAP) || defined(USE_IMAGE) ++    Anchor *an; ++    MapArea *a; ++    int x, y; ++    ParsedURL p_url; ++ ++    an = retrieveCurrentImg(Currentbuf); ++    x = Currentbuf->cursorX + Currentbuf->rootX; ++    y = Currentbuf->cursorY + Currentbuf->rootY; ++    a = follow_map_menu(Currentbuf, name, an, x, y); ++    if (a == NULL || a->url == NULL || *(a->url) == '\0') { ++#endif ++#ifndef MENU_MAP ++	Buffer *buf = follow_map_panel(Currentbuf, name); ++ ++	if (buf != NULL) ++	    cmd_loadBuffer(buf, BP_NORMAL, LB_NOLINK); ++#endif ++#if defined(MENU_MAP) || defined(USE_IMAGE) ++	return; ++    } ++    if (*(a->url) == '#') { ++	gotoLabel(a->url + 1); ++	return; ++    } ++    parseURL2(a->url, &p_url, baseURL(Currentbuf)); ++    pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr); ++    if (check_target && open_tab_blank && a->target && ++	(!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) { ++	Buffer *buf; ++ ++	_newT(); ++	buf = Currentbuf; ++	cmd_loadURL(a->url, baseURL(Currentbuf), ++		    parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL); ++	if (buf != Currentbuf) ++	    delBuffer(buf); ++	else ++	    deleteTab(CurrentTab); ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	return; ++    } ++    cmd_loadURL(a->url, baseURL(Currentbuf), ++		parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL); ++#endif ++} ++ ++#ifdef USE_MENU ++/* link menu */ ++DEFUN(linkMn, LINK_MENU, "Popup link element menu") ++{ ++    LinkList *l = link_menu(Currentbuf); ++    ParsedURL p_url; ++ ++    if (!l || !l->url) ++	return; ++    if (*(l->url) == '#') { ++	gotoLabel(l->url + 1); ++	return; ++    } ++    parseURL2(l->url, &p_url, baseURL(Currentbuf)); ++    pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr); ++    cmd_loadURL(l->url, baseURL(Currentbuf), ++		parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL); ++} ++ ++static void ++anchorMn(Anchor *(*menu_func) (Buffer *), int go) ++{ ++    Anchor *a; ++    BufferPoint *po; ++ ++    if (!Currentbuf->href || !Currentbuf->hmarklist) ++	return; ++    a = menu_func(Currentbuf); ++    if (!a || a->hseq < 0) ++	return; ++    po = &Currentbuf->hmarklist->marks[a->hseq]; ++    gotoLine(Currentbuf, po->line); ++    Currentbuf->pos = po->pos; ++    arrangeCursor(Currentbuf); ++    displayBuffer(Currentbuf, B_NORMAL); ++    if (go) ++	followA(); ++} ++ ++/* accesskey */ ++DEFUN(accessKey, ACCESSKEY, "Popup acceskey menu") ++{ ++    anchorMn(accesskey_menu, TRUE); ++} ++ ++/* list menu */ ++DEFUN(listMn, LIST_MENU, "Popup link list menu and go to selected link") ++{ ++    anchorMn(list_menu, TRUE); ++} ++ ++DEFUN(movlistMn, MOVE_LIST_MENU, ++      "Popup link list menu and move cursor to selected link") ++{ ++    anchorMn(list_menu, FALSE); ++} ++#endif ++ ++/* link,anchor,image list */ ++DEFUN(linkLst, LIST, "Show all links and images") ++{ ++    Buffer *buf; ++ ++    buf = link_list_panel(Currentbuf); ++    if (buf != NULL) { ++#ifdef USE_M17N ++	buf->document_charset = Currentbuf->document_charset; ++#endif ++	cmd_loadBuffer(buf, BP_NORMAL, LB_NOLINK); ++    } ++} ++ ++#ifdef USE_COOKIE ++/* cookie list */ ++DEFUN(cooLst, COOKIE, "View cookie list") ++{ ++    Buffer *buf; ++ ++    buf = cookie_list_panel(); ++    if (buf != NULL) ++	cmd_loadBuffer(buf, BP_NO_URL, LB_NOLINK); ++} ++#endif				/* USE_COOKIE */ ++ ++#ifdef USE_HISTORY ++/* History page */ ++DEFUN(ldHist, HISTORY, "View history of URL") ++{ ++    cmd_loadBuffer(historyBuffer(URLHist), BP_NO_URL, LB_NOLINK); ++} ++#endif				/* USE_HISTORY */ ++ ++/* download HREF link */ ++DEFUN(svA, SAVE_LINK, "Save link to file") ++{ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    do_download = TRUE; ++    followA(); ++    do_download = FALSE; ++} ++ ++/* download IMG link */ ++DEFUN(svI, SAVE_IMAGE, "Save image to file") ++{ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    do_download = TRUE; ++    followI(); ++    do_download = FALSE; ++} ++ ++/* save buffer */ ++DEFUN(svBuf, PRINT SAVE_SCREEN, "Save rendered document to file") ++{ ++    char *qfile = NULL, *file; ++    FILE *f; ++    int is_pipe; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    file = searchKeyData(); ++    if (file == NULL || *file == '\0') { ++	/* FIXME: gettextize? */ ++	qfile = inputLineHist("Save buffer to: ", NULL, IN_COMMAND, SaveHist); ++	if (qfile == NULL || *qfile == '\0') { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++    } ++    file = conv_to_system(qfile ? qfile : file); ++    if (*file == '|') { ++	is_pipe = TRUE; ++	f = popen(file + 1, "w"); ++    } ++    else { ++	if (qfile) { ++	    file = unescape_spaces(Strnew_charp(qfile))->ptr; ++	    file = conv_to_system(file); ++	} ++	file = expandPath(file); ++	if (checkOverWrite(file) < 0) { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++	f = fopen(file, "w"); ++	is_pipe = FALSE; ++    } ++    if (f == NULL) { ++	/* FIXME: gettextize? */ ++	char *emsg = Sprintf("Can't open %s", conv_from_system(file))->ptr; ++	disp_err_message(emsg, TRUE); ++	return; ++    } ++    saveBuffer(Currentbuf, f, TRUE); ++    if (is_pipe) ++	pclose(f); ++    else ++	fclose(f); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* save source */ ++DEFUN(svSrc, DOWNLOAD SAVE, "Save document source to file") ++{ ++    char *file; ++ ++    if (Currentbuf->sourcefile == NULL) ++	return; ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    PermitSaveToPipe = TRUE; ++    if (Currentbuf->real_scheme == SCM_LOCAL) ++	file = conv_from_system(guess_save_name(NULL, ++						Currentbuf->currentURL. ++						real_file)); ++    else ++	file = guess_save_name(Currentbuf, Currentbuf->currentURL.file); ++    doFileCopy(Currentbuf->sourcefile, file); ++    PermitSaveToPipe = FALSE; ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++static void ++_peekURL(int only_img) ++{ ++ ++    Anchor *a; ++    ParsedURL pu; ++    static Str s = NULL; ++#ifdef USE_M17N ++    static Lineprop *p = NULL; ++    Lineprop *pp; ++#endif ++    static int offset = 0, n; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    if (CurrentKey == prev_key && s != NULL) { ++	if (s->length - offset >= COLS) ++	    offset++; ++	else if (s->length <= offset)	/* bug ? */ ++	    offset = 0; ++	goto disp; ++    } ++    else { ++	offset = 0; ++    } ++    s = NULL; ++    a = (only_img ? NULL : retrieveCurrentAnchor(Currentbuf)); ++    if (a == NULL) { ++	a = (only_img ? NULL : retrieveCurrentForm(Currentbuf)); ++	if (a == NULL) { ++	    a = retrieveCurrentImg(Currentbuf); ++	    if (a == NULL) ++		return; ++	} ++	else ++	    s = Strnew_charp(form2str((FormItemList *)a->url)); ++    } ++    if (s == NULL) { ++	parseURL2(a->url, &pu, baseURL(Currentbuf)); ++	s = parsedURL2Str(&pu); ++    } ++    if (DecodeURL) ++	s = Strnew_charp(url_unquote_conv ++			 (s->ptr, Currentbuf->document_charset)); ++#ifdef USE_M17N ++    s = checkType(s, &pp, NULL); ++    p = NewAtom_N(Lineprop, s->length); ++    bcopy((void *)pp, (void *)p, s->length * sizeof(Lineprop)); ++#endif ++  disp: ++    n = searchKeyNum(); ++    if (n > 1 && s->length > (n - 1) * (COLS - 1)) ++	offset = (n - 1) * (COLS - 1); ++#ifdef USE_M17N ++    while (offset < s->length && p[offset] & PC_WCHAR2) ++	offset++; ++#endif ++    disp_message_nomouse(&s->ptr[offset], TRUE); ++} ++ ++/* peek URL */ ++DEFUN(peekURL, PEEK_LINK, "Peek link URL") ++{ ++    _peekURL(0); ++} ++ ++/* peek URL of image */ ++DEFUN(peekIMG, PEEK_IMG, "Peek image URL") ++{ ++    _peekURL(1); ++} ++ ++/* show current URL */ ++static Str ++currentURL(void) ++{ ++    if (Currentbuf->bufferprop & BP_INTERNAL) ++	return Strnew_size(0); ++    return parsedURL2Str(&Currentbuf->currentURL); ++} ++ ++DEFUN(curURL, PEEK, "Peek current URL") ++{ ++    static Str s = NULL; ++#ifdef USE_M17N ++    static Lineprop *p = NULL; ++    Lineprop *pp; ++#endif ++    static int offset = 0, n; ++ ++    if (Currentbuf->bufferprop & BP_INTERNAL) ++	return; ++    if (CurrentKey == prev_key && s != NULL) { ++	if (s->length - offset >= COLS) ++	    offset++; ++	else if (s->length <= offset)	/* bug ? */ ++	    offset = 0; ++    } ++    else { ++	offset = 0; ++	s = currentURL(); ++	if (DecodeURL) ++	    s = Strnew_charp(url_unquote_conv(s->ptr, 0)); ++#ifdef USE_M17N ++	s = checkType(s, &pp, NULL); ++	p = NewAtom_N(Lineprop, s->length); ++	bcopy((void *)pp, (void *)p, s->length * sizeof(Lineprop)); ++#endif ++    } ++    n = searchKeyNum(); ++    if (n > 1 && s->length > (n - 1) * (COLS - 1)) ++	offset = (n - 1) * (COLS - 1); ++#ifdef USE_M17N ++    while (offset < s->length && p[offset] & PC_WCHAR2) ++	offset++; ++#endif ++    disp_message_nomouse(&s->ptr[offset], TRUE); ++} ++/* view HTML source */ ++ ++DEFUN(vwSrc, SOURCE VIEW, "View HTML source") ++{ ++    Buffer *buf; ++ ++    if (Currentbuf->type == NULL || Currentbuf->bufferprop & BP_FRAME) ++	return; ++    if ((buf = Currentbuf->linkBuffer[LB_SOURCE]) != NULL || ++	(buf = Currentbuf->linkBuffer[LB_N_SOURCE]) != NULL) { ++	Currentbuf = buf; ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    if (Currentbuf->sourcefile == NULL) { ++	if (Currentbuf->pagerSource && ++	    !strcasecmp(Currentbuf->type, "text/plain")) { ++#ifdef USE_M17N ++	    wc_ces old_charset; ++	    wc_bool old_fix_width_conv; ++#endif ++	    FILE *f; ++	    Str tmpf = tmpfname(TMPF_SRC, NULL); ++	    f = fopen(tmpf->ptr, "w"); ++	    if (f == NULL) ++		return; ++#ifdef USE_M17N ++	    old_charset = DisplayCharset; ++	    old_fix_width_conv = WcOption.fix_width_conv; ++	    DisplayCharset = (Currentbuf->document_charset != WC_CES_US_ASCII) ++		? Currentbuf->document_charset : 0; ++	    WcOption.fix_width_conv = WC_FALSE; ++#endif ++	    saveBufferBody(Currentbuf, f, TRUE); ++#ifdef USE_M17N ++	    DisplayCharset = old_charset; ++	    WcOption.fix_width_conv = old_fix_width_conv; ++#endif ++	    fclose(f); ++	    Currentbuf->sourcefile = tmpf->ptr; ++	} ++	else { ++	    return; ++	} ++    } ++ ++    buf = newBuffer(INIT_BUFFER_WIDTH); ++ ++    if (!strcasecmp(Currentbuf->type, "text/html")) { ++	buf->type = "text/plain"; ++	if (Currentbuf->real_type && ++	    !strcasecmp(Currentbuf->real_type, "text/html")) ++	    buf->real_type = "text/plain"; ++	else ++	    buf->real_type = Currentbuf->real_type; ++	buf->buffername = Sprintf("source of %s", Currentbuf->buffername)->ptr; ++	buf->linkBuffer[LB_N_SOURCE] = Currentbuf; ++	Currentbuf->linkBuffer[LB_SOURCE] = buf; ++    } ++    else if (!strcasecmp(Currentbuf->type, "text/plain")) { ++	buf->type = "text/html"; ++	if (Currentbuf->real_type && ++	    !strcasecmp(Currentbuf->real_type, "text/plain")) ++	    buf->real_type = "text/html"; ++	else ++	    buf->real_type = Currentbuf->real_type; ++	buf->buffername = Sprintf("HTML view of %s", ++				  Currentbuf->buffername)->ptr; ++	buf->linkBuffer[LB_SOURCE] = Currentbuf; ++	Currentbuf->linkBuffer[LB_N_SOURCE] = buf; ++    } ++    else { ++	return; ++    } ++    buf->currentURL = Currentbuf->currentURL; ++    buf->real_scheme = Currentbuf->real_scheme; ++    buf->filename = Currentbuf->filename; ++    buf->sourcefile = Currentbuf->sourcefile; ++    buf->header_source = Currentbuf->header_source; ++    buf->search_header = Currentbuf->search_header; ++#ifdef USE_M17N ++    buf->document_charset = Currentbuf->document_charset; ++#endif ++    buf->clone = Currentbuf->clone; ++    (*buf->clone)++; ++ ++    buf->need_reshape = TRUE; ++    reshapeBuffer(buf); ++    pushBuffer(buf); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++/* reload */ ++DEFUN(reload, RELOAD, "Reload buffer") ++{ ++    Buffer *buf, *fbuf = NULL, sbuf; ++#ifdef USE_M17N ++    wc_ces old_charset; ++#endif ++    Str url; ++    FormList *request; ++    int multipart; ++ ++    if (Currentbuf->bufferprop & BP_INTERNAL) { ++	if (!strcmp(Currentbuf->buffername, DOWNLOAD_LIST_TITLE)) { ++	    ldDL(); ++	    return; ++	} ++	/* FIXME: gettextize? */ ++	disp_err_message("Can't reload...", TRUE); ++	return; ++    } ++    if (Currentbuf->currentURL.scheme == SCM_LOCAL && ++	!strcmp(Currentbuf->currentURL.file, "-")) { ++	/* file is std input */ ++	/* FIXME: gettextize? */ ++	disp_err_message("Can't reload stdin", TRUE); ++	return; ++    } ++    copyBuffer(&sbuf, Currentbuf); ++    if (Currentbuf->bufferprop & BP_FRAME && ++	(fbuf = Currentbuf->linkBuffer[LB_N_FRAME])) { ++	if (fmInitialized) { ++	    message("Rendering frame", 0, 0); ++	    refresh(); ++	} ++	if (!(buf = renderFrame(fbuf, 1))) { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++	if (fbuf->linkBuffer[LB_FRAME]) { ++	    if (buf->sourcefile && ++		fbuf->linkBuffer[LB_FRAME]->sourcefile && ++		!strcmp(buf->sourcefile, ++			fbuf->linkBuffer[LB_FRAME]->sourcefile)) ++		fbuf->linkBuffer[LB_FRAME]->sourcefile = NULL; ++	    delBuffer(fbuf->linkBuffer[LB_FRAME]); ++	} ++	fbuf->linkBuffer[LB_FRAME] = buf; ++	buf->linkBuffer[LB_N_FRAME] = fbuf; ++	pushBuffer(buf); ++	Currentbuf = buf; ++	if (Currentbuf->firstLine) { ++	    COPY_BUFROOT(Currentbuf, &sbuf); ++	    restorePosition(Currentbuf, &sbuf); ++	} ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	return; ++    } ++    else if (Currentbuf->frameset != NULL) ++	fbuf = Currentbuf->linkBuffer[LB_FRAME]; ++    multipart = 0; ++    if (Currentbuf->form_submit) { ++	request = Currentbuf->form_submit->parent; ++	if (request->method == FORM_METHOD_POST ++	    && request->enctype == FORM_ENCTYPE_MULTIPART) { ++	    Str query; ++	    struct stat st; ++	    multipart = 1; ++	    query_from_followform(&query, Currentbuf->form_submit, multipart); ++	    stat(request->body, &st); ++	    request->length = st.st_size; ++	} ++    } ++    else { ++	request = NULL; ++    } ++    url = parsedURL2Str(&Currentbuf->currentURL); ++    /* FIXME: gettextize? */ ++    message("Reloading...", 0, 0); ++    refresh(); ++#ifdef USE_M17N ++    old_charset = DocumentCharset; ++    if (Currentbuf->document_charset != WC_CES_US_ASCII) ++	DocumentCharset = Currentbuf->document_charset; ++#endif ++    SearchHeader = Currentbuf->search_header; ++    DefaultType = Currentbuf->real_type; ++    buf = loadGeneralFile(url->ptr, NULL, NO_REFERER, RG_NOCACHE, request); ++#ifdef USE_M17N ++    DocumentCharset = old_charset; ++#endif ++    SearchHeader = FALSE; ++    DefaultType = NULL; ++ ++    if (multipart) ++	unlink(request->body); ++    if (buf == NULL) { ++	/* FIXME: gettextize? */ ++	disp_err_message("Can't reload...", TRUE); ++	return; ++    } ++    else if (buf == NO_BUFFER) { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    if (fbuf != NULL) ++	Firstbuf = deleteBuffer(Firstbuf, fbuf); ++    repBuffer(Currentbuf, buf); ++    if ((buf->type != NULL) && (sbuf.type != NULL) && ++	((!strcasecmp(buf->type, "text/plain") && ++	  !strcasecmp(sbuf.type, "text/html")) || ++	 (!strcasecmp(buf->type, "text/html") && ++	  !strcasecmp(sbuf.type, "text/plain")))) { ++	vwSrc(); ++	if (Currentbuf != buf) ++	    Firstbuf = deleteBuffer(Firstbuf, buf); ++    } ++    Currentbuf->search_header = sbuf.search_header; ++    Currentbuf->form_submit = sbuf.form_submit; ++    if (Currentbuf->firstLine) { ++	COPY_BUFROOT(Currentbuf, &sbuf); ++	restorePosition(Currentbuf, &sbuf); ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* reshape */ ++DEFUN(reshape, RESHAPE, "Re-render buffer") ++{ ++    Currentbuf->need_reshape = TRUE; ++    reshapeBuffer(Currentbuf); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++#ifdef USE_M17N ++static void ++_docCSet(wc_ces charset) ++{ ++    if (Currentbuf->bufferprop & BP_INTERNAL) ++	return; ++    if (Currentbuf->sourcefile == NULL) { ++	disp_message("Can't reload...", FALSE); ++	return; ++    } ++    Currentbuf->document_charset = charset; ++    Currentbuf->need_reshape = TRUE; ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++void ++change_charset(struct parsed_tagarg *arg) ++{ ++    Buffer *buf = Currentbuf->linkBuffer[LB_N_INFO]; ++    wc_ces charset; ++ ++    if (buf == NULL) ++	return; ++    delBuffer(Currentbuf); ++    Currentbuf = buf; ++    if (Currentbuf->bufferprop & BP_INTERNAL) ++	return; ++    charset = Currentbuf->document_charset; ++    for (; arg; arg = arg->next) { ++	if (!strcmp(arg->arg, "charset")) ++	    charset = atoi(arg->value); ++    } ++    _docCSet(charset); ++} ++ ++DEFUN(docCSet, CHARSET, "Change the current document charset") ++{ ++    char *cs; ++    wc_ces charset; ++ ++    cs = searchKeyData(); ++    if (cs == NULL || *cs == '\0') ++	/* FIXME: gettextize? */ ++	cs = inputStr("Document charset: ", ++		      wc_ces_to_charset(Currentbuf->document_charset)); ++    charset = wc_guess_charset_short(cs, 0); ++    if (charset == 0) { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    _docCSet(charset); ++} ++ ++DEFUN(defCSet, DEFAULT_CHARSET, "Change the default document charset") ++{ ++    char *cs; ++    wc_ces charset; ++ ++    cs = searchKeyData(); ++    if (cs == NULL || *cs == '\0') ++	/* FIXME: gettextize? */ ++	cs = inputStr("Default document charset: ", ++		      wc_ces_to_charset(DocumentCharset)); ++    charset = wc_guess_charset_short(cs, 0); ++    if (charset != 0) ++	DocumentCharset = charset; ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++#endif ++ ++/* mark URL-like patterns as anchors */ ++void ++chkURLBuffer(Buffer *buf) ++{ ++    static char *url_like_pat[] = { ++	"https?://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$;]*[a-zA-Z0-9_/=\\-]", ++	"file:/[a-zA-Z0-9:%\\-\\./=_\\+@#,\\$;]*", ++#ifdef USE_GOPHER ++	"gopher://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./_]*", ++#endif				/* USE_GOPHER */ ++	"ftp://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./=_+@#,\\$]*[a-zA-Z0-9_/]", ++#ifdef USE_NNTP ++	"news:[^<> 	][^<> 	]*", ++	"nntp://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./_]*", ++#endif				/* USE_NNTP */ ++#ifndef USE_W3MMAILER		/* see also chkExternalURIBuffer() */ ++	"mailto:[^<> 	][^<> 	]*@[a-zA-Z0-9][a-zA-Z0-9\\-\\._]*[a-zA-Z0-9]", ++#endif ++#ifdef INET6 ++	"https?://[a-zA-Z0-9:%\\-\\./_@]*\\[[a-fA-F0-9:][a-fA-F0-9:\\.]*\\][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$;]*", ++	"ftp://[a-zA-Z0-9:%\\-\\./_@]*\\[[a-fA-F0-9:][a-fA-F0-9:\\.]*\\][a-zA-Z0-9:%\\-\\./=_+@#,\\$]*", ++#endif				/* INET6 */ ++	NULL ++    }; ++    int i; ++    for (i = 0; url_like_pat[i]; i++) { ++	reAnchor(buf, url_like_pat[i]); ++    } ++#ifdef USE_EXTERNAL_URI_LOADER ++    chkExternalURIBuffer(buf); ++#endif ++    buf->check_url |= CHK_URL; ++} ++ ++DEFUN(chkURL, MARK_URL, "Mark URL-like strings as anchors") ++{ ++    chkURLBuffer(Currentbuf); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(chkWORD, MARK_WORD, "Mark current word as anchor") ++{ ++    char *p; ++    int spos, epos; ++    p = getCurWord(Currentbuf, &spos, &epos, ":\"\'`<>()[]{}&|;*?$"); ++    if (p == NULL) ++	return; ++    reAnchorWord(Currentbuf, Currentbuf->currentLine, spos, epos); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++#ifdef USE_NNTP ++/* mark Message-ID-like patterns as NEWS anchors */ ++void ++chkNMIDBuffer(Buffer *buf) ++{ ++    static char *url_like_pat[] = { ++	"<[!-;=?-~]+@[a-zA-Z0-9\\.\\-_]+>", ++	NULL, ++    }; ++    int i; ++    for (i = 0; url_like_pat[i]; i++) { ++	reAnchorNews(buf, url_like_pat[i]); ++    } ++    buf->check_url |= CHK_NMID; ++} ++ ++DEFUN(chkNMID, MARK_MID, "Mark Message-ID-like strings as anchors") ++{ ++    chkNMIDBuffer(Currentbuf); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++#endif				/* USE_NNTP */ ++ ++/* render frame */ ++DEFUN(rFrame, FRAME, "Render frame") ++{ ++    Buffer *buf; ++ ++    if ((buf = Currentbuf->linkBuffer[LB_FRAME]) != NULL) { ++	Currentbuf = buf; ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    if (Currentbuf->frameset == NULL) { ++	if ((buf = Currentbuf->linkBuffer[LB_N_FRAME]) != NULL) { ++	    Currentbuf = buf; ++	    displayBuffer(Currentbuf, B_NORMAL); ++	} ++	return; ++    } ++    if (fmInitialized) { ++	message("Rendering frame", 0, 0); ++	refresh(); ++    } ++    buf = renderFrame(Currentbuf, 0); ++    if (buf == NULL) { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    buf->linkBuffer[LB_N_FRAME] = Currentbuf; ++    Currentbuf->linkBuffer[LB_FRAME] = buf; ++    pushBuffer(buf); ++    if (fmInitialized && display_ok) ++	displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++/* spawn external browser */ ++static void ++invoke_browser(char *url) ++{ ++    Str cmd; ++    char *browser = NULL; ++    int bg = 0, len; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    browser = searchKeyData(); ++    if (browser == NULL || *browser == '\0') { ++	switch (prec_num) { ++	case 0: ++	case 1: ++	    browser = ExtBrowser; ++	    break; ++	case 2: ++	    browser = ExtBrowser2; ++	    break; ++	case 3: ++	    browser = ExtBrowser3; ++	    break; ++	} ++	if (browser == NULL || *browser == '\0') { ++	    browser = inputStr("Browse command: ", NULL); ++	    if (browser != NULL) ++		browser = conv_to_system(browser); ++	} ++    } ++    else { ++	browser = conv_to_system(browser); ++    } ++    if (browser == NULL || *browser == '\0') { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++ ++    if ((len = strlen(browser)) >= 2 && browser[len - 1] == '&' && ++	browser[len - 2] != '\\') { ++	browser = allocStr(browser, len - 2); ++	bg = 1; ++    } ++    cmd = myExtCommand(browser, shell_quote(url), FALSE); ++    Strremovetrailingspaces(cmd); ++    fmTerm(); ++    mySystem(cmd->ptr, bg); ++    fmInit(); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(extbrz, EXTERN, "Execute external browser") ++{ ++    if (Currentbuf->bufferprop & BP_INTERNAL) { ++	/* FIXME: gettextize? */ ++	disp_err_message("Can't browse...", TRUE); ++	return; ++    } ++    if (Currentbuf->currentURL.scheme == SCM_LOCAL && ++	!strcmp(Currentbuf->currentURL.file, "-")) { ++	/* file is std input */ ++	/* FIXME: gettextize? */ ++	disp_err_message("Can't browse stdin", TRUE); ++	return; ++    } ++    invoke_browser(parsedURL2Str(&Currentbuf->currentURL)->ptr); ++} ++ ++DEFUN(linkbrz, EXTERN_LINK, "View current link using external browser") ++{ ++    Anchor *a; ++    ParsedURL pu; ++ ++    if (Currentbuf->firstLine == NULL) ++	return; ++    a = retrieveCurrentAnchor(Currentbuf); ++    if (a == NULL) ++	return; ++    parseURL2(a->url, &pu, baseURL(Currentbuf)); ++    invoke_browser(parsedURL2Str(&pu)->ptr); ++} ++ ++/* show current line number and number of lines in the entire document */ ++DEFUN(curlno, LINE_INFO, "Show current line number") ++{ ++    Line *l = Currentbuf->currentLine; ++    Str tmp; ++    int cur = 0, all = 0, col = 0, len = 0; ++ ++    if (l != NULL) { ++	cur = l->real_linenumber; ++	col = l->bwidth + Currentbuf->currentColumn + Currentbuf->cursorX + 1; ++	while (l->next && l->next->bpos) ++	    l = l->next; ++	if (l->width < 0) ++	    l->width = COLPOS(l, l->len); ++	len = l->bwidth + l->width; ++    } ++    if (Currentbuf->lastLine) ++	all = Currentbuf->lastLine->real_linenumber; ++    if (Currentbuf->pagerSource && !(Currentbuf->bufferprop & BP_CLOSE)) ++	tmp = Sprintf("line %d col %d/%d", cur, col, len); ++    else ++	tmp = Sprintf("line %d/%d (%d%%) col %d/%d", cur, all, ++		      (int)((double)cur * 100.0 / (double)(all ? all : 1) ++			    + 0.5), col, len); ++#ifdef USE_M17N ++    Strcat_charp(tmp, "  "); ++    Strcat_charp(tmp, wc_ces_to_charset_desc(Currentbuf->document_charset)); ++#endif ++ ++    disp_message(tmp->ptr, FALSE); ++} ++ ++#ifdef USE_IMAGE ++DEFUN(dispI, DISPLAY_IMAGE, "Restart loading and drawing of images") ++{ ++    if (!displayImage) ++	initImage(); ++    if (!activeImage) ++	return; ++    displayImage = TRUE; ++    /* ++     * if (!(Currentbuf->type && !strcmp(Currentbuf->type, "text/html"))) ++     * return; ++     */ ++    Currentbuf->image_flag = IMG_FLAG_AUTO; ++    Currentbuf->need_reshape = TRUE; ++    displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++} ++ ++DEFUN(stopI, STOP_IMAGE, "Stop loading and drawing of images") ++{ ++    if (!activeImage) ++	return; ++    /* ++     * if (!(Currentbuf->type && !strcmp(Currentbuf->type, "text/html"))) ++     * return; ++     */ ++    Currentbuf->image_flag = IMG_FLAG_SKIP; ++    displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++} ++#endif ++ ++#ifdef USE_MOUSE ++ ++static int ++mouse_scroll_line(void) ++{ ++    if (relative_wheel_scroll) ++	return (relative_wheel_scroll_ratio * LASTLINE + 99) / 100; ++    else ++	return fixed_wheel_scroll_count; ++} ++ ++static TabBuffer * ++posTab(int x, int y) ++{ ++    TabBuffer *tab; ++ ++    if (mouse_action.menu_str && x < mouse_action.menu_width && y == 0) ++	return NO_TABBUFFER; ++    if (y > LastTab->y) ++	return NULL; ++    for (tab = FirstTab; tab; tab = tab->nextTab) { ++	if (tab->x1 <= x && x <= tab->x2 && tab->y == y) ++	    return tab; ++    } ++    return NULL; ++} ++ ++static void ++do_mouse_action(int btn, int x, int y) ++{ ++    MouseActionMap *map = NULL; ++    int ny = -1; ++ ++    if (nTab > 1 || mouse_action.menu_str) ++	ny = LastTab->y + 1; ++ ++    switch (btn) { ++    case MOUSE_BTN1_DOWN: ++	btn = 0; ++	break; ++    case MOUSE_BTN2_DOWN: ++	btn = 1; ++	break; ++    case MOUSE_BTN3_DOWN: ++	btn = 2; ++	break; ++    default: ++	return; ++    } ++    if (y < ny) { ++	if (mouse_action.menu_str && x >= 0 && x < mouse_action.menu_width) { ++	    if (mouse_action.menu_map[btn]) ++		map = &mouse_action.menu_map[btn][x]; ++	} ++	else ++	    map = &mouse_action.tab_map[btn]; ++    } ++    else if (y == LASTLINE) { ++	if (mouse_action.lastline_str && x >= 0 && ++	    x < mouse_action.lastline_width) { ++	    if (mouse_action.lastline_map[btn]) ++		map = &mouse_action.lastline_map[btn][x]; ++	} ++    } ++    else if (y > ny) { ++	if (y == Currentbuf->cursorY + Currentbuf->rootY && ++	    (x == Currentbuf->cursorX + Currentbuf->rootX ++#ifdef USE_M17N ++	     || (WcOption.use_wide && Currentbuf->currentLine != NULL && ++		 (CharType(Currentbuf->currentLine->propBuf[Currentbuf->pos]) ++		  == PC_KANJI1) ++		 && x == Currentbuf->cursorX + Currentbuf->rootX + 1) ++#endif ++	    )) { ++	    if (retrieveCurrentAnchor(Currentbuf) || ++		retrieveCurrentForm(Currentbuf)) { ++		map = &mouse_action.active_map[btn]; ++		if (!(map && map->func)) ++		    map = &mouse_action.anchor_map[btn]; ++	    } ++	} ++	else { ++	    int cx = Currentbuf->cursorX, cy = Currentbuf->cursorY; ++	    cursorXY(Currentbuf, x - Currentbuf->rootX, y - Currentbuf->rootY); ++	    if (y == Currentbuf->cursorY + Currentbuf->rootY && ++		(x == Currentbuf->cursorX + Currentbuf->rootX ++#ifdef USE_M17N ++		 || (WcOption.use_wide && Currentbuf->currentLine != NULL && ++		     (CharType(Currentbuf->currentLine-> ++			       propBuf[Currentbuf->pos]) == PC_KANJI1) ++		     && x == Currentbuf->cursorX + Currentbuf->rootX + 1) ++#endif ++		) && ++		(retrieveCurrentAnchor(Currentbuf) || ++		 retrieveCurrentForm(Currentbuf))) ++		map = &mouse_action.anchor_map[btn]; ++	    cursorXY(Currentbuf, cx, cy); ++	} ++    } ++    else { ++	return; ++    } ++    if (!(map && map->func)) ++	map = &mouse_action.default_map[btn]; ++    if (map && map->func) { ++	mouse_action.in_action = TRUE; ++	mouse_action.cursorX = x; ++	mouse_action.cursorY = y; ++	CurrentKey = -1; ++	CurrentKeyData = NULL; ++	CurrentCmdData = map->data; ++	(*map->func) (); ++	CurrentCmdData = NULL; ++    } ++} ++ ++static void ++process_mouse(int btn, int x, int y) ++{ ++    int delta_x, delta_y, i; ++    static int press_btn = MOUSE_BTN_RESET, press_x, press_y; ++    TabBuffer *t; ++    int ny = -1; ++ ++    if (nTab > 1 || mouse_action.menu_str) ++	ny = LastTab->y + 1; ++    if (btn == MOUSE_BTN_UP) { ++	switch (press_btn) { ++	case MOUSE_BTN1_DOWN: ++	    if (press_y == y && press_x == x) ++		do_mouse_action(press_btn, x, y); ++	    else if (ny > 0 && y < ny) { ++		if (press_y < ny) { ++		    moveTab(posTab(press_x, press_y), posTab(x, y), ++			    (press_y == y) ? (press_x < x) : (press_y < y)); ++		    return; ++		} ++		else if (press_x >= Currentbuf->rootX) { ++		    Buffer *buf = Currentbuf; ++		    int cx = Currentbuf->cursorX, cy = Currentbuf->cursorY; ++ ++		    t = posTab(x, y); ++		    if (t == NULL) ++			return; ++		    if (t == NO_TABBUFFER) ++			t = NULL;	/* open new tab */ ++		    cursorXY(Currentbuf, press_x - Currentbuf->rootX, ++			     press_y - Currentbuf->rootY); ++		    if (Currentbuf->cursorY == press_y - Currentbuf->rootY && ++			(Currentbuf->cursorX == press_x - Currentbuf->rootX ++#ifdef USE_M17N ++			 || (WcOption.use_wide && ++			     Currentbuf->currentLine != NULL && ++			     (CharType(Currentbuf->currentLine-> ++				       propBuf[Currentbuf->pos]) == PC_KANJI1) ++			     && Currentbuf->cursorX == press_x ++			     - Currentbuf->rootX - 1) ++#endif ++			)) { ++			displayBuffer(Currentbuf, B_NORMAL); ++			followTab(t); ++		    } ++		    if (buf == Currentbuf) ++			cursorXY(Currentbuf, cx, cy); ++		} ++		return; ++	    } ++	    else { ++		delta_x = x - press_x; ++		delta_y = y - press_y; ++ ++		if (abs(delta_x) < abs(delta_y) / 3) ++		    delta_x = 0; ++		if (abs(delta_y) < abs(delta_x) / 3) ++		    delta_y = 0; ++		if (reverse_mouse) { ++		    delta_y = -delta_y; ++		    delta_x = -delta_x; ++		} ++		if (delta_y > 0) { ++		    prec_num = delta_y; ++		    ldown1(); ++		} ++		else if (delta_y < 0) { ++		    prec_num = -delta_y; ++		    lup1(); ++		} ++		if (delta_x > 0) { ++		    prec_num = delta_x; ++		    col1L(); ++		} ++		else if (delta_x < 0) { ++		    prec_num = -delta_x; ++		    col1R(); ++		} ++	    } ++	    break; ++	case MOUSE_BTN2_DOWN: ++	case MOUSE_BTN3_DOWN: ++	    if (press_y == y && press_x == x) ++		do_mouse_action(press_btn, x, y); ++	    break; ++	case MOUSE_BTN4_DOWN_RXVT: ++	    for (i = 0; i < mouse_scroll_line(); i++) ++		ldown1(); ++	    break; ++	case MOUSE_BTN5_DOWN_RXVT: ++	    for (i = 0; i < mouse_scroll_line(); i++) ++		lup1(); ++	    break; ++	} ++    } ++    else if (btn == MOUSE_BTN4_DOWN_XTERM) { ++	for (i = 0; i < mouse_scroll_line(); i++) ++	    ldown1(); ++    } ++    else if (btn == MOUSE_BTN5_DOWN_XTERM) { ++	for (i = 0; i < mouse_scroll_line(); i++) ++	    lup1(); ++    } ++ ++    if (btn != MOUSE_BTN4_DOWN_RXVT || press_btn == MOUSE_BTN_RESET) { ++	press_btn = btn; ++	press_x = x; ++	press_y = y; ++    } ++    else { ++	press_btn = MOUSE_BTN_RESET; ++    } ++} ++ ++DEFUN(msToggle, MOUSE_TOGGLE, "Toggle activity of mouse") ++{ ++    if (use_mouse) { ++	use_mouse = FALSE; ++    } ++    else { ++	use_mouse = TRUE; ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(mouse, MOUSE, "mouse operation") ++{ ++    int btn, x, y; ++ ++    btn = (unsigned char)getch() - 32; ++#if defined(__CYGWIN__) && CYGWIN_VERSION_DLL_MAJOR < 1005 ++    if (cygwin_mouse_btn_swapped) { ++	if (btn == MOUSE_BTN2_DOWN) ++	    btn = MOUSE_BTN3_DOWN; ++	else if (btn == MOUSE_BTN3_DOWN) ++	    btn = MOUSE_BTN2_DOWN; ++    } ++#endif ++    x = (unsigned char)getch() - 33; ++    if (x < 0) ++	x += 0x100; ++    y = (unsigned char)getch() - 33; ++    if (y < 0) ++	y += 0x100; ++ ++    if (x < 0 || x >= COLS || y < 0 || y > LASTLINE) ++	return; ++    process_mouse(btn, x, y); ++} ++ ++#ifdef USE_GPM ++int ++gpm_process_mouse(Gpm_Event * event, void *data) ++{ ++    int btn = MOUSE_BTN_RESET, x, y; ++    if (event->type & GPM_UP) ++	btn = MOUSE_BTN_UP; ++    else if (event->type & GPM_DOWN) { ++	switch (event->buttons) { ++	case GPM_B_LEFT: ++	    btn = MOUSE_BTN1_DOWN; ++	    break; ++	case GPM_B_MIDDLE: ++	    btn = MOUSE_BTN2_DOWN; ++	    break; ++	case GPM_B_RIGHT: ++	    btn = MOUSE_BTN3_DOWN; ++	    break; ++	} ++    } ++    else { ++	GPM_DRAWPOINTER(event); ++	return 0; ++    } ++    x = event->x; ++    y = event->y; ++    process_mouse(btn, x - 1, y - 1); ++    return 0; ++} ++#endif				/* USE_GPM */ ++ ++#ifdef USE_SYSMOUSE ++int ++sysm_process_mouse(int x, int y, int nbs, int obs) ++{ ++    int btn; ++    int bits; ++ ++    if (obs & ~nbs) ++	btn = MOUSE_BTN_UP; ++    else if (nbs & ~obs) { ++	bits = nbs & ~obs; ++	btn = bits & 0x1 ? MOUSE_BTN1_DOWN : ++	    (bits & 0x2 ? MOUSE_BTN2_DOWN : ++	     (bits & 0x4 ? MOUSE_BTN3_DOWN : 0)); ++    } ++    else			/* nbs == obs */ ++	return 0; ++    process_mouse(btn, x, y); ++    return 0; ++} ++#endif				/* USE_SYSMOUSE */ ++ ++DEFUN(movMs, MOVE_MOUSE, "Move cursor to mouse cursor (for mouse action)") ++{ ++    if (!mouse_action.in_action) ++	return; ++    if ((nTab > 1 || mouse_action.menu_str) && ++	mouse_action.cursorY < LastTab->y + 1) ++	return; ++    else if (mouse_action.cursorX >= Currentbuf->rootX && ++	     mouse_action.cursorY < LASTLINE) { ++	cursorXY(Currentbuf, mouse_action.cursorX - Currentbuf->rootX, ++		 mouse_action.cursorY - Currentbuf->rootY); ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++#ifdef USE_MENU ++#ifdef KANJI_SYMBOLS ++#define FRAME_WIDTH 2 ++#else ++#define FRAME_WIDTH 1 ++#endif ++ ++DEFUN(menuMs, MENU_MOUSE, "Popup menu at mouse cursor (for mouse action)") ++{ ++    if (!mouse_action.in_action) ++	return; ++    if ((nTab > 1 || mouse_action.menu_str) && ++	mouse_action.cursorY < LastTab->y + 1) ++	mouse_action.cursorX -= FRAME_WIDTH + 1; ++    else if (mouse_action.cursorX >= Currentbuf->rootX && ++	     mouse_action.cursorY < LASTLINE) { ++	cursorXY(Currentbuf, mouse_action.cursorX - Currentbuf->rootX, ++		 mouse_action.cursorY - Currentbuf->rootY); ++	displayBuffer(Currentbuf, B_NORMAL); ++    } ++    mainMn(); ++} ++#endif ++ ++DEFUN(tabMs, TAB_MOUSE, "Move to tab on mouse cursor (for mouse action)") ++{ ++    TabBuffer *tab; ++ ++    if (!mouse_action.in_action) ++	return; ++    tab = posTab(mouse_action.cursorX, mouse_action.cursorY); ++    if (!tab || tab == NO_TABBUFFER) ++	return; ++    CurrentTab = tab; ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(closeTMs, CLOSE_TAB_MOUSE, ++      "Close tab on mouse cursor (for mouse action)") ++{ ++    TabBuffer *tab; ++ ++    if (!mouse_action.in_action) ++	return; ++    tab = posTab(mouse_action.cursorX, mouse_action.cursorY); ++    if (!tab || tab == NO_TABBUFFER) ++	return; ++    deleteTab(tab); ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++#endif				/* USE_MOUSE */ ++ ++DEFUN(dispVer, VERSION, "Display version of w3m") ++{ ++    disp_message(Sprintf("w3m version %s", w3m_version)->ptr, TRUE); ++} ++ ++DEFUN(wrapToggle, WRAP_TOGGLE, "Toggle wrap search mode") ++{ ++    if (WrapSearch) { ++	WrapSearch = FALSE; ++	/* FIXME: gettextize? */ ++	disp_message("Wrap search off", TRUE); ++    } ++    else { ++	WrapSearch = TRUE; ++	/* FIXME: gettextize? */ ++	disp_message("Wrap search on", TRUE); ++    } ++} ++ ++static int ++is_wordchar(int c, const char *badchars) ++{ ++    if (badchars) ++	return !(IS_SPACE(c) || strchr(badchars, c)); ++    else ++	return IS_ALPHA(c); ++} ++ ++static char * ++getCurWord(Buffer *buf, int *spos, int *epos, const char *badchars) ++{ ++    char *p; ++    Line *l = buf->currentLine; ++    int b, e; ++ ++    *spos = 0; ++    *epos = 0; ++    if (l == NULL) ++	return NULL; ++    p = l->lineBuf; ++    e = buf->pos; ++    while (e > 0 && !is_wordchar(p[e], badchars)) ++	e--; ++    if (!is_wordchar(p[e], badchars)) ++	return NULL; ++    b = e; ++    while (b > 0 && is_wordchar(p[b - 1], badchars)) ++	b--; ++    while (e < l->len && is_wordchar(p[e], badchars)) ++	e++; ++    *spos = b; ++    *epos = e; ++    return &p[b]; ++} ++ ++static char * ++GetWord(Buffer *buf) ++{ ++    int b, e; ++    char *p; ++ ++    if ((p = getCurWord(buf, &b, &e, 0)) != NULL) { ++	return Strnew_charp_n(p, e - b)->ptr; ++    } ++    return NULL; ++} ++ ++#ifdef USE_DICT ++static void ++execdict(char *word) ++{ ++    char *w, *dictcmd; ++    Buffer *buf; ++ ++    if (!UseDictCommand || word == NULL || *word == '\0') { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    w = conv_to_system(word); ++    if (*w == '\0') { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    dictcmd = Sprintf("%s?%s", DictCommand, ++		      Str_form_quote(Strnew_charp(w))->ptr)->ptr; ++    buf = loadGeneralFile(dictcmd, NULL, NO_REFERER, 0, NULL); ++    if (buf == NULL) { ++	disp_message("Execution failed", TRUE); ++	return; ++    } ++    else { ++	buf->filename = w; ++	buf->buffername = Sprintf("%s %s", DICTBUFFERNAME, word)->ptr; ++	if (buf->type == NULL) ++	    buf->type = "text/plain"; ++	pushBuffer(buf); ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(dictword, DICT_WORD, "Execute dictionary command (see README.dict)") ++{ ++    execdict(inputStr("(dictionary)!", "")); ++} ++ ++DEFUN(dictwordat, DICT_WORD_AT, ++      "Execute dictionary command for word at cursor") ++{ ++    execdict(GetWord(Currentbuf)); ++} ++#endif				/* USE_DICT */ ++ ++void ++set_buffer_environ(Buffer *buf) ++{ ++    static Buffer *prev_buf = NULL; ++    static Line *prev_line = NULL; ++    static int prev_pos = -1; ++    Line *l; ++ ++    if (buf == NULL) ++	return; ++    if (buf != prev_buf) { ++	set_environ("W3M_SOURCEFILE", buf->sourcefile); ++	set_environ("W3M_FILENAME", buf->filename); ++	set_environ("W3M_TITLE", buf->buffername); ++	set_environ("W3M_URL", parsedURL2Str(&buf->currentURL)->ptr); ++	set_environ("W3M_TYPE", buf->real_type ? buf->real_type : "unknown"); ++#ifdef USE_M17N ++	set_environ("W3M_CHARSET", wc_ces_to_charset(buf->document_charset)); ++#endif ++    } ++    l = buf->currentLine; ++    if (l && (buf != prev_buf || l != prev_line || buf->pos != prev_pos)) { ++	Anchor *a; ++	ParsedURL pu; ++	char *s = GetWord(buf); ++	set_environ("W3M_CURRENT_WORD", s ? s : ""); ++	a = retrieveCurrentAnchor(buf); ++	if (a) { ++	    parseURL2(a->url, &pu, baseURL(buf)); ++	    set_environ("W3M_CURRENT_LINK", parsedURL2Str(&pu)->ptr); ++	} ++	else ++	    set_environ("W3M_CURRENT_LINK", ""); ++	a = retrieveCurrentImg(buf); ++	if (a) { ++	    parseURL2(a->url, &pu, baseURL(buf)); ++	    set_environ("W3M_CURRENT_IMG", parsedURL2Str(&pu)->ptr); ++	} ++	else ++	    set_environ("W3M_CURRENT_IMG", ""); ++	a = retrieveCurrentForm(buf); ++	if (a) ++	    set_environ("W3M_CURRENT_FORM", form2str((FormItemList *)a->url)); ++	else ++	    set_environ("W3M_CURRENT_FORM", ""); ++	set_environ("W3M_CURRENT_LINE", Sprintf("%d", ++						l->real_linenumber)->ptr); ++	set_environ("W3M_CURRENT_COLUMN", Sprintf("%d", ++						  buf->currentColumn + ++						  buf->cursorX + 1)->ptr); ++    } ++    else if (!l) { ++	set_environ("W3M_CURRENT_WORD", ""); ++	set_environ("W3M_CURRENT_LINK", ""); ++	set_environ("W3M_CURRENT_IMG", ""); ++	set_environ("W3M_CURRENT_FORM", ""); ++	set_environ("W3M_CURRENT_LINE", "0"); ++	set_environ("W3M_CURRENT_COLUMN", "0"); ++    } ++    prev_buf = buf; ++    prev_line = l; ++    prev_pos = buf->pos; ++} ++ ++char * ++searchKeyData(void) ++{ ++    char *data = NULL; ++ ++    if (CurrentKeyData != NULL && *CurrentKeyData != '\0') ++	data = CurrentKeyData; ++    else if (CurrentCmdData != NULL && *CurrentCmdData != '\0') ++	data = CurrentCmdData; ++    else if (CurrentKey >= 0) ++	data = getKeyData(CurrentKey); ++    CurrentKeyData = NULL; ++    CurrentCmdData = NULL; ++    if (data == NULL || *data == '\0') ++	return NULL; ++    return allocStr(data, -1); ++} ++ ++static int ++searchKeyNum(void) ++{ ++    char *d; ++    int n = 1; ++ ++    d = searchKeyData(); ++    if (d != NULL) ++	n = atoi(d); ++    return n * PREC_NUM; ++} ++ ++#ifdef __EMX__ ++#ifdef USE_M17N ++static char * ++getCodePage(void) ++{ ++    unsigned long CpList[8], CpSize; ++ ++    if (!getenv("WINDOWID") && !DosQueryCp(sizeof(CpList), CpList, &CpSize)) ++	return Sprintf("CP%d", *CpList)->ptr; ++    return NULL; ++} ++#endif ++#endif ++ ++void ++deleteFiles() ++{ ++    Buffer *buf; ++    char *f; ++ ++    for (CurrentTab = FirstTab; CurrentTab; CurrentTab = CurrentTab->nextTab) { ++	while (Firstbuf && Firstbuf != NO_BUFFER) { ++	    buf = Firstbuf->nextBuffer; ++	    discardBuffer(Firstbuf); ++	    Firstbuf = buf; ++	} ++    } ++    while ((f = popText(fileToDelete)) != NULL) ++	unlink(f); ++} ++ ++void ++w3m_exit(int i) ++{ ++#ifdef USE_MIGEMO ++    init_migemo();		/* close pipe to migemo */ ++#endif ++    stopDownload(); ++    deleteFiles(); ++#ifdef USE_SSL ++    free_ssl_ctx(); ++#endif ++    disconnectFTP(); ++#ifdef USE_NNTP ++    disconnectNews(); ++#endif ++#ifdef __MINGW32_VERSION ++    WSACleanup(); ++#endif ++    exit(i); ++} ++ ++DEFUN(execCmd, COMMAND, "Execute w3m command(s)") ++{ ++    char *data, *p; ++    int cmd; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    data = searchKeyData(); ++    if (data == NULL || *data == '\0') { ++	data = inputStrHist("command [; ...]: ", "", TextHist); ++	if (data == NULL) { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++    } ++    /* data: FUNC [DATA] [; FUNC [DATA] ...] */ ++    while (*data) { ++	SKIP_BLANKS(data); ++	if (*data == ';') { ++	    data++; ++	    continue; ++	} ++	p = getWord(&data); ++	cmd = getFuncList(p); ++	if (cmd < 0) ++	    break; ++	p = getQWord(&data); ++	CurrentKey = -1; ++	CurrentKeyData = NULL; ++	CurrentCmdData = *p ? p : NULL; ++#ifdef USE_MOUSE ++	if (use_mouse) ++	    mouse_inactive(); ++#endif ++	w3mFuncList[cmd].func(); ++#ifdef USE_MOUSE ++	if (use_mouse) ++	    mouse_active(); ++#endif ++	CurrentCmdData = NULL; ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++#ifdef USE_ALARM ++static MySignalHandler ++SigAlarm(SIGNAL_ARG) ++{ ++    char *data; ++ ++    if (CurrentAlarm->sec > 0) { ++	CurrentKey = -1; ++	CurrentKeyData = NULL; ++	CurrentCmdData = data = (char *)CurrentAlarm->data; ++#ifdef USE_MOUSE ++	if (use_mouse) ++	    mouse_inactive(); ++#endif ++	w3mFuncList[CurrentAlarm->cmd].func(); ++#ifdef USE_MOUSE ++	if (use_mouse) ++	    mouse_active(); ++#endif ++	CurrentCmdData = NULL; ++	if (CurrentAlarm->status == AL_IMPLICIT_ONCE) { ++	    CurrentAlarm->sec = 0; ++	    CurrentAlarm->status = AL_UNSET; ++	} ++	if (Currentbuf->event) { ++	    if (Currentbuf->event->status != AL_UNSET) ++		CurrentAlarm = Currentbuf->event; ++	    else ++		Currentbuf->event = NULL; ++	} ++	if (!Currentbuf->event) ++	    CurrentAlarm = &DefaultAlarm; ++	if (CurrentAlarm->sec > 0) { ++	    mySignal(SIGALRM, SigAlarm); ++	    alarm(CurrentAlarm->sec); ++	} ++    } ++    SIGNAL_RETURN; ++} ++ ++ ++DEFUN(setAlarm, ALARM, "Set alarm") ++{ ++    char *data; ++    int sec = 0, cmd = -1; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    data = searchKeyData(); ++    if (data == NULL || *data == '\0') { ++	data = inputStrHist("(Alarm)sec command: ", "", TextHist); ++	if (data == NULL) { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++    } ++    if (*data != '\0') { ++	sec = atoi(getWord(&data)); ++	if (sec > 0) ++	    cmd = getFuncList(getWord(&data)); ++    } ++    if (cmd >= 0) { ++	data = getQWord(&data); ++	setAlarmEvent(&DefaultAlarm, sec, AL_EXPLICIT, cmd, data); ++	disp_message_nsec(Sprintf("%dsec %s %s", sec, w3mFuncList[cmd].id, ++				  data)->ptr, FALSE, 1, FALSE, TRUE); ++    } ++    else { ++	setAlarmEvent(&DefaultAlarm, 0, AL_UNSET, FUNCNAME_nulcmd, NULL); ++    } ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++AlarmEvent * ++setAlarmEvent(AlarmEvent * event, int sec, short status, int cmd, void *data) ++{ ++    if (event == NULL) ++	event = New(AlarmEvent); ++    event->sec = sec; ++    event->status = status; ++    event->cmd = cmd; ++    event->data = data; ++    return event; ++} ++#endif ++ ++DEFUN(reinit, REINIT, "Reload configuration files") ++{ ++    char *resource = searchKeyData(); ++ ++    if (resource == NULL) { ++	init_rc(); ++	sync_with_option(); ++#ifdef USE_COOKIE ++	initCookie(); ++#endif ++	displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++	return; ++    } ++ ++    if (!strcasecmp(resource, "CONFIG") || !strcasecmp(resource, "RC")) { ++	init_rc(); ++	sync_with_option(); ++	displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++	return; ++    } ++ ++#ifdef USE_COOKIE ++    if (!strcasecmp(resource, "COOKIE")) { ++	initCookie(); ++	return; ++    } ++#endif ++ ++    if (!strcasecmp(resource, "KEYMAP")) { ++	initKeymap(TRUE); ++	return; ++    } ++ ++    if (!strcasecmp(resource, "MAILCAP")) { ++	initMailcap(); ++	return; ++    } ++ ++#ifdef USE_MOUSE ++    if (!strcasecmp(resource, "MOUSE")) { ++	initMouseAction(); ++	displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++	return; ++    } ++#endif ++ ++#ifdef USE_MENU ++    if (!strcasecmp(resource, "MENU")) { ++	initMenu(); ++	return; ++    } ++#endif ++ ++    if (!strcasecmp(resource, "MIMETYPES")) { ++	initMimeTypes(); ++	return; ++    } ++ ++#ifdef USE_EXTERNAL_URI_LOADER ++    if (!strcasecmp(resource, "URIMETHODS")) { ++	initURIMethods(); ++	return; ++    } ++#endif ++ ++    disp_err_message(Sprintf("Don't know how to reinitialize '%s'", resource)-> ++		     ptr, FALSE); ++} ++ ++DEFUN(defKey, DEFINE_KEY, ++      "Define a binding between a key stroke and a user command") ++{ ++    char *data; ++ ++    CurrentKeyData = NULL;	/* not allowed in w3m-control: */ ++    data = searchKeyData(); ++    if (data == NULL || *data == '\0') { ++	data = inputStrHist("Key definition: ", "", TextHist); ++	if (data == NULL || *data == '\0') { ++	    displayBuffer(Currentbuf, B_NORMAL); ++	    return; ++	} ++    } ++    setKeymap(allocStr(data, -1), -1, TRUE); ++    displayBuffer(Currentbuf, B_NORMAL); ++} ++ ++TabBuffer * ++newTab(void) ++{ ++    TabBuffer *n; ++ ++    n = New(TabBuffer); ++    if (n == NULL) ++	return NULL; ++    n->nextTab = NULL; ++    n->currentBuffer = NULL; ++    n->firstBuffer = NULL; ++    return n; ++} ++ ++static void ++_newT(void) ++{ ++    TabBuffer *tag; ++    Buffer *buf; ++    int i; ++ ++    tag = newTab(); ++    if (!tag) ++	return; ++ ++    buf = newBuffer(Currentbuf->width); ++    copyBuffer(buf, Currentbuf); ++    buf->nextBuffer = NULL; ++    for (i = 0; i < MAX_LB; i++) ++	buf->linkBuffer[i] = NULL; ++    (*buf->clone)++; ++    tag->firstBuffer = tag->currentBuffer = buf; ++ ++    tag->nextTab = CurrentTab->nextTab; ++    tag->prevTab = CurrentTab; ++    if (CurrentTab->nextTab) ++	CurrentTab->nextTab->prevTab = tag; ++    else ++	LastTab = tag; ++    CurrentTab->nextTab = tag; ++    CurrentTab = tag; ++    nTab++; ++} ++ ++DEFUN(newT, NEW_TAB, "Open new tab") ++{ ++    _newT(); ++    displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++} ++ ++static TabBuffer * ++numTab(int n) ++{ ++    TabBuffer *tab; ++    int i; ++ ++    if (n == 0) ++	return CurrentTab; ++    if (n == 1) ++	return FirstTab; ++    if (nTab <= 1) ++	return NULL; ++    for (tab = FirstTab, i = 1; tab && i < n; tab = tab->nextTab, i++) ; ++    return tab; ++} ++ ++void ++calcTabPos(void) ++{ ++    TabBuffer *tab; ++#if 0 ++    int lcol = 0, rcol = 2, col; ++#else ++    int lcol = 0, rcol = 0, col; ++#endif ++    int n1, n2, na, nx, ny, ix, iy; ++ ++#ifdef USE_MOUSE ++    lcol = mouse_action.menu_str ? mouse_action.menu_width : 0; ++#endif ++ ++    if (nTab <= 0) ++	return; ++    n1 = (COLS - rcol - lcol) / TabCols; ++    if (n1 >= nTab) { ++	n2 = 1; ++	ny = 1; ++    } ++    else { ++	if (n1 < 0) ++	    n1 = 0; ++	n2 = COLS / TabCols; ++	if (n2 == 0) ++	    n2 = 1; ++	ny = (nTab - n1 - 1) / n2 + 2; ++    } ++    na = n1 + n2 * (ny - 1); ++    n1 -= (na - nTab) / ny; ++    if (n1 < 0) ++	n1 = 0; ++    na = n1 + n2 * (ny - 1); ++    tab = FirstTab; ++    for (iy = 0; iy < ny && tab; iy++) { ++	if (iy == 0) { ++	    nx = n1; ++	    col = COLS - rcol - lcol; ++	} ++	else { ++	    nx = n2 - (na - nTab + (iy - 1)) / (ny - 1); ++	    col = COLS; ++	} ++	for (ix = 0; ix < nx && tab; ix++, tab = tab->nextTab) { ++	    tab->x1 = col * ix / nx; ++	    tab->x2 = col * (ix + 1) / nx - 1; ++	    tab->y = iy; ++	    if (iy == 0) { ++		tab->x1 += lcol; ++		tab->x2 += lcol; ++	    } ++	} ++    } ++} ++ ++TabBuffer * ++deleteTab(TabBuffer * tab) ++{ ++    Buffer *buf, *next; ++ ++    if (nTab <= 1) ++	return FirstTab; ++    if (tab->prevTab) { ++	if (tab->nextTab) ++	    tab->nextTab->prevTab = tab->prevTab; ++	else ++	    LastTab = tab->prevTab; ++	tab->prevTab->nextTab = tab->nextTab; ++	if (tab == CurrentTab) ++	    CurrentTab = tab->prevTab; ++    } ++    else {			/* tab == FirstTab */ ++	tab->nextTab->prevTab = NULL; ++	FirstTab = tab->nextTab; ++	if (tab == CurrentTab) ++	    CurrentTab = tab->nextTab; ++    } ++    nTab--; ++    buf = tab->firstBuffer; ++    while (buf && buf != NO_BUFFER) { ++	next = buf->nextBuffer; ++	discardBuffer(buf); ++	buf = next; ++    } ++    return FirstTab; ++} ++ ++DEFUN(closeT, CLOSE_TAB, "Close current tab") ++{ ++    TabBuffer *tab; ++ ++    if (nTab <= 1) ++	return; ++    if (prec_num) ++	tab = numTab(PREC_NUM); ++    else ++	tab = CurrentTab; ++    if (tab) ++	deleteTab(tab); ++    displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++} ++ ++DEFUN(nextT, NEXT_TAB, "Move to next tab") ++{ ++    int i; ++ ++    if (nTab <= 1) ++	return; ++    for (i = 0; i < PREC_NUM; i++) { ++	if (CurrentTab->nextTab) ++	    CurrentTab = CurrentTab->nextTab; ++	else ++	    CurrentTab = FirstTab; ++    } ++    displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++} ++ ++DEFUN(prevT, PREV_TAB, "Move to previous tab") ++{ ++    int i; ++ ++    if (nTab <= 1) ++	return; ++    for (i = 0; i < PREC_NUM; i++) { ++	if (CurrentTab->prevTab) ++	    CurrentTab = CurrentTab->prevTab; ++	else ++	    CurrentTab = LastTab; ++    } ++    displayBuffer(Currentbuf, B_REDRAW_IMAGE); ++} ++ ++static void ++followTab(TabBuffer * tab) ++{ ++    Buffer *buf; ++    Anchor *a; ++ ++#ifdef USE_IMAGE ++    a = retrieveCurrentImg(Currentbuf); ++    if (!(a && a->image && a->image->map)) ++#endif ++	a = retrieveCurrentAnchor(Currentbuf); ++    if (a == NULL) ++	return; ++ ++    if (tab == CurrentTab) { ++	check_target = FALSE; ++	followA(); ++	check_target = TRUE; ++	return; ++    } ++    _newT(); ++    buf = Currentbuf; ++    check_target = FALSE; ++    followA(); ++    check_target = TRUE; ++    if (tab == NULL) { ++	if (buf != Currentbuf) ++	    delBuffer(buf); ++	else ++	    deleteTab(CurrentTab); ++    } ++    else if (buf != Currentbuf) { ++	/* buf <- p <- ... <- Currentbuf = c */ ++	Buffer *c, *p; ++ ++	c = Currentbuf; ++	p = prevBuffer(c, buf); ++	p->nextBuffer = NULL; ++	Firstbuf = buf; ++	deleteTab(CurrentTab); ++	CurrentTab = tab; ++	for (buf = p; buf; buf = p) { ++	    p = prevBuffer(c, buf); ++	    pushBuffer(buf); ++	} ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(tabA, TAB_LINK, "Open current link on new tab") ++{ ++    followTab(prec_num ? numTab(PREC_NUM) : NULL); ++} ++ ++static void ++tabURL0(TabBuffer * tab, char *prompt, int relative) ++{ ++    Buffer *buf; ++ ++    if (tab == CurrentTab) { ++	goURL0(prompt, relative); ++	return; ++    } ++    _newT(); ++    buf = Currentbuf; ++    goURL0(prompt, relative); ++    if (tab == NULL) { ++	if (buf != Currentbuf) ++	    delBuffer(buf); ++	else ++	    deleteTab(CurrentTab); ++    } ++    else if (buf != Currentbuf) { ++	/* buf <- p <- ... <- Currentbuf = c */ ++	Buffer *c, *p; ++ ++	c = Currentbuf; ++	p = prevBuffer(c, buf); ++	p->nextBuffer = NULL; ++	Firstbuf = buf; ++	deleteTab(CurrentTab); ++	CurrentTab = tab; ++	for (buf = p; buf; buf = p) { ++	    p = prevBuffer(c, buf); ++	    pushBuffer(buf); ++	} ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(tabURL, TAB_GOTO, "Open URL on new tab") ++{ ++    tabURL0(prec_num ? numTab(PREC_NUM) : NULL, ++	    "Goto URL on new tab: ", FALSE); ++} ++ ++DEFUN(tabrURL, TAB_GOTO_RELATIVE, "Open relative URL on new tab") ++{ ++    tabURL0(prec_num ? numTab(PREC_NUM) : NULL, ++	    "Goto relative URL on new tab: ", TRUE); ++} ++ ++static void ++moveTab(TabBuffer * t, TabBuffer * t2, int right) ++{ ++    if (t2 == NO_TABBUFFER) ++	t2 = FirstTab; ++    if (!t || !t2 || t == t2 || t == NO_TABBUFFER) ++	return; ++    if (t->prevTab) { ++	if (t->nextTab) ++	    t->nextTab->prevTab = t->prevTab; ++	else ++	    LastTab = t->prevTab; ++	t->prevTab->nextTab = t->nextTab; ++    } ++    else { ++	t->nextTab->prevTab = NULL; ++	FirstTab = t->nextTab; ++    } ++    if (right) { ++	t->nextTab = t2->nextTab; ++	t->prevTab = t2; ++	if (t2->nextTab) ++	    t2->nextTab->prevTab = t; ++	else ++	    LastTab = t; ++	t2->nextTab = t; ++    } ++    else { ++	t->prevTab = t2->prevTab; ++	t->nextTab = t2; ++	if (t2->prevTab) ++	    t2->prevTab->nextTab = t; ++	else ++	    FirstTab = t; ++	t2->prevTab = t; ++    } ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(tabR, TAB_RIGHT, "Move current tab right") ++{ ++    TabBuffer *tab; ++    int i; ++ ++    for (tab = CurrentTab, i = 0; tab && i < PREC_NUM; ++	 tab = tab->nextTab, i++) ; ++    moveTab(CurrentTab, tab ? tab : LastTab, TRUE); ++} ++ ++DEFUN(tabL, TAB_LEFT, "Move current tab left") ++{ ++    TabBuffer *tab; ++    int i; ++ ++    for (tab = CurrentTab, i = 0; tab && i < PREC_NUM; ++	 tab = tab->prevTab, i++) ; ++    moveTab(CurrentTab, tab ? tab : FirstTab, FALSE); ++} ++ ++void ++addDownloadList(pid_t pid, char *url, char *save, char *lock, clen_t size) ++{ ++    DownloadList *d; ++ ++    d = New(DownloadList); ++    d->pid = pid; ++    d->url = url; ++    if (save[0] != '/' && save[0] != '~') ++	save = Strnew_m_charp(CurrentDir, "/", save, NULL)->ptr; ++    d->save = expandPath(save); ++    d->lock = lock; ++    d->size = size; ++    d->time = time(0); ++    d->ok = FALSE; ++    d->next = NULL; ++    d->prev = LastDL; ++    if (LastDL) ++	LastDL->next = d; ++    else ++	FirstDL = d; ++    LastDL = d; ++    add_download_list = TRUE; ++} ++ ++int ++checkDownloadList(void) ++{ ++    DownloadList *d; ++    struct stat st; ++ ++    if (!FirstDL) ++	return FALSE; ++    for (d = FirstDL; d != NULL; d = d->next) { ++	if (!d->ok && !lstat(d->lock, &st)) ++	    return TRUE; ++    } ++    return FALSE; ++} ++ ++static char * ++convert_size3(clen_t size) ++{ ++    Str tmp = Strnew(); ++    int n; ++ ++    do { ++	n = size % 1000; ++	size /= 1000; ++	tmp = Sprintf(size ? ",%.3d%s" : "%d%s", n, tmp->ptr); ++    } while (size); ++    return tmp->ptr; ++} ++ ++static Buffer * ++DownloadListBuffer(void) ++{ ++    DownloadList *d; ++    Str src = NULL; ++    struct stat st; ++    time_t cur_time; ++    int duration, rate, eta; ++    size_t size; ++ ++    if (!FirstDL) ++	return NULL; ++    cur_time = time(0); ++    /* FIXME: gettextize? */ ++    src = Strnew_charp("<html><head><title>" DOWNLOAD_LIST_TITLE ++		       "</title></head>\n<body><h1 align=center>" ++		       DOWNLOAD_LIST_TITLE "</h1>\n" ++		       "<form method=internal action=download><hr>\n"); ++    for (d = LastDL; d != NULL; d = d->prev) { ++	if (lstat(d->lock, &st)) ++	    d->ok = TRUE; ++	Strcat_charp(src, "<pre>\n"); ++	Strcat(src, Sprintf("%s\n  --> %s\n  ", html_quote(d->url), ++			    html_quote(conv_from_system(d->save)))); ++	duration = cur_time - d->time; ++	if (!stat(d->save, &st)) { ++	    size = st.st_size; ++	    if (d->ok) { ++		d->size = size; ++		duration = st.st_mtime - d->time; ++	    } ++	} ++	else ++	    size = 0; ++	if (d->size) { ++	    int i, l = COLS - 6; ++	    if (size < d->size) ++		i = 1.0 * l * size / d->size; ++	    else ++		i = l; ++	    l -= i; ++	    while (i-- > 0) ++		Strcat_char(src, '#'); ++	    while (l-- > 0) ++		Strcat_char(src, '_'); ++	    Strcat_char(src, '\n'); ++	} ++	if (!d->ok && size < d->size) ++	    Strcat(src, Sprintf("  %s / %s bytes (%d%%)", ++				convert_size3(size), convert_size3(d->size), ++				(int)(100.0 * size / d->size))); ++	else ++	    Strcat(src, Sprintf("  %s bytes loaded", convert_size3(size))); ++	if (duration > 0) { ++	    rate = size / duration; ++	    Strcat(src, Sprintf("  %02d:%02d:%02d  rate %s/sec", ++				duration / (60 * 60), (duration / 60) % 60, ++				duration % 60, convert_size(rate, 1))); ++	    if (!d->ok && size < d->size && rate) { ++		eta = (d->size - size) / rate; ++		Strcat(src, Sprintf("  eta %02d:%02d:%02d", eta / (60 * 60), ++				    (eta / 60) % 60, eta % 60)); ++	    } ++	} ++	Strcat_char(src, '\n'); ++	if (d->ok) { ++	    Strcat(src, Sprintf("<input type=submit name=ok%d value=OK>", ++				d->pid)); ++	    if (size < d->size) ++		Strcat_charp(src, " Download incompleted"); ++	    else ++		Strcat_charp(src, " Download completed"); ++	} ++	else ++	    Strcat(src, Sprintf("<input type=submit name=stop%d value=STOP>", ++				d->pid)); ++	Strcat_charp(src, "\n</pre><hr>\n"); ++    } ++    Strcat_charp(src, "</form></body></html>"); ++    return loadHTMLString(src); ++} ++ ++void ++download_action(struct parsed_tagarg *arg) ++{ ++    DownloadList *d; ++    pid_t pid; ++ ++    for (; arg; arg = arg->next) { ++	if (!strncmp(arg->arg, "stop", 4)) { ++	    pid = (pid_t) atoi(&arg->arg[4]); ++#ifndef __MINGW32_VERSION ++	    kill(pid, SIGKILL); ++#endif ++	} ++	else if (!strncmp(arg->arg, "ok", 2)) ++	    pid = (pid_t) atoi(&arg->arg[2]); ++	else ++	    continue; ++	for (d = FirstDL; d; d = d->next) { ++	    if (d->pid == pid) { ++		unlink(d->lock); ++		if (d->prev) ++		    d->prev->next = d->next; ++		else ++		    FirstDL = d->next; ++		if (d->next) ++		    d->next->prev = d->prev; ++		else ++		    LastDL = d->prev; ++		break; ++	    } ++	} ++    } ++    ldDL(); ++} ++ ++void ++stopDownload(void) ++{ ++    DownloadList *d; ++ ++    if (!FirstDL) ++	return; ++    for (d = FirstDL; d != NULL; d = d->next) { ++	if (d->ok) ++	    continue; ++#ifndef __MINGW32_VERSION ++	kill(d->pid, SIGKILL); ++#endif ++	unlink(d->lock); ++    } ++} ++ ++/* download panel */ ++DEFUN(ldDL, DOWNLOAD_LIST, "Display download list panel") ++{ ++    Buffer *buf; ++    int replace = FALSE, new_tab = FALSE; ++#ifdef USE_ALARM ++    int reload; ++#endif ++ ++    if (Currentbuf->bufferprop & BP_INTERNAL && ++	!strcmp(Currentbuf->buffername, DOWNLOAD_LIST_TITLE)) ++	replace = TRUE; ++    if (!FirstDL) { ++	if (replace) { ++	    if (Currentbuf == Firstbuf && Currentbuf->nextBuffer == NULL) { ++		if (nTab > 1) ++		    deleteTab(CurrentTab); ++	    } ++	    else ++		delBuffer(Currentbuf); ++	    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++	} ++	return; ++    } ++#ifdef USE_ALARM ++    reload = checkDownloadList(); ++#endif ++    buf = DownloadListBuffer(); ++    if (!buf) { ++	displayBuffer(Currentbuf, B_NORMAL); ++	return; ++    } ++    buf->bufferprop |= (BP_INTERNAL | BP_NO_URL); ++    if (replace) { ++	COPY_BUFROOT(buf, Currentbuf); ++	restorePosition(buf, Currentbuf); ++    } ++    if (!replace && open_tab_dl_list) { ++	_newT(); ++	new_tab = TRUE; ++    } ++    pushBuffer(buf); ++    if (replace || new_tab) ++	deletePrevBuf(); ++#ifdef USE_ALARM ++    if (reload) ++	Currentbuf->event = setAlarmEvent(Currentbuf->event, 1, AL_IMPLICIT, ++					  FUNCNAME_reload, NULL); ++#endif ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++static void ++save_buffer_position(Buffer *buf) ++{ ++    BufferPos *b = buf->undo; ++ ++    if (!buf->firstLine) ++	return; ++    if (b && b->top_linenumber == TOP_LINENUMBER(buf) && ++	b->cur_linenumber == CUR_LINENUMBER(buf) && ++	b->currentColumn == buf->currentColumn && b->pos == buf->pos) ++	return; ++    b = New(BufferPos); ++    b->top_linenumber = TOP_LINENUMBER(buf); ++    b->cur_linenumber = CUR_LINENUMBER(buf); ++    b->currentColumn = buf->currentColumn; ++    b->pos = buf->pos; ++    b->bpos = buf->currentLine ? buf->currentLine->bpos : 0; ++    b->next = NULL; ++    b->prev = buf->undo; ++    if (buf->undo) ++	buf->undo->next = b; ++    buf->undo = b; ++} ++ ++static void ++resetPos(BufferPos * b) ++{ ++    Buffer buf; ++    Line top, cur; ++ ++    top.linenumber = b->top_linenumber; ++    cur.linenumber = b->cur_linenumber; ++    cur.bpos = b->bpos; ++    buf.topLine = ⊤ ++    buf.currentLine = &cur; ++    buf.pos = b->pos; ++    buf.currentColumn = b->currentColumn; ++    restorePosition(Currentbuf, &buf); ++    Currentbuf->undo = b; ++    displayBuffer(Currentbuf, B_FORCE_REDRAW); ++} ++ ++DEFUN(undoPos, UNDO, "Cancel the last cursor movement") ++{ ++    BufferPos *b = Currentbuf->undo; ++    int i; ++ ++    if (!Currentbuf->firstLine) ++	return; ++    if (!b || !b->prev) ++	return; ++    for (i = 0; i < PREC_NUM && b->prev; i++, b = b->prev) ; ++    resetPos(b); ++} ++ ++DEFUN(redoPos, REDO, "Cancel the last undo") ++{ ++    BufferPos *b = Currentbuf->undo; ++    int i; ++ ++    if (!Currentbuf->firstLine) ++	return; ++    if (!b || !b->next) ++	return; ++    for (i = 0; i < PREC_NUM && b->next; i++, b = b->next) ; ++    resetPos(b); ++} +diff -urN w3m-0.5.2.orig/rc.c w3m-0.5.2/rc.c +--- w3m-0.5.2.orig/rc.c	2007-05-24 00:06:06.000000000 +0900 ++++ w3m-0.5.2/rc.c	2010-07-18 08:13:26.000000000 +0900 +@@ -330,6 +330,13 @@ + }; + #endif +  ++static struct sel_c graphic_char_str[] = { ++    {N_S(GRAPHIC_CHAR_ASCII), N_("No")}, ++    {N_S(GRAPHIC_CHAR_CHARSET), N_("Yes, but only charset specific")}, ++    {N_S(GRAPHIC_CHAR_ALL), N_("Yes")}, ++    {0, NULL, NULL} ++}; ++ + struct param_ptr params1[] = { +     {"tabstop", P_NZINT, PI_TEXT, (void *)&Tabstop, CMT_TABSTOP, NULL}, +     {"indent_incr", P_NZINT, PI_TEXT, (void *)&IndentIncr, CMT_INDENT_INCR, +@@ -364,8 +371,8 @@ +     {"multicol", P_INT, PI_ONOFF, (void *)&multicolList, CMT_MULTICOL, NULL}, +     {"alt_entity", P_CHARINT, PI_ONOFF, (void *)&UseAltEntity, CMT_ALT_ENTITY, +      NULL}, +-    {"graphic_char", P_CHARINT, PI_ONOFF, (void *)&UseGraphicChar, +-     CMT_GRAPHIC_CHAR, NULL}, ++    {"graphic_char", P_CHARINT, PI_SEL_C, (void *)&UseGraphicChar, ++     CMT_GRAPHIC_CHAR, (void *)graphic_char_str}, +     {"fold_textarea", P_CHARINT, PI_ONOFF, (void *)&FoldTextarea, +      CMT_FOLD_TEXTAREA, NULL}, +     {"display_ins_del", P_INT, PI_SEL_C, (void *)&displayInsDel, +diff -urN w3m-0.5.2.orig/rc.c.orig w3m-0.5.2/rc.c.orig +--- w3m-0.5.2.orig/rc.c.orig	1970-01-01 09:00:00.000000000 +0900 ++++ w3m-0.5.2/rc.c.orig	2007-05-24 00:06:06.000000000 +0900 +@@ -0,0 +1,1513 @@ ++/* $Id: rc.c,v 1.106 2007/05/23 15:06:06 inu Exp $ */ ++/*  ++ * Initialization file etc. ++ */ ++#include "fm.h" ++#include "myctype.h" ++#include "proto.h" ++#include <stdio.h> ++#include <errno.h> ++#include "parsetag.h" ++#include "local.h" ++#include <stdlib.h> ++ ++struct param_ptr { ++    char *name; ++    int type; ++    int inputtype; ++    void *varptr; ++    char *comment; ++    void *select; ++}; ++ ++struct param_section { ++    char *name; ++    struct param_ptr *params; ++}; ++ ++struct rc_search_table { ++    struct param_ptr *param; ++    short uniq_pos; ++}; ++ ++static struct rc_search_table *RC_search_table; ++static int RC_table_size; ++ ++#define P_INT      0 ++#define P_SHORT    1 ++#define P_CHARINT  2 ++#define P_CHAR     3 ++#define P_STRING   4 ++#if defined(USE_SSL) && defined(USE_SSL_VERIFY) ++#define P_SSLPATH  5 ++#endif ++#ifdef USE_COLOR ++#define P_COLOR    6 ++#endif ++#ifdef USE_M17N ++#define P_CODE     7 ++#endif ++#define P_PIXELS   8 ++#define P_NZINT    9 ++#define P_SCALE    10 ++ ++/* FIXME: gettextize here */ ++#ifdef USE_M17N ++static wc_ces OptionCharset = WC_CES_US_ASCII;	/* FIXME: charset of source code */ ++static int OptionEncode = FALSE; ++#endif ++ ++#define CMT_HELPER	 N_("External Viewer Setup") ++#define CMT_TABSTOP      N_("Tab width in characters") ++#define CMT_INDENT_INCR  N_("Indent for HTML rendering") ++#define CMT_PIXEL_PER_CHAR N_("Number of pixels per character (4.0...32.0)") ++#define CMT_PIXEL_PER_LINE N_("Number of pixels per line (4.0...64.0)") ++#define CMT_PAGERLINE    N_("Number of remembered lines when used as a pager") ++#define CMT_HISTORY	 N_("Use URL history") ++#define CMT_HISTSIZE     N_("Number of remembered URL") ++#define CMT_SAVEHIST     N_("Save URL history") ++#define CMT_FRAME        N_("Render frames automatically") ++#define CMT_ARGV_IS_URL  N_("Treat argument without scheme as URL") ++#define CMT_TSELF        N_("Use _self as default target") ++#define CMT_OPEN_TAB_BLANK N_("Open link on new tab if target is _blank or _new") ++#define CMT_OPEN_TAB_DL_LIST N_("Open download list panel on new tab") ++#define CMT_DISPLINK     N_("Display link URL automatically") ++#define CMT_DECODE_URL   N_("Display decoded URL") ++#define CMT_DISPLINEINFO N_("Display current line number") ++#define CMT_DISP_IMAGE   N_("Display inline images") ++#ifdef USE_IMAGE ++#define CMT_AUTO_IMAGE   N_("Load inline images automatically") ++#define CMT_MAX_LOAD_IMAGE N_("Maximum processes for parallel image loading") ++#define CMT_EXT_IMAGE_VIEWER   N_("Use external image viewer") ++#define CMT_IMAGE_SCALE  N_("Scale of image (%)") ++#define CMT_IMGDISPLAY   N_("External command to display image") ++#define CMT_IMAGE_MAP_LIST N_("Use link list of image map") ++#endif ++#define CMT_MULTICOL     N_("Display file names in multi-column format") ++#define CMT_ALT_ENTITY   N_("Use ASCII equivalents to display entities") ++#define CMT_GRAPHIC_CHAR N_("Use graphic char for border of table and menu") ++#define CMT_FOLD_TEXTAREA N_("Fold lines in TEXTAREA") ++#define CMT_DISP_INS_DEL N_("Display INS, DEL, S and STRIKE element") ++#define CMT_COLOR        N_("Display with color") ++#define CMT_B_COLOR      N_("Color of normal character") ++#define CMT_A_COLOR      N_("Color of anchor") ++#define CMT_I_COLOR      N_("Color of image link") ++#define CMT_F_COLOR      N_("Color of form") ++#define CMT_ACTIVE_STYLE N_("Enable coloring of active link") ++#define CMT_C_COLOR	 N_("Color of currently active link") ++#define CMT_VISITED_ANCHOR N_("Use visited link color") ++#define CMT_V_COLOR	 N_("Color of visited link") ++#define CMT_BG_COLOR     N_("Color of background") ++#define CMT_MARK_COLOR   N_("Color of mark") ++#define CMT_USE_PROXY    N_("Use proxy") ++#define CMT_HTTP_PROXY   N_("URL of HTTP proxy host") ++#ifdef USE_SSL ++#define CMT_HTTPS_PROXY  N_("URL of HTTPS proxy host") ++#endif				/* USE_SSL */ ++#ifdef USE_GOPHER ++#define CMT_GOPHER_PROXY N_("URL of GOPHER proxy host") ++#endif				/* USE_GOPHER */ ++#define CMT_FTP_PROXY    N_("URL of FTP proxy host") ++#define CMT_NO_PROXY     N_("Domains to be accessed directly (no proxy)") ++#define CMT_NOPROXY_NETADDR	N_("Check noproxy by network address") ++#define CMT_NO_CACHE     N_("Disable cache") ++#ifdef USE_NNTP ++#define CMT_NNTP_SERVER  N_("News server") ++#define CMT_NNTP_MODE    N_("Mode of news server") ++#define CMT_MAX_NEWS     N_("Number of news messages") ++#endif ++#define CMT_DNS_ORDER	N_("Order of name resolution") ++#define CMT_DROOT       N_("Directory corresponding to / (document root)") ++#define CMT_PDROOT      N_("Directory corresponding to /~user") ++#define CMT_CGIBIN      N_("Directory corresponding to /cgi-bin") ++#define CMT_CONFIRM_QQ  N_("Confirm when quitting with q") ++#define CMT_CLOSE_TAB_BACK N_("Close tab if buffer is last when back") ++#ifdef USE_MARK ++#define CMT_USE_MARK	N_("Enable mark operations") ++#endif ++#define CMT_EMACS_LIKE_LINEEDIT	N_("Enable Emacs-style line editing") ++#define CMT_VI_PREC_NUM	 N_("Enable vi-like numeric prefix") ++#define CMT_LABEL_TOPLINE N_("Move cursor to top line when going to label") ++#define CMT_NEXTPAGE_TOPLINE N_("Move cursor to top line when moving to next page") ++#define CMT_FOLD_LINE    N_("Fold lines of plain text file") ++#define CMT_SHOW_NUM     N_("Show line numbers") ++#define CMT_SHOW_SRCH_STR N_("Show search string") ++#define CMT_MIMETYPES    N_("List of mime.types files") ++#define CMT_MAILCAP      N_("List of mailcap files") ++#define CMT_URIMETHODMAP N_("List of urimethodmap files") ++#define CMT_EDITOR       N_("Editor") ++#define CMT_MAILER       N_("Mailer") ++#define CMT_EXTBRZ       N_("External Browser") ++#define CMT_EXTBRZ2      N_("Second External Browser") ++#define CMT_EXTBRZ3      N_("Third External Browser") ++#define CMT_DISABLE_SECRET_SECURITY_CHECK	N_("Disable secret file security check") ++#define CMT_PASSWDFILE	 N_("Password file") ++#define CMT_PRE_FORM_FILE	N_("File for setting form on loading") ++#define CMT_FTPPASS      N_("Password for anonymous FTP (your mail address)") ++#define CMT_FTPPASS_HOSTNAMEGEN N_("Generate domain part of password for FTP") ++#define CMT_USERAGENT    N_("User-Agent identification string") ++#define CMT_ACCEPTENCODING	N_("Accept-Encoding header") ++#define CMT_ACCEPTMEDIA	 N_("Accept header") ++#define CMT_ACCEPTLANG   N_("Accept-Language header") ++#define CMT_MARK_ALL_PAGES N_("Treat URL-like strings as links in all pages") ++#define CMT_WRAP         N_("Wrap search") ++#define CMT_VIEW_UNSEENOBJECTS N_("Display unseen objects (e.g. bgimage tag)") ++#define CMT_AUTO_UNCOMPRESS	N_("Uncompress compressed data automatically when downloading") ++#ifdef __EMX__ ++#define CMT_BGEXTVIEW	 N_("Run external viewer in a separate session") ++#else ++#define CMT_BGEXTVIEW    N_("Run external viewer in the background") ++#endif ++#define CMT_EXT_DIRLIST  N_("Use external program for directory listing") ++#define CMT_DIRLIST_CMD  N_("URL of directory listing command") ++#ifdef USE_DICT ++#define CMT_USE_DICTCOMMAND  N_("Enable dictionary lookup through CGI") ++#define CMT_DICTCOMMAND  N_("URL of dictionary lookup command") ++#endif				/* USE_DICT */ ++#define CMT_IGNORE_NULL_IMG_ALT	N_("Display link name for images lacking ALT") ++#define CMT_IFILE        N_("Index file for directories") ++#define CMT_RETRY_HTTP   N_("Prepend http:// to URL automatically") ++#define CMT_DEFAULT_URL  N_("Default value for open-URL command") ++#define CMT_DECODE_CTE   N_("Decode Content-Transfer-Encoding when saving") ++#define CMT_PRESERVE_TIMESTAMP N_("Preserve timestamp when saving") ++#ifdef USE_MOUSE ++#define CMT_MOUSE         N_("Enable mouse") ++#define CMT_REVERSE_MOUSE N_("Scroll in reverse direction of mouse drag") ++#define CMT_RELATIVE_WHEEL_SCROLL N_("Behavior of wheel scroll speed") ++#define CMT_RELATIVE_WHEEL_SCROLL_RATIO N_("(A only)Scroll by # (%) of screen") ++#define CMT_FIXED_WHEEL_SCROLL_COUNT N_("(B only)Scroll by # lines") ++#endif				/* USE_MOUSE */ ++#define CMT_CLEAR_BUF     N_("Free memory of undisplayed buffers") ++#define CMT_NOSENDREFERER N_("Suppress `Referer:' header") ++#define CMT_IGNORE_CASE N_("Search case-insensitively") ++#define CMT_USE_LESSOPEN N_("Use LESSOPEN") ++#ifdef USE_SSL ++#ifdef USE_SSL_VERIFY ++#define CMT_SSL_VERIFY_SERVER N_("Perform SSL server verification") ++#define CMT_SSL_CERT_FILE N_("PEM encoded certificate file of client") ++#define CMT_SSL_KEY_FILE N_("PEM encoded private key file of client") ++#define CMT_SSL_CA_PATH N_("Path to directory for PEM encoded certificates of CAs") ++#define CMT_SSL_CA_FILE N_("File consisting of PEM encoded certificates of CAs") ++#endif				/* USE_SSL_VERIFY */ ++#define CMT_SSL_FORBID_METHOD N_("List of forbidden SSL methods (2: SSLv2, 3: SSLv3, t:TLSv1)") ++#endif				/* USE_SSL */ ++#ifdef USE_COOKIE ++#define CMT_USECOOKIE   N_("Enable cookie processing") ++#define CMT_SHOWCOOKIE  N_("Print a message when receiving a cookie") ++#define CMT_ACCEPTCOOKIE N_("Accept cookies") ++#define CMT_ACCEPTBADCOOKIE N_("Action to be taken on invalid cookie") ++#define CMT_COOKIE_REJECT_DOMAINS N_("Domains to reject cookies from") ++#define CMT_COOKIE_ACCEPT_DOMAINS N_("Domains to accept cookies from") ++#endif ++#define CMT_FOLLOW_REDIRECTION N_("Number of redirections to follow") ++#define CMT_META_REFRESH N_("Enable processing of meta-refresh tag") ++ ++#ifdef USE_MIGEMO ++#define CMT_USE_MIGEMO N_("Enable Migemo (Roma-ji search)") ++#define CMT_MIGEMO_COMMAND N_("Migemo command") ++#endif				/* USE_MIGEMO */ ++ ++#ifdef USE_M17N ++#define CMT_DISPLAY_CHARSET  N_("Display charset") ++#define CMT_DOCUMENT_CHARSET N_("Default document charset") ++#define CMT_AUTO_DETECT      N_("Automatic charset detect when loading") ++#define CMT_SYSTEM_CHARSET   N_("System charset") ++#define CMT_FOLLOW_LOCALE    N_("System charset follows locale(LC_CTYPE)") ++#define CMT_EXT_HALFDUMP     N_("Output halfdump with display charset") ++#define CMT_USE_WIDE         N_("Use multi column characters") ++#define CMT_USE_COMBINING    N_("Use combining characters") ++#define CMT_USE_LANGUAGE_TAG N_("Use Unicode language tags") ++#define CMT_UCS_CONV         N_("Charset conversion using Unicode map") ++#define CMT_PRE_CONV         N_("Charset conversion when loading") ++#define CMT_SEARCH_CONV      N_("Adjust search string for document charset") ++#define CMT_FIX_WIDTH_CONV   N_("Fix character width when conversion") ++#define CMT_USE_GB12345_MAP  N_("Use GB 12345 Unicode map instead of GB 2312's") ++#define CMT_USE_JISX0201     N_("Use JIS X 0201 Roman for ISO-2022-JP") ++#define CMT_USE_JISC6226     N_("Use JIS C 6226:1978 for ISO-2022-JP") ++#define CMT_USE_JISX0201K    N_("Use JIS X 0201 Katakana") ++#define CMT_USE_JISX0212     N_("Use JIS X 0212:1990 (Supplemental Kanji)") ++#define CMT_USE_JISX0213     N_("Use JIS X 0213:2000 (2000JIS)") ++#define CMT_STRICT_ISO2022   N_("Strict ISO-2022-JP/KR/CN") ++#define CMT_GB18030_AS_UCS   N_("Treat 4 bytes char. of GB18030 as Unicode") ++#endif ++ ++#define CMT_KEYMAP_FILE N_("keymap file") ++ ++#define PI_TEXT    0 ++#define PI_ONOFF   1 ++#define PI_SEL_C   2 ++#ifdef USE_M17N ++#define PI_CODE    3 ++#endif ++ ++struct sel_c { ++    int value; ++    char *cvalue; ++    char *text; ++}; ++ ++#ifdef USE_COLOR ++static struct sel_c colorstr[] = { ++    {0, "black", N_("black")}, ++    {1, "red", N_("red")}, ++    {2, "green", N_("green")}, ++    {3, "yellow", N_("yellow")}, ++    {4, "blue", N_("blue")}, ++    {5, "magenta", N_("magenta")}, ++    {6, "cyan", N_("cyan")}, ++    {7, "white", N_("white")}, ++    {8, "terminal", N_("terminal")}, ++    {0, NULL, NULL} ++}; ++#endif				/* USE_COLOR */ ++ ++#if 1				/* ANSI-C ? */ ++#define N_STR(x)	#x ++#define N_S(x)	(x), N_STR(x) ++#else				/* for traditional cpp? */ ++static char n_s[][2] = { ++    {'0', 0}, ++    {'1', 0}, ++    {'2', 0}, ++}; ++#define N_S(x) (x), n_s[(x)] ++#endif ++ ++ ++static struct sel_c defaulturls[] = { ++    {N_S(DEFAULT_URL_EMPTY), N_("none")}, ++    {N_S(DEFAULT_URL_CURRENT), N_("current URL")}, ++    {N_S(DEFAULT_URL_LINK), N_("link URL")}, ++    {0, NULL, NULL} ++}; ++ ++static struct sel_c displayinsdel[] = { ++    {N_S(DISPLAY_INS_DEL_SIMPLE), N_("simple")}, ++    {N_S(DISPLAY_INS_DEL_NORMAL), N_("use tag")}, ++    {N_S(DISPLAY_INS_DEL_FONTIFY), N_("fontify")}, ++    {0, NULL, NULL} ++}; ++ ++#ifdef USE_MOUSE ++static struct sel_c wheelmode[] = { ++    {TRUE, "1", N_("A:relative to screen height")}, ++    {FALSE, "0", N_("B:fixed speed")}, ++    {0, NULL, NULL} ++}; ++#endif				/* MOUSE */ ++ ++#ifdef INET6 ++static struct sel_c dnsorders[] = { ++    {N_S(DNS_ORDER_UNSPEC), N_("unspecified")}, ++    {N_S(DNS_ORDER_INET_INET6), N_("inet inet6")}, ++    {N_S(DNS_ORDER_INET6_INET), N_("inet6 inet")}, ++    {N_S(DNS_ORDER_INET_ONLY), N_("inet only")}, ++    {N_S(DNS_ORDER_INET6_ONLY), N_("inet6 only")}, ++    {0, NULL, NULL} ++}; ++#endif				/* INET6 */ ++ ++#ifdef USE_COOKIE ++static struct sel_c badcookiestr[] = { ++    {N_S(ACCEPT_BAD_COOKIE_DISCARD), N_("discard")}, ++#if 0 ++    {N_S(ACCEPT_BAD_COOKIE_ACCEPT), N_("accept")}, ++#endif ++    {N_S(ACCEPT_BAD_COOKIE_ASK), N_("ask")}, ++    {0, NULL, NULL} ++}; ++#endif				/* USE_COOKIE */ ++ ++#ifdef USE_M17N ++static wc_ces_list *display_charset_str = NULL; ++static wc_ces_list *document_charset_str = NULL; ++static wc_ces_list *system_charset_str = NULL; ++static struct sel_c auto_detect_str[] = { ++    {N_S(WC_OPT_DETECT_OFF), N_("OFF")}, ++    {N_S(WC_OPT_DETECT_ISO_2022), N_("Only ISO 2022")}, ++    {N_S(WC_OPT_DETECT_ON), N_("ON")}, ++    {0, NULL, NULL} ++}; ++#endif ++ ++struct param_ptr params1[] = { ++    {"tabstop", P_NZINT, PI_TEXT, (void *)&Tabstop, CMT_TABSTOP, NULL}, ++    {"indent_incr", P_NZINT, PI_TEXT, (void *)&IndentIncr, CMT_INDENT_INCR, ++     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 ++    {"frame", P_CHARINT, PI_ONOFF, (void *)&RenderFrame, CMT_FRAME, NULL}, ++    {"target_self", P_CHARINT, PI_ONOFF, (void *)&TargetSelf, CMT_TSELF, NULL}, ++    {"open_tab_blank", P_INT, PI_ONOFF, (void *)&open_tab_blank, ++     CMT_OPEN_TAB_BLANK, NULL}, ++    {"open_tab_dl_list", P_INT, PI_ONOFF, (void *)&open_tab_dl_list, ++     CMT_OPEN_TAB_DL_LIST, NULL}, ++    {"display_link", P_INT, PI_ONOFF, (void *)&displayLink, CMT_DISPLINK, ++     NULL}, ++    {"decode_url", P_INT, PI_ONOFF, (void *)&DecodeURL, CMT_DECODE_URL, NULL}, ++    {"display_lineinfo", P_INT, PI_ONOFF, (void *)&displayLineInfo, ++     CMT_DISPLINEINFO, NULL}, ++    {"ext_dirlist", P_INT, PI_ONOFF, (void *)&UseExternalDirBuffer, ++     CMT_EXT_DIRLIST, NULL}, ++    {"dirlist_cmd", P_STRING, PI_TEXT, (void *)&DirBufferCommand, ++     CMT_DIRLIST_CMD, NULL}, ++#ifdef USE_DICT ++    {"use_dictcommand", P_INT, PI_ONOFF, (void *)&UseDictCommand, ++     CMT_USE_DICTCOMMAND, NULL}, ++    {"dictcommand", P_STRING, PI_TEXT, (void *)&DictCommand, ++     CMT_DICTCOMMAND, NULL}, ++#endif				/* USE_DICT */ ++    {"multicol", P_INT, PI_ONOFF, (void *)&multicolList, CMT_MULTICOL, NULL}, ++    {"alt_entity", P_CHARINT, PI_ONOFF, (void *)&UseAltEntity, CMT_ALT_ENTITY, ++     NULL}, ++    {"graphic_char", P_CHARINT, PI_ONOFF, (void *)&UseGraphicChar, ++     CMT_GRAPHIC_CHAR, NULL}, ++    {"fold_textarea", P_CHARINT, PI_ONOFF, (void *)&FoldTextarea, ++     CMT_FOLD_TEXTAREA, NULL}, ++    {"display_ins_del", P_INT, PI_SEL_C, (void *)&displayInsDel, ++     CMT_DISP_INS_DEL, displayinsdel}, ++    {"ignore_null_img_alt", P_INT, PI_ONOFF, (void *)&ignore_null_img_alt, ++     CMT_IGNORE_NULL_IMG_ALT, NULL}, ++    {"view_unseenobject", P_INT, PI_ONOFF, (void *)&view_unseenobject, ++     CMT_VIEW_UNSEENOBJECTS, NULL}, ++    /* XXX: emacs-w3m force to off display_image even if image options off */ ++    {"display_image", P_INT, PI_ONOFF, (void *)&displayImage, CMT_DISP_IMAGE, ++     NULL}, ++#ifdef USE_IMAGE ++    {"auto_image", P_INT, PI_ONOFF, (void *)&autoImage, CMT_AUTO_IMAGE, NULL}, ++    {"max_load_image", P_INT, PI_TEXT, (void *)&maxLoadImage, ++     CMT_MAX_LOAD_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}, ++    {"image_map_list", P_INT, PI_ONOFF, (void *)&image_map_list, ++     CMT_IMAGE_MAP_LIST, NULL}, ++#endif ++    {"fold_line", P_INT, PI_ONOFF, (void *)&FoldLine, CMT_FOLD_LINE, NULL}, ++    {"show_lnum", P_INT, PI_ONOFF, (void *)&showLineNum, CMT_SHOW_NUM, NULL}, ++    {"show_srch_str", P_INT, PI_ONOFF, (void *)&show_srch_str, ++     CMT_SHOW_SRCH_STR, NULL}, ++    {"label_topline", P_INT, PI_ONOFF, (void *)&label_topline, ++     CMT_LABEL_TOPLINE, NULL}, ++    {"nextpage_topline", P_INT, PI_ONOFF, (void *)&nextpage_topline, ++     CMT_NEXTPAGE_TOPLINE, NULL}, ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++ ++#ifdef USE_COLOR ++struct param_ptr params2[] = { ++    {"color", P_INT, PI_ONOFF, (void *)&useColor, CMT_COLOR, NULL}, ++    {"basic_color", P_COLOR, PI_SEL_C, (void *)&basic_color, CMT_B_COLOR, ++     (void *)colorstr}, ++    {"anchor_color", P_COLOR, PI_SEL_C, (void *)&anchor_color, CMT_A_COLOR, ++     (void *)colorstr}, ++    {"image_color", P_COLOR, PI_SEL_C, (void *)&image_color, CMT_I_COLOR, ++     (void *)colorstr}, ++    {"form_color", P_COLOR, PI_SEL_C, (void *)&form_color, CMT_F_COLOR, ++     (void *)colorstr}, ++#ifdef USE_BG_COLOR ++    {"mark_color", P_COLOR, PI_SEL_C, (void *)&mark_color, CMT_MARK_COLOR, ++     (void *)colorstr}, ++    {"bg_color", P_COLOR, PI_SEL_C, (void *)&bg_color, CMT_BG_COLOR, ++     (void *)colorstr}, ++#endif				/* USE_BG_COLOR */ ++    {"active_style", P_INT, PI_ONOFF, (void *)&useActiveColor, ++     CMT_ACTIVE_STYLE, NULL}, ++    {"active_color", P_COLOR, PI_SEL_C, (void *)&active_color, CMT_C_COLOR, ++     (void *)colorstr}, ++    {"visited_anchor", P_INT, PI_ONOFF, (void *)&useVisitedColor, ++     CMT_VISITED_ANCHOR, NULL}, ++    {"visited_color", P_COLOR, PI_SEL_C, (void *)&visited_color, CMT_V_COLOR, ++     (void *)colorstr}, ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++#endif				/* USE_COLOR */ ++ ++ ++struct param_ptr params3[] = { ++    {"pagerline", P_NZINT, PI_TEXT, (void *)&PagerMax, CMT_PAGERLINE, NULL}, ++#ifdef USE_HISTORY ++    {"use_history", P_INT, PI_ONOFF, (void *)&UseHistory, CMT_HISTORY, NULL}, ++    {"history", P_INT, PI_TEXT, (void *)&URLHistSize, CMT_HISTSIZE, NULL}, ++    {"save_hist", P_INT, PI_ONOFF, (void *)&SaveURLHist, CMT_SAVEHIST, NULL}, ++#endif				/* USE_HISTORY */ ++    {"confirm_qq", P_INT, PI_ONOFF, (void *)&confirm_on_quit, CMT_CONFIRM_QQ, ++     NULL}, ++    {"close_tab_back", P_INT, PI_ONOFF, (void *)&close_tab_back, ++     CMT_CLOSE_TAB_BACK, NULL}, ++#ifdef USE_MARK ++    {"mark", P_INT, PI_ONOFF, (void *)&use_mark, CMT_USE_MARK, NULL}, ++#endif ++    {"emacs_like_lineedit", P_INT, PI_ONOFF, (void *)&emacs_like_lineedit, ++     CMT_EMACS_LIKE_LINEEDIT, NULL}, ++    {"vi_prec_num", P_INT, PI_ONOFF, (void *)&vi_prec_num, CMT_VI_PREC_NUM, ++     NULL}, ++    {"mark_all_pages", P_INT, PI_ONOFF, (void *)&MarkAllPages, ++     CMT_MARK_ALL_PAGES, NULL}, ++    {"wrap_search", P_INT, PI_ONOFF, (void *)&WrapDefault, CMT_WRAP, NULL}, ++    {"ignorecase_search", P_INT, PI_ONOFF, (void *)&IgnoreCase, ++     CMT_IGNORE_CASE, NULL}, ++#ifdef USE_MIGEMO ++    {"use_migemo", P_INT, PI_ONOFF, (void *)&use_migemo, CMT_USE_MIGEMO, ++     NULL}, ++    {"migemo_command", P_STRING, PI_TEXT, (void *)&migemo_command, ++     CMT_MIGEMO_COMMAND, NULL}, ++#endif				/* USE_MIGEMO */ ++#ifdef USE_MOUSE ++    {"use_mouse", P_INT, PI_ONOFF, (void *)&use_mouse, CMT_MOUSE, NULL}, ++    {"reverse_mouse", P_INT, PI_ONOFF, (void *)&reverse_mouse, ++     CMT_REVERSE_MOUSE, NULL}, ++    {"relative_wheel_scroll", P_INT, PI_SEL_C, (void *)&relative_wheel_scroll, ++     CMT_RELATIVE_WHEEL_SCROLL, (void *)wheelmode}, ++    {"relative_wheel_scroll_ratio", P_INT, PI_TEXT, ++     (void *)&relative_wheel_scroll_ratio, ++     CMT_RELATIVE_WHEEL_SCROLL_RATIO, NULL}, ++    {"fixed_wheel_scroll_count", P_INT, PI_TEXT, ++     (void *)&fixed_wheel_scroll_count, ++     CMT_FIXED_WHEEL_SCROLL_COUNT, NULL}, ++#endif				/* USE_MOUSE */ ++    {"clear_buffer", P_INT, PI_ONOFF, (void *)&clear_buffer, CMT_CLEAR_BUF, ++     NULL}, ++    {"decode_cte", P_CHARINT, PI_ONOFF, (void *)&DecodeCTE, CMT_DECODE_CTE, ++     NULL}, ++    {"auto_uncompress", P_CHARINT, PI_ONOFF, (void *)&AutoUncompress, ++     CMT_AUTO_UNCOMPRESS, NULL}, ++    {"preserve_timestamp", P_CHARINT, PI_ONOFF, (void *)&PreserveTimestamp, ++     CMT_PRESERVE_TIMESTAMP, NULL}, ++    {"keymap_file", P_STRING, PI_TEXT, (void *)&keymap_file, CMT_KEYMAP_FILE, ++     NULL}, ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++ ++struct param_ptr params4[] = { ++    {"use_proxy", P_CHARINT, PI_ONOFF, (void *)&use_proxy, CMT_USE_PROXY, ++     NULL}, ++    {"http_proxy", P_STRING, PI_TEXT, (void *)&HTTP_proxy, CMT_HTTP_PROXY, ++     NULL}, ++#ifdef USE_SSL ++    {"https_proxy", P_STRING, PI_TEXT, (void *)&HTTPS_proxy, CMT_HTTPS_PROXY, ++     NULL}, ++#endif				/* USE_SSL */ ++#ifdef USE_GOPHER ++    {"gopher_proxy", P_STRING, PI_TEXT, (void *)&GOPHER_proxy, ++     CMT_GOPHER_PROXY, NULL}, ++#endif				/* USE_GOPHER */ ++    {"ftp_proxy", P_STRING, PI_TEXT, (void *)&FTP_proxy, CMT_FTP_PROXY, NULL}, ++    {"no_proxy", P_STRING, PI_TEXT, (void *)&NO_proxy, CMT_NO_PROXY, NULL}, ++    {"noproxy_netaddr", P_INT, PI_ONOFF, (void *)&NOproxy_netaddr, ++     CMT_NOPROXY_NETADDR, NULL}, ++    {"no_cache", P_CHARINT, PI_ONOFF, (void *)&NoCache, CMT_NO_CACHE, NULL}, ++ ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++ ++struct param_ptr params5[] = { ++    {"document_root", P_STRING, PI_TEXT, (void *)&document_root, CMT_DROOT, ++     NULL}, ++    {"personal_document_root", P_STRING, PI_TEXT, ++     (void *)&personal_document_root, CMT_PDROOT, NULL}, ++    {"cgi_bin", P_STRING, PI_TEXT, (void *)&cgi_bin, CMT_CGIBIN, NULL}, ++    {"index_file", P_STRING, PI_TEXT, (void *)&index_file, CMT_IFILE, NULL}, ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++ ++struct param_ptr params6[] = { ++    {"mime_types", P_STRING, PI_TEXT, (void *)&mimetypes_files, CMT_MIMETYPES, ++     NULL}, ++    {"mailcap", P_STRING, PI_TEXT, (void *)&mailcap_files, CMT_MAILCAP, NULL}, ++#ifdef USE_EXTERNAL_URI_LOADER ++    {"urimethodmap", P_STRING, PI_TEXT, (void *)&urimethodmap_files, ++     CMT_URIMETHODMAP, NULL}, ++#endif ++    {"editor", P_STRING, PI_TEXT, (void *)&Editor, CMT_EDITOR, NULL}, ++    {"mailer", P_STRING, PI_TEXT, (void *)&Mailer, CMT_MAILER, NULL}, ++    {"extbrowser", P_STRING, PI_TEXT, (void *)&ExtBrowser, CMT_EXTBRZ, NULL}, ++    {"extbrowser2", P_STRING, PI_TEXT, (void *)&ExtBrowser2, CMT_EXTBRZ2, ++     NULL}, ++    {"extbrowser3", P_STRING, PI_TEXT, (void *)&ExtBrowser3, CMT_EXTBRZ3, ++     NULL}, ++    {"bgextviewer", P_INT, PI_ONOFF, (void *)&BackgroundExtViewer, ++     CMT_BGEXTVIEW, NULL}, ++    {"use_lessopen", P_INT, PI_ONOFF, (void *)&use_lessopen, CMT_USE_LESSOPEN, ++     NULL}, ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++ ++#ifdef USE_SSL ++struct param_ptr params7[] = { ++    {"ssl_forbid_method", P_STRING, PI_TEXT, (void *)&ssl_forbid_method, ++     CMT_SSL_FORBID_METHOD, NULL}, ++#ifdef USE_SSL_VERIFY ++    {"ssl_verify_server", P_INT, PI_ONOFF, (void *)&ssl_verify_server, ++     CMT_SSL_VERIFY_SERVER, NULL}, ++    {"ssl_cert_file", P_SSLPATH, PI_TEXT, (void *)&ssl_cert_file, ++     CMT_SSL_CERT_FILE, NULL}, ++    {"ssl_key_file", P_SSLPATH, PI_TEXT, (void *)&ssl_key_file, ++     CMT_SSL_KEY_FILE, NULL}, ++    {"ssl_ca_path", P_SSLPATH, PI_TEXT, (void *)&ssl_ca_path, CMT_SSL_CA_PATH, ++     NULL}, ++    {"ssl_ca_file", P_SSLPATH, PI_TEXT, (void *)&ssl_ca_file, CMT_SSL_CA_FILE, ++     NULL}, ++#endif				/* USE_SSL_VERIFY */ ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++#endif				/* USE_SSL */ ++ ++#ifdef USE_COOKIE ++struct param_ptr params8[] = { ++    {"use_cookie", P_INT, PI_ONOFF, (void *)&use_cookie, CMT_USECOOKIE, NULL}, ++    {"show_cookie", P_INT, PI_ONOFF, (void *)&show_cookie, ++     CMT_SHOWCOOKIE, NULL}, ++    {"accept_cookie", P_INT, PI_ONOFF, (void *)&accept_cookie, ++     CMT_ACCEPTCOOKIE, NULL}, ++    {"accept_bad_cookie", P_INT, PI_SEL_C, (void *)&accept_bad_cookie, ++     CMT_ACCEPTBADCOOKIE, (void *)badcookiestr}, ++    {"cookie_reject_domains", P_STRING, PI_TEXT, ++     (void *)&cookie_reject_domains, CMT_COOKIE_REJECT_DOMAINS, NULL}, ++    {"cookie_accept_domains", P_STRING, PI_TEXT, ++     (void *)&cookie_accept_domains, CMT_COOKIE_ACCEPT_DOMAINS, NULL}, ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++#endif ++ ++struct param_ptr params9[] = { ++    {"passwd_file", P_STRING, PI_TEXT, (void *)&passwd_file, CMT_PASSWDFILE, ++     NULL}, ++    {"disable_secret_security_check", P_INT, PI_ONOFF, ++     (void *)&disable_secret_security_check, CMT_DISABLE_SECRET_SECURITY_CHECK, ++     NULL}, ++    {"ftppasswd", P_STRING, PI_TEXT, (void *)&ftppasswd, CMT_FTPPASS, NULL}, ++    {"ftppass_hostnamegen", P_INT, PI_ONOFF, (void *)&ftppass_hostnamegen, ++     CMT_FTPPASS_HOSTNAMEGEN, NULL}, ++    {"pre_form_file", P_STRING, PI_TEXT, (void *)&pre_form_file, ++     CMT_PRE_FORM_FILE, NULL}, ++    {"user_agent", P_STRING, PI_TEXT, (void *)&UserAgent, CMT_USERAGENT, NULL}, ++    {"no_referer", P_INT, PI_ONOFF, (void *)&NoSendReferer, CMT_NOSENDREFERER, ++     NULL}, ++    {"accept_language", P_STRING, PI_TEXT, (void *)&AcceptLang, CMT_ACCEPTLANG, ++     NULL}, ++    {"accept_encoding", P_STRING, PI_TEXT, (void *)&AcceptEncoding, ++     CMT_ACCEPTENCODING, ++     NULL}, ++    {"accept_media", P_STRING, PI_TEXT, (void *)&AcceptMedia, CMT_ACCEPTMEDIA, ++     NULL}, ++    {"argv_is_url", P_CHARINT, PI_ONOFF, (void *)&ArgvIsURL, CMT_ARGV_IS_URL, ++     NULL}, ++    {"retry_http", P_INT, PI_ONOFF, (void *)&retryAsHttp, CMT_RETRY_HTTP, ++     NULL}, ++    {"default_url", P_INT, PI_SEL_C, (void *)&DefaultURLString, ++     CMT_DEFAULT_URL, (void *)defaulturls}, ++    {"follow_redirection", P_INT, PI_TEXT, &FollowRedirection, ++     CMT_FOLLOW_REDIRECTION, NULL}, ++    {"meta_refresh", P_CHARINT, PI_ONOFF, (void *)&MetaRefresh, ++     CMT_META_REFRESH, NULL}, ++#ifdef INET6 ++    {"dns_order", P_INT, PI_SEL_C, (void *)&DNS_order, CMT_DNS_ORDER, ++     (void *)dnsorders}, ++#endif				/* INET6 */ ++#ifdef USE_NNTP ++    {"nntpserver", P_STRING, PI_TEXT, (void *)&NNTP_server, CMT_NNTP_SERVER, ++     NULL}, ++    {"nntpmode", P_STRING, PI_TEXT, (void *)&NNTP_mode, CMT_NNTP_MODE, NULL}, ++    {"max_news", P_INT, PI_TEXT, (void *)&MaxNewsMessage, CMT_MAX_NEWS, NULL}, ++#endif ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++ ++#ifdef USE_M17N ++struct param_ptr params10[] = { ++    {"display_charset", P_CODE, PI_CODE, (void *)&DisplayCharset, ++     CMT_DISPLAY_CHARSET, (void *)&display_charset_str}, ++    {"document_charset", P_CODE, PI_CODE, (void *)&DocumentCharset, ++     CMT_DOCUMENT_CHARSET, (void *)&document_charset_str}, ++    {"auto_detect", P_CHARINT, PI_SEL_C, (void *)&WcOption.auto_detect, ++     CMT_AUTO_DETECT, (void *)auto_detect_str}, ++    {"system_charset", P_CODE, PI_CODE, (void *)&SystemCharset, ++     CMT_SYSTEM_CHARSET, (void *)&system_charset_str}, ++    {"follow_locale", P_CHARINT, PI_ONOFF, (void *)&FollowLocale, ++     CMT_FOLLOW_LOCALE, NULL}, ++    {"ext_halfdump", P_CHARINT, PI_ONOFF, (void *)&ExtHalfdump, ++     CMT_EXT_HALFDUMP, NULL}, ++    {"use_wide", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_wide, CMT_USE_WIDE, ++     NULL}, ++    {"use_combining", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_combining, ++     CMT_USE_COMBINING, NULL}, ++#ifdef USE_UNICODE ++    {"use_language_tag", P_CHARINT, PI_ONOFF, ++     (void *)&WcOption.use_language_tag, CMT_USE_LANGUAGE_TAG, NULL}, ++    {"ucs_conv", P_CHARINT, PI_ONOFF, (void *)&WcOption.ucs_conv, CMT_UCS_CONV, ++     NULL}, ++#endif ++    {"pre_conv", P_CHARINT, PI_ONOFF, (void *)&WcOption.pre_conv, CMT_PRE_CONV, ++     NULL}, ++    {"search_conv", P_CHARINT, PI_ONOFF, (void *)&SearchConv, CMT_SEARCH_CONV, ++     NULL}, ++    {"fix_width_conv", P_CHARINT, PI_ONOFF, (void *)&WcOption.fix_width_conv, ++     CMT_FIX_WIDTH_CONV, NULL}, ++#ifdef USE_UNICODE ++    {"use_gb12345_map", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_gb12345_map, ++     CMT_USE_GB12345_MAP, NULL}, ++#endif ++    {"use_jisx0201", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisx0201, ++     CMT_USE_JISX0201, NULL}, ++    {"use_jisc6226", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisc6226, ++     CMT_USE_JISC6226, NULL}, ++    {"use_jisx0201k", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisx0201k, ++     CMT_USE_JISX0201K, NULL}, ++    {"use_jisx0212", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisx0212, ++     CMT_USE_JISX0212, NULL}, ++    {"use_jisx0213", P_CHARINT, PI_ONOFF, (void *)&WcOption.use_jisx0213, ++     CMT_USE_JISX0213, NULL}, ++    {"strict_iso2022", P_CHARINT, PI_ONOFF, (void *)&WcOption.strict_iso2022, ++     CMT_STRICT_ISO2022, NULL}, ++#ifdef USE_UNICODE ++    {"gb18030_as_ucs", P_CHARINT, PI_ONOFF, (void *)&WcOption.gb18030_as_ucs, ++     CMT_GB18030_AS_UCS, NULL}, ++#endif ++    {NULL, 0, 0, NULL, NULL, NULL}, ++}; ++#endif ++ ++struct param_section sections[] = { ++    {N_("Display Settings"), params1}, ++#ifdef USE_COLOR ++    {N_("Color Settings"), params2}, ++#endif				/* USE_COLOR */ ++    {N_("Miscellaneous Settings"), params3}, ++    {N_("Directory Settings"), params5}, ++    {N_("External Program Settings"), params6}, ++    {N_("Network Settings"), params9}, ++    {N_("Proxy Settings"), params4}, ++#ifdef USE_SSL ++    {N_("SSL Settings"), params7}, ++#endif ++#ifdef USE_COOKIE ++    {N_("Cookie Settings"), params8}, ++#endif ++#ifdef USE_M17N ++    {N_("Charset Settings"), params10}, ++#endif ++    {NULL, NULL} ++}; ++ ++static Str to_str(struct param_ptr *p); ++ ++static int ++compare_table(struct rc_search_table *a, struct rc_search_table *b) ++{ ++    return strcmp(a->param->name, b->param->name); ++} ++ ++static void ++create_option_search_table() ++{ ++    int i, j, k; ++    int diff1, diff2; ++    char *p, *q; ++ ++    /* count table size */ ++    RC_table_size = 0; ++    for (j = 0; sections[j].name != NULL; j++) { ++	i = 0; ++	while (sections[j].params[i].name) { ++	    i++; ++	    RC_table_size++; ++	} ++    } ++ ++    RC_search_table = New_N(struct rc_search_table, RC_table_size); ++    k = 0; ++    for (j = 0; sections[j].name != NULL; j++) { ++	i = 0; ++	while (sections[j].params[i].name) { ++	    RC_search_table[k].param = §ions[j].params[i]; ++	    k++; ++	    i++; ++	} ++    } ++ ++    qsort(RC_search_table, RC_table_size, sizeof(struct rc_search_table), ++	  (int (*)(const void *, const void *))compare_table); ++ ++    diff1 = diff2 = 0; ++    for (i = 0; i < RC_table_size - 1; i++) { ++	p = RC_search_table[i].param->name; ++	q = RC_search_table[i + 1].param->name; ++	for (j = 0; p[j] != '\0' && q[j] != '\0' && p[j] == q[j]; j++) ; ++	diff1 = j; ++	if (diff1 > diff2) ++	    RC_search_table[i].uniq_pos = diff1 + 1; ++	else ++	    RC_search_table[i].uniq_pos = diff2 + 1; ++	diff2 = diff1; ++    } ++} ++ ++struct param_ptr * ++search_param(char *name) ++{ ++    size_t b, e, i; ++    int cmp; ++    int len = strlen(name); ++ ++    for (b = 0, e = RC_table_size - 1; b <= e;) { ++	i = (b + e) / 2; ++	cmp = strncmp(name, RC_search_table[i].param->name, len); ++ ++	if (!cmp) { ++	    if (len >= RC_search_table[i].uniq_pos) { ++		return RC_search_table[i].param; ++	    } ++	    else { ++		while ((cmp = ++			strcmp(name, RC_search_table[i].param->name)) <= 0) ++		    if (!cmp) ++			return RC_search_table[i].param; ++		    else if (i == 0) ++			return NULL; ++		    else ++			i--; ++		/* ambiguous */ ++		return NULL; ++	    } ++	} ++	else if (cmp < 0) { ++	    if (i == 0) ++		return NULL; ++	    e = i - 1; ++	} ++	else ++	    b = i + 1; ++    } ++    return NULL; ++} ++ ++/* show parameter with bad options invokation */ ++void ++show_params(FILE * fp) ++{ ++    int i, j, l; ++    char *t = NULL; ++    char *cmt; ++ ++#ifdef USE_M17N ++#ifdef ENABLE_NLS ++    OptionCharset = SystemCharset;	/* FIXME */ ++#endif ++#endif ++ ++    fputs("\nconfiguration parameters\n", fp); ++    for (j = 0; sections[j].name != NULL; j++) { ++#ifdef USE_M17N ++	if (!OptionEncode) ++	    cmt = ++		wc_conv(_(sections[j].name), OptionCharset, ++			InnerCharset)->ptr; ++	else ++#endif ++	    cmt = sections[j].name; ++	fprintf(fp, "  section[%d]: %s\n", j, conv_to_system(cmt)); ++	i = 0; ++	while (sections[j].params[i].name) { ++	    switch (sections[j].params[i].type) { ++	    case P_INT: ++	    case P_SHORT: ++	    case P_CHARINT: ++	    case P_NZINT: ++		t = (sections[j].params[i].inputtype == ++		     PI_ONOFF) ? "bool" : "number"; ++		break; ++	    case P_CHAR: ++		t = "char"; ++		break; ++	    case P_STRING: ++		t = "string"; ++		break; ++#if defined(USE_SSL) && defined(USE_SSL_VERIFY) ++	    case P_SSLPATH: ++		t = "path"; ++		break; ++#endif ++#ifdef USE_COLOR ++	    case P_COLOR: ++		t = "color"; ++		break; ++#endif ++#ifdef USE_M17N ++	    case P_CODE: ++		t = "charset"; ++		break; ++#endif ++	    case P_PIXELS: ++		t = "number"; ++		break; ++	    case P_SCALE: ++		t = "percent"; ++		break; ++	    } ++#ifdef USE_M17N ++	    if (!OptionEncode) ++		cmt = wc_conv(_(sections[j].params[i].comment), ++			      OptionCharset, InnerCharset)->ptr; ++	    else ++#endif ++		cmt = sections[j].params[i].comment; ++	    l = 30 - (strlen(sections[j].params[i].name) + strlen(t)); ++	    if (l < 0) ++		l = 1; ++	    fprintf(fp, "    -o %s=<%s>%*s%s\n", ++		    sections[j].params[i].name, t, l, " ", ++		    conv_to_system(cmt)); ++	    i++; ++	} ++    } ++} ++ ++int ++str_to_bool(char *value, int old) ++{ ++    if (value == NULL) ++	return 1; ++    switch (TOLOWER(*value)) { ++    case '0': ++    case 'f':			/* false */ ++    case 'n':			/* no */ ++    case 'u':			/* undef */ ++	return 0; ++    case 'o': ++	if (TOLOWER(value[1]) == 'f')	/* off */ ++	    return 0; ++	return 1;		/* on */ ++    case 't': ++	if (TOLOWER(value[1]) == 'o')	/* toggle */ ++	    return !old; ++	return 1;		/* true */ ++    case '!': ++    case 'r':			/* reverse */ ++    case 'x':			/* exchange */ ++	return !old; ++    } ++    return 1; ++} ++ ++#ifdef USE_COLOR ++static int ++str_to_color(char *value) ++{ ++    if (value == NULL) ++	return 8;		/* terminal */ ++    switch (TOLOWER(*value)) { ++    case '0': ++	return 0;		/* black */ ++    case '1': ++    case 'r': ++	return 1;		/* red */ ++    case '2': ++    case 'g': ++	return 2;		/* green */ ++    case '3': ++    case 'y': ++	return 3;		/* yellow */ ++    case '4': ++	return 4;		/* blue */ ++    case '5': ++    case 'm': ++	return 5;		/* magenta */ ++    case '6': ++    case 'c': ++	return 6;		/* cyan */ ++    case '7': ++    case 'w': ++	return 7;		/* white */ ++    case '8': ++    case 't': ++	return 8;		/* terminal */ ++    case 'b': ++	if (!strncasecmp(value, "blu", 3)) ++	    return 4;		/* blue */ ++	else ++	    return 0;		/* black */ ++    } ++    return 8;			/* terminal */ ++} ++#endif ++ ++static int ++set_param(char *name, char *value) ++{ ++    struct param_ptr *p; ++    double ppc; ++ ++    if (value == NULL) ++	return 0; ++    p = search_param(name); ++    if (p == NULL) ++	return 0; ++    switch (p->type) { ++    case P_INT: ++	if (atoi(value) >= 0) ++	    *(int *)p->varptr = (p->inputtype == PI_ONOFF) ++		? str_to_bool(value, *(int *)p->varptr) : atoi(value); ++	break; ++    case P_NZINT: ++	if (atoi(value) > 0) ++	    *(int *)p->varptr = atoi(value); ++	break; ++    case P_SHORT: ++	*(short *)p->varptr = (p->inputtype == PI_ONOFF) ++	    ? str_to_bool(value, *(short *)p->varptr) : atoi(value); ++	break; ++    case P_CHARINT: ++	*(char *)p->varptr = (p->inputtype == PI_ONOFF) ++	    ? str_to_bool(value, *(char *)p->varptr) : atoi(value); ++	break; ++    case P_CHAR: ++	*(char *)p->varptr = value[0]; ++	break; ++    case P_STRING: ++	*(char **)p->varptr = value; ++	break; ++#if defined(USE_SSL) && defined(USE_SSL_VERIFY) ++    case P_SSLPATH: ++	if (value != NULL && value[0] != '\0') ++	    *(char **)p->varptr = rcFile(value); ++	else ++	    *(char **)p->varptr = NULL; ++	ssl_path_modified = 1; ++	break; ++#endif ++#ifdef USE_COLOR ++    case P_COLOR: ++	*(int *)p->varptr = str_to_color(value); ++	break; ++#endif ++#ifdef USE_M17N ++    case P_CODE: ++	*(wc_ces *) p->varptr = ++	    wc_guess_charset_short(value, *(wc_ces *) p->varptr); ++	break; ++#endif ++    case P_PIXELS: ++	ppc = atof(value); ++	if (ppc >= MINIMUM_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; ++    } ++    return 1; ++} ++ ++int ++set_param_option(char *option) ++{ ++    Str tmp = Strnew(); ++    char *p = option, *q; ++ ++    while (*p && !IS_SPACE(*p) && *p != '=') ++	Strcat_char(tmp, *p++); ++    while (*p && IS_SPACE(*p)) ++	p++; ++    if (*p == '=') { ++	p++; ++	while (*p && IS_SPACE(*p)) ++	    p++; ++    } ++    Strlower(tmp); ++    if (set_param(tmp->ptr, p)) ++	goto option_assigned; ++    q = tmp->ptr; ++    if (!strncmp(q, "no", 2)) {	/* -o noxxx, -o no-xxx, -o no_xxx */ ++	q += 2; ++	if (*q == '-' || *q == '_') ++	    q++; ++    } ++    else if (tmp->ptr[0] == '-')	/* -o -xxx */ ++	q++; ++    else ++	return 0; ++    if (set_param(q, "0")) ++	goto option_assigned; ++    return 0; ++  option_assigned: ++    return 1; ++} ++ ++char * ++get_param_option(char *name) ++{ ++    struct param_ptr *p; ++ ++    p = search_param(name); ++    return p ? to_str(p)->ptr : NULL; ++} ++ ++static void ++interpret_rc(FILE * f) ++{ ++    Str line; ++    Str tmp; ++    char *p; ++ ++    for (;;) { ++	line = Strfgets(f); ++	Strchop(line); ++	if (line->length == 0) ++	    break; ++	Strremovefirstspaces(line); ++	if (line->ptr[0] == '#')	/* comment */ ++	    continue; ++	tmp = Strnew(); ++	p = line->ptr; ++	while (*p && !IS_SPACE(*p)) ++	    Strcat_char(tmp, *p++); ++	while (*p && IS_SPACE(*p)) ++	    p++; ++	Strlower(tmp); ++	set_param(tmp->ptr, p); ++    } ++} ++ ++void ++parse_proxy() ++{ ++    if (non_null(HTTP_proxy)) ++	parseURL(HTTP_proxy, &HTTP_proxy_parsed, NULL); ++#ifdef USE_SSL ++    if (non_null(HTTPS_proxy)) ++	parseURL(HTTPS_proxy, &HTTPS_proxy_parsed, NULL); ++#endif				/* USE_SSL */ ++#ifdef USE_GOPHER ++    if (non_null(GOPHER_proxy)) ++	parseURL(GOPHER_proxy, &GOPHER_proxy_parsed, NULL); ++#endif ++    if (non_null(FTP_proxy)) ++	parseURL(FTP_proxy, &FTP_proxy_parsed, NULL); ++    if (non_null(NO_proxy)) ++	set_no_proxy(NO_proxy); ++} ++ ++#ifdef USE_COOKIE ++void ++parse_cookie() ++{ ++    if (non_null(cookie_reject_domains)) ++	Cookie_reject_domains = make_domain_list(cookie_reject_domains); ++    if (non_null(cookie_accept_domains)) ++	Cookie_accept_domains = make_domain_list(cookie_accept_domains); ++} ++#endif ++ ++#ifdef __EMX__ ++static int ++do_mkdir(const char *dir, long mode) ++{ ++    char *r, abs[_MAX_PATH]; ++    size_t n; ++ ++    _abspath(abs, rc_dir, _MAX_PATH);	/* Translate '\\' to '/' */ ++ ++    if (!(n = strlen(abs))) ++	return -1; ++ ++    if (*(r = abs + n - 1) == '/')	/* Ignore tailing slash if it is */ ++	*r = 0; ++ ++    return mkdir(abs, mode); ++} ++#else				/* not __EMX__ */ ++#ifdef __MINGW32_VERSION ++#define do_mkdir(dir,mode) mkdir(dir) ++#else ++#define do_mkdir(dir,mode) mkdir(dir,mode) ++#endif				/* not __MINW32_VERSION */ ++#endif				/* not __EMX__ */ ++ ++void ++sync_with_option(void) ++{ ++    if (PagerMax < LINES) ++	PagerMax = LINES; ++    WrapSearch = WrapDefault; ++    parse_proxy(); ++#ifdef USE_COOKIE ++    parse_cookie(); ++#endif ++    initMailcap(); ++    initMimeTypes(); ++#ifdef USE_EXTERNAL_URI_LOADER ++    initURIMethods(); ++#endif ++#ifdef USE_MIGEMO ++    init_migemo(); ++#endif ++#ifdef USE_IMAGE ++    if (fmInitialized && displayImage) ++	initImage(); ++#else ++    displayImage = FALSE;	/* XXX */ ++#endif ++    loadPasswd(); ++    loadPreForm(); ++ ++    if (AcceptLang == NULL || *AcceptLang == '\0') { ++	/* TRANSLATORS:  ++	 * AcceptLang default: this is used in Accept-Language: HTTP request  ++	 * header. For example, ja.po should translate it as ++	 * "ja;q=1.0, en;q=0.5" like that. ++	 */ ++	AcceptLang = _("en;q=1.0"); ++    } ++    if (AcceptEncoding == NULL || *AcceptEncoding == '\0') ++	AcceptEncoding = acceptableEncoding(); ++    if (AcceptMedia == NULL || *AcceptMedia == '\0') ++	AcceptMedia = acceptableMimeTypes(); ++    if (fmInitialized) { ++	initKeymap(FALSE); ++#ifdef USE_MOUSE ++	initMouseAction(); ++#endif				/* MOUSE */ ++#ifdef USE_MENU ++	initMenu(); ++#endif				/* MENU */ ++    } ++} ++ ++void ++init_rc(void) ++{ ++    int i; ++    struct stat st; ++    FILE *f; ++ ++    if (rc_dir != NULL) ++	goto open_rc; ++ ++    rc_dir = expandPath(RC_DIR); ++    i = strlen(rc_dir); ++    if (i > 1 && rc_dir[i - 1] == '/') ++	rc_dir[i - 1] = '\0'; ++ ++#ifdef USE_M17N ++    display_charset_str = wc_get_ces_list(); ++    document_charset_str = display_charset_str; ++    system_charset_str = display_charset_str; ++#endif ++ ++    if (stat(rc_dir, &st) < 0) { ++	if (errno == ENOENT) {	/* no directory */ ++	    if (do_mkdir(rc_dir, 0700) < 0) { ++		fprintf(stderr, "Can't create config directory (%s)!", rc_dir); ++		goto rc_dir_err; ++	    } ++	    else { ++		stat(rc_dir, &st); ++	    } ++	} ++	else { ++	    fprintf(stderr, "Can't open config directory (%s)!", rc_dir); ++	    goto rc_dir_err; ++	} ++    } ++    if (!S_ISDIR(st.st_mode)) { ++	/* not a directory */ ++	fprintf(stderr, "%s is not a directory!", rc_dir); ++	goto rc_dir_err; ++    } ++    if (!(st.st_mode & S_IWUSR)) { ++	fprintf(stderr, "%s is not writable!", rc_dir); ++	goto rc_dir_err; ++    } ++    no_rc_dir = FALSE; ++    tmp_dir = rc_dir; ++ ++    if (config_file == NULL) ++	config_file = rcFile(CONFIG_FILE); ++ ++    create_option_search_table(); ++ ++  open_rc: ++    /* open config file */ ++    if ((f = fopen(etcFile(W3MCONFIG), "rt")) != NULL) { ++	interpret_rc(f); ++	fclose(f); ++    } ++    if ((f = fopen(confFile(CONFIG_FILE), "rt")) != NULL) { ++	interpret_rc(f); ++	fclose(f); ++    } ++    if ((f = fopen(config_file, "rt")) != NULL) { ++	interpret_rc(f); ++	fclose(f); ++    } ++    return; ++ ++  rc_dir_err: ++    no_rc_dir = TRUE; ++    if (((tmp_dir = getenv("TMPDIR")) == NULL || *tmp_dir == '\0') && ++	((tmp_dir = getenv("TMP")) == NULL || *tmp_dir == '\0') && ++	((tmp_dir = getenv("TEMP")) == NULL || *tmp_dir == '\0')) ++	tmp_dir = "/tmp"; ++} ++ ++ ++static char optionpanel_src1[] = ++    "<html><head><title>Option Setting Panel</title></head><body>\ ++<h1 align=center>Option Setting Panel<br>(w3m version %s)</b></h1>\ ++<form method=post action=\"file:///$LIB/" W3MHELPERPANEL_CMDNAME "\">\ ++<input type=hidden name=mode value=panel>\ ++<input type=hidden name=cookie value=\"%s\">\ ++<input type=submit value=\"%s\">\ ++</form><br>\ ++<form method=internal action=option>"; ++ ++static Str optionpanel_str = NULL; ++ ++static Str ++to_str(struct param_ptr *p) ++{ ++    switch (p->type) { ++    case P_INT: ++#ifdef USE_COLOR ++    case P_COLOR: ++#endif ++#ifdef USE_M17N ++    case P_CODE: ++	return Sprintf("%d", (int)(*(wc_ces *) p->varptr)); ++#endif ++    case P_NZINT: ++	return Sprintf("%d", *(int *)p->varptr); ++    case P_SHORT: ++	return Sprintf("%d", *(short *)p->varptr); ++    case P_CHARINT: ++	return Sprintf("%d", *(char *)p->varptr); ++    case P_CHAR: ++	return Sprintf("%c", *(char *)p->varptr); ++    case P_STRING: ++#if defined(USE_SSL) && defined(USE_SSL_VERIFY) ++    case P_SSLPATH: ++#endif ++	/*  SystemCharset -> InnerCharset */ ++	return Strnew_charp(conv_from_system(*(char **)p->varptr)); ++    case P_PIXELS: ++    case P_SCALE: ++	return Sprintf("%g", *(double *)p->varptr); ++    } ++    /* not reached */ ++    return NULL; ++} ++ ++Buffer * ++load_option_panel(void) ++{ ++    Str src; ++    struct param_ptr *p; ++    struct sel_c *s; ++#ifdef USE_M17N ++    wc_ces_list *c; ++#endif ++    int x, i; ++    Str tmp; ++    Buffer *buf; ++ ++    if (optionpanel_str == NULL) ++	optionpanel_str = Sprintf(optionpanel_src1, w3m_version, ++			      html_quote(localCookie()->ptr), _(CMT_HELPER)); ++#ifdef USE_M17N ++#ifdef ENABLE_NLS ++    OptionCharset = SystemCharset;	/* FIXME */ ++#endif ++    if (!OptionEncode) { ++	optionpanel_str = ++	    wc_Str_conv(optionpanel_str, OptionCharset, InnerCharset); ++	for (i = 0; sections[i].name != NULL; i++) { ++	    sections[i].name = ++		wc_conv(_(sections[i].name), OptionCharset, ++			InnerCharset)->ptr; ++	    for (p = sections[i].params; p->name; p++) { ++		p->comment = ++		    wc_conv(_(p->comment), OptionCharset, ++			    InnerCharset)->ptr; ++		if (p->inputtype == PI_SEL_C ++#ifdef USE_COLOR ++			&& p->select != colorstr ++#endif ++			) { ++		    for (s = (struct sel_c *)p->select; s->text != NULL; s++) { ++			s->text = ++			    wc_conv(_(s->text), OptionCharset, ++				    InnerCharset)->ptr; ++		    } ++		} ++	    } ++	} ++#ifdef USE_COLOR ++	for (s = colorstr; s->text; s++) ++	    s->text = wc_conv(_(s->text), OptionCharset, ++			      InnerCharset)->ptr; ++#endif ++	OptionEncode = TRUE; ++    } ++#endif ++    src = Strdup(optionpanel_str); ++ ++    Strcat_charp(src, "<table><tr><td>"); ++    for (i = 0; sections[i].name != NULL; i++) { ++	Strcat_m_charp(src, "<h1>", sections[i].name, "</h1>", NULL); ++	p = sections[i].params; ++	Strcat_charp(src, "<table width=100% cellpadding=0>"); ++	while (p->name) { ++	    Strcat_m_charp(src, "<tr><td>", p->comment, NULL); ++	    Strcat(src, Sprintf("</td><td width=%d>", ++				(int)(28 * pixel_per_char))); ++	    switch (p->inputtype) { ++	    case PI_TEXT: ++		Strcat_m_charp(src, "<input type=text name=", ++			       p->name, ++			       " value=\"", ++			       html_quote(to_str(p)->ptr), "\">", NULL); ++		break; ++	    case PI_ONOFF: ++		x = atoi(to_str(p)->ptr); ++		Strcat_m_charp(src, "<input type=radio name=", ++			       p->name, ++			       " value=1", ++			       (x ? " checked" : ""), ++			       ">YES  <input type=radio name=", ++			       p->name, ++			       " value=0", (x ? "" : " checked"), ">NO", NULL); ++		break; ++	    case PI_SEL_C: ++		tmp = to_str(p); ++		Strcat_m_charp(src, "<select name=", p->name, ">", NULL); ++		for (s = (struct sel_c *)p->select; s->text != NULL; s++) { ++		    Strcat_charp(src, "<option value="); ++		    Strcat(src, Sprintf("%s\n", s->cvalue)); ++		    if ((p->type != P_CHAR && s->value == atoi(tmp->ptr)) || ++			(p->type == P_CHAR && (char)s->value == *(tmp->ptr))) ++			Strcat_charp(src, " selected"); ++		    Strcat_char(src, '>'); ++		    Strcat_charp(src, s->text); ++		} ++		Strcat_charp(src, "</select>"); ++		break; ++#ifdef USE_M17N ++	    case PI_CODE: ++		tmp = to_str(p); ++		Strcat_m_charp(src, "<select name=", p->name, ">", NULL); ++		for (c = *(wc_ces_list **) p->select; c->desc != NULL; c++) { ++		    Strcat_charp(src, "<option value="); ++		    Strcat(src, Sprintf("%s\n", c->name)); ++		    if (c->id == atoi(tmp->ptr)) ++			Strcat_charp(src, " selected"); ++		    Strcat_char(src, '>'); ++		    Strcat_charp(src, c->desc); ++		} ++		Strcat_charp(src, "</select>"); ++		break; ++#endif ++	    } ++	    Strcat_charp(src, "</td></tr>\n"); ++	    p++; ++	} ++	Strcat_charp(src, ++		     "<tr><td></td><td><p><input type=submit value=\"OK\"></td></tr>"); ++	Strcat_charp(src, "</table><hr width=50%>"); ++    } ++    Strcat_charp(src, "</table></form></body></html>"); ++    buf = loadHTMLString(src); ++#ifdef USE_M17N ++    if (buf) ++	buf->document_charset = OptionCharset; ++#endif ++    return buf; ++} ++ ++void ++panel_set_option(struct parsed_tagarg *arg) ++{ ++    FILE *f = NULL; ++    char *p; ++ ++    if (no_rc_dir) { ++	disp_message("There's no ~/.w3m directory... config not saved", FALSE); ++    } ++    else { ++	f = fopen(config_file, "wt"); ++	if (f == NULL) { ++	    disp_message("Can't write option!", FALSE); ++	} ++    } ++    while (arg) { ++	/*  InnerCharset -> SystemCharset */ ++	if (arg->value) { ++	    p = conv_to_system(arg->value); ++	    if (set_param(arg->arg, p)) { ++		if (f) ++		    fprintf(f, "%s %s\n", arg->arg, p); ++	    } ++	} ++	arg = arg->next; ++    } ++    if (f) ++	fclose(f); ++    sync_with_option(); ++    backBf(); ++} ++ ++char * ++rcFile(char *base) ++{ ++    if (base && ++	(base[0] == '/' || ++	 (base[0] == '.' ++	  && (base[1] == '/' || (base[1] == '.' && base[2] == '/'))) ++	 || (base[0] == '~' && base[1] == '/'))) ++	/* /file, ./file, ../file, ~/file */ ++	return expandPath(base); ++    return expandPath(Strnew_m_charp(rc_dir, "/", base, NULL)->ptr); ++} ++ ++char * ++auxbinFile(char *base) ++{ ++    return expandPath(Strnew_m_charp(w3m_auxbin_dir(), "/", base, NULL)->ptr); ++} ++ ++#if 0				/* not used */ ++char * ++libFile(char *base) ++{ ++    return expandPath(Strnew_m_charp(w3m_lib_dir(), "/", base, NULL)->ptr); ++} ++#endif ++ ++char * ++etcFile(char *base) ++{ ++    return expandPath(Strnew_m_charp(w3m_etc_dir(), "/", base, NULL)->ptr); ++} ++ ++char * ++confFile(char *base) ++{ ++    return expandPath(Strnew_m_charp(w3m_conf_dir(), "/", base, NULL)->ptr); ++} ++ ++#ifndef USE_HELP_CGI ++char * ++helpFile(char *base) ++{ ++    return expandPath(Strnew_m_charp(w3m_help_dir(), "/", base, NULL)->ptr); ++} ++#endif +diff -urN w3m-0.5.2.orig/symbol.c w3m-0.5.2/symbol.c +--- w3m-0.5.2.orig/symbol.c	2003-09-23 06:02:21.000000000 +0900 ++++ w3m-0.5.2/symbol.c	2010-07-18 08:13:26.000000000 +0900 +@@ -86,24 +86,29 @@ +     charset_symbol_set *p; +     symbol_set *s = NULL; +  +-    if (charset == save_charset && save_symbol != NULL && +-	*width == save_symbol->width) { +-	*width = save_symbol->width; +-	return save_symbol->item; +-    } +-    save_charset = charset; +-    for (p = charset_symbol_list; p->charset; p++) { +-	if (charset == p->charset && +-	    (*width == 0 || *width == p->symbol->width)) { +-	    s = p->symbol; +-	    break; ++    if (UseGraphicChar != GRAPHIC_CHAR_ASCII) { ++	if (charset == save_charset && save_symbol != NULL && ++	    *width == save_symbol->width) ++	    return save_symbol->item; ++	save_charset = charset; ++	for (p = charset_symbol_list; p->charset; p++) { ++	    if (charset == p->charset && ++		(*width == 0 || *width == p->symbol->width)) { ++		s = p->symbol; ++		break; ++	    } + 	} +-    } +-    if (s == NULL) ++	if (s == NULL) ++	    s = (*width == 2) ? &alt2_symbol_set : &alt_symbol_set; ++	if (s != save_symbol) { ++	    if (!s->encode) ++		encode_symbol(s); ++	    save_symbol = s; ++	} ++    } else { ++	if (save_symbol != NULL && *width == save_symbol->width) ++	    return save_symbol->item; + 	s = (*width == 2) ? &alt2_symbol_set : &alt_symbol_set; +-    if (s != save_symbol) { +-	if (!s->encode) +-	    encode_symbol(s); + 	save_symbol = s; +     } +     *width = s->width; +diff -urN w3m-0.5.2.orig/terms.c w3m-0.5.2/terms.c +--- w3m-0.5.2.orig/terms.c	2007-05-30 13:44:00.000000000 +0900 ++++ w3m-0.5.2/terms.c	2010-07-18 08:13:26.000000000 +0900 +@@ -1201,7 +1201,7 @@ + int + graph_ok(void) + { +-    if (!UseGraphicChar) ++    if (UseGraphicChar != GRAPHIC_CHAR_ALL) + 	return 0; +     return T_as[0] != 0 && T_ae[0] != 0 && T_ac[0] != 0; + } +diff -urN w3m-0.5.2.orig/terms.c.orig w3m-0.5.2/terms.c.orig +--- w3m-0.5.2.orig/terms.c.orig	1970-01-01 09:00:00.000000000 +0900 ++++ w3m-0.5.2/terms.c.orig	2007-05-30 13:44:00.000000000 +0900 +@@ -0,0 +1,2257 @@ ++/* $Id: terms.c,v 1.57 2007/05/30 04:44:00 inu Exp $ */ ++/*  ++ * An original curses library for EUC-kanji by Akinori ITO,     December 1989 ++ * revised by Akinori ITO, January 1995 ++ */ ++#include <stdio.h> ++#include <signal.h> ++#include <sys/types.h> ++#include <fcntl.h> ++#include <errno.h> ++#include <sys/time.h> ++#include <unistd.h> ++#include "config.h" ++#include <string.h> ++#ifdef HAVE_SYS_SELECT_H ++#include <sys/select.h> ++#endif ++#ifndef __MINGW32_VERSION ++#include <sys/ioctl.h> ++#else ++#include <winsock.h> ++#endif /* __MINGW32_VERSION */ ++#ifdef USE_MOUSE ++#ifdef USE_GPM ++#include <gpm.h> ++#endif				/* USE_GPM */ ++#ifdef USE_SYSMOUSE ++#include <osreldate.h> ++#if (__FreeBSD_version >= 400017) ++#include <sys/consio.h> ++#include <sys/fbio.h> ++#else ++#include <machine/console.h> ++#endif ++int (*sysm_handler) (int x, int y, int nbs, int obs); ++static int cwidth = 8, cheight = 16; ++static int xpix, ypix, nbs, obs = 0; ++#endif				/* use_SYSMOUSE */ ++ ++static int is_xterm = 0; ++ ++void mouse_init(), mouse_end(); ++int mouseActive = 0; ++#endif				/* USE_MOUSE */ ++ ++static char *title_str = NULL; ++ ++static int tty; ++ ++#include "terms.h" ++#include "fm.h" ++#include "myctype.h" ++ ++#ifdef __EMX__ ++#define INCL_DOSNLS ++#include <os2.h> ++#endif				/* __EMX__ */ ++ ++#if defined(__CYGWIN__) ++#include <windows.h> ++#include <sys/cygwin.h> ++static int isWinConsole = 0; ++#define TERM_CYGWIN 1 ++#define TERM_CYGWIN_RESERVE_IME 2 ++static int isLocalConsole = 0; ++ ++#if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE) ++int cygwin_mouse_btn_swapped = 0; ++#endif ++ ++#if defined(SUPPORT_WIN9X_CONSOLE_MBCS) ++static HANDLE hConIn = INVALID_HANDLE_VALUE; ++static int isWin95 = 0; ++static char *ConInV; ++static int iConIn, nConIn, nConInMax; ++ ++static void ++check_win9x(void) ++{ ++    OSVERSIONINFO winVersionInfo; ++ ++    winVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); ++    if (GetVersionEx(&winVersionInfo) == 0) { ++	fprintf(stderr, "can't get Windows version information.\n"); ++	exit(1); ++    } ++    if (winVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { ++	isWin95 = 1; ++    } ++    else { ++	isWin95 = 0; ++    } ++} ++ ++void ++enable_win9x_console_input(void) ++{ ++    if (isWin95 && isWinConsole && isLocalConsole && ++	hConIn == INVALID_HANDLE_VALUE) { ++	hConIn = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE, ++			    FILE_SHARE_READ | FILE_SHARE_WRITE, ++			    NULL, OPEN_EXISTING, 0, NULL); ++	if (hConIn != INVALID_HANDLE_VALUE) { ++	    getch(); ++	} ++    } ++} ++ ++void ++disable_win9x_console_input(void) ++{ ++    if (hConIn != INVALID_HANDLE_VALUE) { ++	CloseHandle(hConIn); ++	hConIn = INVALID_HANDLE_VALUE; ++    } ++} ++ ++static void ++expand_win32_console_input_buffer(int n) ++{ ++    if (nConIn + n >= nConInMax) { ++	char *oldv; ++ ++	nConInMax = ((nConIn + n) / 2 + 1) * 3; ++	oldv = ConInV; ++	ConInV = GC_MALLOC_ATOMIC(nConInMax); ++	memcpy(ConInV, oldv, nConIn); ++    } ++} ++ ++static int ++read_win32_console_input(void) ++{ ++    INPUT_RECORD rec; ++    DWORD nevents; ++ ++    if (PeekConsoleInput(hConIn, &rec, 1, &nevents) && nevents) { ++	switch (rec.EventType) { ++	case KEY_EVENT: ++	    expand_win32_console_input_buffer(3); ++ ++	    if (ReadConsole(hConIn, &ConInV[nConIn], 1, &nevents, NULL)) { ++		nConIn += nevents; ++		return nevents; ++	    } ++ ++	    break; ++	default: ++	    break; ++	} ++ ++	ReadConsoleInput(hConIn, &rec, 1, &nevents); ++    } ++    return 0; ++} ++ ++static int ++read_win32_console(char *s, int n) ++{ ++    KEY_EVENT_RECORD *ker; ++ ++    if (hConIn == INVALID_HANDLE_VALUE) ++	return read(tty, s, n); ++ ++    if (n > 0) ++	for (;;) { ++	    if (iConIn < nConIn) { ++		if (n > nConIn - iConIn) ++		    n = nConIn - iConIn; ++ ++		memcpy(s, ConInV, n); ++ ++		if ((iConIn += n) >= nConIn) ++		    iConIn = nConIn = 0; ++ ++		break; ++	    } ++ ++	    iConIn = nConIn = 0; ++ ++	    while (!read_win32_console_input()) ; ++	} ++ ++    return n; ++} ++ ++#endif				/* SUPPORT_WIN9X_CONSOLE_MBCS */ ++ ++static HWND ++GetConsoleHwnd(void) ++{ ++#define MY_BUFSIZE 1024 ++    HWND hwndFound; ++    char pszNewWindowTitle[MY_BUFSIZE]; ++    char pszOldWindowTitle[MY_BUFSIZE]; ++ ++    GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE); ++    wsprintf(pszNewWindowTitle, "%d/%d", ++	     GetTickCount(), GetCurrentProcessId()); ++    SetConsoleTitle(pszNewWindowTitle); ++    Sleep(40); ++    hwndFound = FindWindow(NULL, pszNewWindowTitle); ++    SetConsoleTitle(pszOldWindowTitle); ++    return (hwndFound); ++} ++ ++#if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE) ++static unsigned long ++cygwin_version(void) ++{ ++    struct per_process *p; ++ ++    p = (struct per_process *)cygwin_internal(CW_USER_DATA); ++    if (p != NULL) { ++	return (p->dll_major * 1000) + p->dll_minor; ++    } ++    return 0; ++} ++#endif ++ ++static void ++check_cygwin_console(void) ++{ ++    char *term = getenv("TERM"); ++    HANDLE hWnd; ++ ++    if (term == NULL) ++	term = DEFAULT_TERM; ++    if (term && strncmp(term, "cygwin", 6) == 0) { ++	isWinConsole = TERM_CYGWIN; ++    } ++    if (isWinConsole) { ++	hWnd = GetConsoleHwnd(); ++	if (hWnd != INVALID_HANDLE_VALUE) { ++	    if (IsWindowVisible(hWnd)) { ++		isLocalConsole = 1; ++	    } ++	} ++	if (strncmp(getenv("LANG"), "ja", 2) == 0) { ++	    isWinConsole = TERM_CYGWIN_RESERVE_IME; ++	} ++#ifdef SUPPORT_WIN9X_CONSOLE_MBCS ++	check_win9x(); ++	if (isWin95 && ttyslot() != -1) { ++	    isLocalConsole = 0; ++	} ++#endif ++    } ++#if CYGWIN_VERSION_DLL_MAJOR < 1005 && defined(USE_MOUSE) ++    if (cygwin_version() <= 1003015) { ++	/* cygwin DLL 1.3.15 or earler */ ++	cygwin_mouse_btn_swapped = 1; ++    } ++#endif ++} ++#endif				/* __CYGWIN__ */ ++ ++char *getenv(const char *); ++MySignalHandler reset_exit(SIGNAL_ARG), error_dump(SIGNAL_ARG); ++void setlinescols(void); ++void flush_tty(); ++ ++#ifndef SIGIOT ++#define SIGIOT SIGABRT ++#endif				/* not SIGIOT */ ++ ++#ifdef HAVE_TERMIO_H ++#include <termio.h> ++typedef struct termio TerminalMode; ++#define TerminalSet(fd,x)       ioctl(fd,TCSETA,x) ++#define TerminalGet(fd,x)       ioctl(fd,TCGETA,x) ++#define MODEFLAG(d)     ((d).c_lflag) ++#define IMODEFLAG(d)    ((d).c_iflag) ++#endif				/* HAVE_TERMIO_H */ ++ ++#ifdef HAVE_TERMIOS_H ++#include <termios.h> ++#include <unistd.h> ++typedef struct termios TerminalMode; ++#define TerminalSet(fd,x)       tcsetattr(fd,TCSANOW,x) ++#define TerminalGet(fd,x)       tcgetattr(fd,x) ++#define MODEFLAG(d)     ((d).c_lflag) ++#define IMODEFLAG(d)    ((d).c_iflag) ++#endif				/* HAVE_TERMIOS_H */ ++ ++#ifdef HAVE_SGTTY_H ++#include <sgtty.h> ++typedef struct sgttyb TerminalMode; ++#define TerminalSet(fd,x)       ioctl(fd,TIOCSETP,x) ++#define TerminalGet(fd,x)       ioctl(fd,TIOCGETP,x) ++#define MODEFLAG(d)     ((d).sg_flags) ++#endif				/* HAVE_SGTTY_H */ ++ ++#ifdef __MINGW32_VERSION ++/* dummy struct */ ++typedef unsigned char   cc_t; ++typedef unsigned int    speed_t; ++typedef unsigned int    tcflag_t; ++ ++#define NCCS 32 ++struct termios ++  { ++    tcflag_t c_iflag;           /* input mode flags */ ++    tcflag_t c_oflag;           /* output mode flags */ ++    tcflag_t c_cflag;           /* control mode flags */ ++    tcflag_t c_lflag;           /* local mode flags */ ++    cc_t c_line;                        /* line discipline */ ++    cc_t c_cc[NCCS];            /* control characters */ ++    speed_t c_ispeed;           /* input speed */ ++    speed_t c_ospeed;           /* output speed */ ++  }; ++typedef struct termios TerminalMode; ++#define TerminalSet(fd,x)       (0) ++#define TerminalGet(fd,x)       (0) ++#define MODEFLAG(d)     (0) ++ ++/* dummy defines */ ++#define SIGHUP (0) ++#define SIGQUIT (0) ++#define ECHO (0) ++#define ISIG (0) ++#define VEOF (0) ++#define ICANON (0) ++#define IXON (0) ++#define IXOFF (0) ++ ++char *ttyname(int); ++#endif /* __MINGW32_VERSION */ ++ ++#define MAX_LINE        200 ++#define MAX_COLUMN      400 ++ ++/* Screen properties */ ++#define S_SCREENPROP    0x0f ++#define S_NORMAL        0x00 ++#define S_STANDOUT      0x01 ++#define S_UNDERLINE     0x02 ++#define S_BOLD          0x04 ++#define S_EOL           0x08 ++ ++/* Sort of Character */ ++#define C_WHICHCHAR     0xc0 ++#define C_ASCII         0x00 ++#ifdef USE_M17N ++#define C_WCHAR1        0x40 ++#define C_WCHAR2        0x80 ++#endif ++#define C_CTRL          0xc0 ++ ++#define CHMODE(c)       ((c)&C_WHICHCHAR) ++#define SETCHMODE(var,mode)	((var) = (((var)&~C_WHICHCHAR) | mode)) ++#ifdef USE_M17N ++#define SETCH(var,ch,len)	((var) = New_Reuse(char, (var), (len) + 1), \ ++				strncpy((var), (ch), (len)), (var)[len] = '\0') ++#else ++#define SETCH(var,ch,len)	((var) = (ch)) ++#endif ++ ++/* Charactor Color */ ++#define COL_FCOLOR      0xf00 ++#define COL_FBLACK      0x800 ++#define COL_FRED        0x900 ++#define COL_FGREEN      0xa00 ++#define COL_FYELLOW     0xb00 ++#define COL_FBLUE       0xc00 ++#define COL_FMAGENTA    0xd00 ++#define COL_FCYAN       0xe00 ++#define COL_FWHITE      0xf00 ++#define COL_FTERM       0x000 ++ ++#define S_COLORED       0xf00 ++ ++#ifdef USE_BG_COLOR ++/* Background Color */ ++#define COL_BCOLOR      0xf000 ++#define COL_BBLACK      0x8000 ++#define COL_BRED        0x9000 ++#define COL_BGREEN      0xa000 ++#define COL_BYELLOW     0xb000 ++#define COL_BBLUE       0xc000 ++#define COL_BMAGENTA    0xd000 ++#define COL_BCYAN       0xe000 ++#define COL_BWHITE      0xf000 ++#define COL_BTERM       0x0000 ++ ++#define S_BCOLORED      0xf000 ++#endif				/* USE_BG_COLOR */ ++ ++ ++#define S_GRAPHICS      0x10 ++ ++#define S_DIRTY         0x20 ++ ++#define SETPROP(var,prop) (var = (((var)&S_DIRTY) | prop)) ++ ++/* Line status */ ++#define L_DIRTY         0x01 ++#define L_UNUSED        0x02 ++#define L_NEED_CE       0x04 ++#define L_CLRTOEOL      0x08 ++ ++#define ISDIRTY(d)      ((d) & L_DIRTY) ++#define ISUNUSED(d)     ((d) & L_UNUSED) ++#define NEED_CE(d)      ((d) & L_NEED_CE) ++ ++typedef unsigned short l_prop; ++ ++typedef struct scline { ++#ifdef USE_M17N ++    char **lineimage; ++#else ++    char *lineimage; ++#endif ++    l_prop *lineprop; ++    short isdirty; ++    short eol; ++} Screen; ++ ++static TerminalMode d_ioval; ++static int tty = -1; ++static FILE *ttyf = NULL; ++ ++static ++char bp[1024], funcstr[256]; ++ ++char *T_cd, *T_ce, *T_kr, *T_kl, *T_cr, *T_bt, *T_ta, *T_sc, *T_rc, ++    *T_so, *T_se, *T_us, *T_ue, *T_cl, *T_cm, *T_al, *T_sr, *T_md, *T_me, ++    *T_ti, *T_te, *T_nd, *T_as, *T_ae, *T_eA, *T_ac, *T_op; ++ ++int LINES, COLS; ++#if defined(__CYGWIN__) ++int LASTLINE; ++#endif				/* defined(__CYGWIN__) */ ++ ++static int max_LINES = 0, max_COLS = 0; ++static int tab_step = 8; ++static int CurLine, CurColumn; ++static Screen *ScreenElem = NULL, **ScreenImage = NULL; ++static l_prop CurrentMode = 0; ++static int graph_enabled = 0; ++ ++static char gcmap[96]; ++ ++extern int tgetent(char *, char *); ++extern int tgetnum(char *); ++extern int tgetflag(char *); ++extern char *tgetstr(char *, char **); ++extern char *tgoto(char *, int, int); ++extern int tputs(char *, int, int (*)(char)); ++void clear(), wrap(), touch_line(), touch_column(int); ++#if 0 ++void need_clrtoeol(void); ++#endif ++void clrtoeol(void);		/* conflicts with curs_clear(3)? */ ++ ++static int write1(char); ++ ++static void ++writestr(char *s) ++{ ++    tputs(s, 1, write1); ++} ++ ++#define MOVE(line,column)       writestr(tgoto(T_cm,column,line)); ++ ++#ifdef USE_MOUSE ++#define W3M_TERM_INFO(name, title, mouse)	name, title, mouse ++#define NEED_XTERM_ON   (1) ++#define NEED_XTERM_OFF  (1<<1) ++#ifdef __CYGWIN__ ++#define NEED_CYGWIN_ON  (1<<2) ++#define NEED_CYGWIN_OFF (1<<3) ++#endif ++#else ++#define W3M_TERM_INFO(name, title, mouse)	name, title ++#endif ++ ++static char XTERM_TITLE[] = "\033]0;w3m: %s\007"; ++static char SCREEN_TITLE[] = "\033k%s\033\134"; ++#ifdef __CYGWIN__ ++static char CYGWIN_TITLE[] = "w3m: %s"; ++#endif ++ ++/* *INDENT-OFF* */ ++static struct w3m_term_info { ++    char *term; ++    char *title_str; ++#ifdef USE_MOUSE ++    int mouse_flag; ++#endif ++} w3m_term_info_list[] = { ++    {W3M_TERM_INFO("xterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, ++    {W3M_TERM_INFO("kterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, ++    {W3M_TERM_INFO("rxvt", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, ++    {W3M_TERM_INFO("Eterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, ++    {W3M_TERM_INFO("mlterm", XTERM_TITLE, (NEED_XTERM_ON|NEED_XTERM_OFF))}, ++    {W3M_TERM_INFO("screen", SCREEN_TITLE, 0)}, ++#ifdef __CYGWIN__ ++    {W3M_TERM_INFO("cygwin", CYGWIN_TITLE, (NEED_CYGWIN_ON|NEED_CYGWIN_OFF))}, ++#endif ++    {W3M_TERM_INFO(NULL, NULL, 0)} ++}; ++#undef W3M_TERM_INFO ++/* *INDENT-ON * */ ++ ++int ++set_tty(void) ++{ ++    char *ttyn; ++ ++    if (isatty(0))		/* stdin */ ++	ttyn = ttyname(0); ++    else ++	ttyn = DEV_TTY_PATH; ++    tty = open(ttyn, O_RDWR); ++    if (tty < 0) { ++	/* use stderr instead of stdin... is it OK???? */ ++	tty = 2; ++    } ++    ttyf = fdopen(tty, "w"); ++#ifdef __CYGWIN__ ++    check_cygwin_console(); ++#endif ++    TerminalGet(tty, &d_ioval); ++    if (displayTitleTerm != NULL) { ++	struct w3m_term_info *p; ++	for (p = w3m_term_info_list; p->term != NULL; p++) { ++	    if (!strncmp(displayTitleTerm, p->term, strlen(p->term))) { ++		title_str = p->title_str; ++		break; ++	    } ++	} ++    } ++#ifdef USE_MOUSE ++    { ++	char *term = getenv("TERM"); ++	if (term != NULL) { ++	    struct w3m_term_info *p; ++	    for (p = w3m_term_info_list; p->term != NULL; p++) { ++		if (!strncmp(term, p->term, strlen(p->term))) { ++			is_xterm = p->mouse_flag; ++			break; ++		    } ++		} ++	} ++    } ++#endif ++    return 0; ++} ++ ++void ++ttymode_set(int mode, int imode) ++{ ++#ifndef __MINGW32_VERSION ++    TerminalMode ioval; ++ ++    TerminalGet(tty, &ioval); ++    MODEFLAG(ioval) |= mode; ++#ifndef HAVE_SGTTY_H ++    IMODEFLAG(ioval) |= imode; ++#endif				/* not HAVE_SGTTY_H */ ++ ++    while (TerminalSet(tty, &ioval) == -1) { ++	if (errno == EINTR || errno == EAGAIN) ++	    continue; ++	printf("Error occured while set %x: errno=%d\n", mode, errno); ++	reset_exit(SIGNAL_ARGLIST); ++    } ++#endif ++} ++ ++void ++ttymode_reset(int mode, int imode) ++{ ++#ifndef __MINGW32_VERSION ++    TerminalMode ioval; ++ ++    TerminalGet(tty, &ioval); ++    MODEFLAG(ioval) &= ~mode; ++#ifndef HAVE_SGTTY_H ++    IMODEFLAG(ioval) &= ~imode; ++#endif				/* not HAVE_SGTTY_H */ ++ ++    while (TerminalSet(tty, &ioval) == -1) { ++	if (errno == EINTR || errno == EAGAIN) ++	    continue; ++	printf("Error occured while reset %x: errno=%d\n", mode, errno); ++	reset_exit(SIGNAL_ARGLIST); ++    } ++#endif /* __MINGW32_VERSION */ ++} ++ ++#ifndef HAVE_SGTTY_H ++void ++set_cc(int spec, int val) ++{ ++    TerminalMode ioval; ++ ++    TerminalGet(tty, &ioval); ++    ioval.c_cc[spec] = val; ++    while (TerminalSet(tty, &ioval) == -1) { ++	if (errno == EINTR || errno == EAGAIN) ++	    continue; ++	printf("Error occured: errno=%d\n", errno); ++	reset_exit(SIGNAL_ARGLIST); ++    } ++} ++#endif				/* not HAVE_SGTTY_H */ ++ ++void ++close_tty(void) ++{ ++    if (tty > 2) ++	close(tty); ++} ++ ++char * ++ttyname_tty(void) ++{ ++    return ttyname(tty); ++} ++ ++void ++reset_tty(void) ++{ ++    writestr(T_op);		/* turn off */ ++    writestr(T_me); ++    if (!Do_not_use_ti_te) { ++	if (T_te && *T_te) ++	    writestr(T_te); ++	else ++	    writestr(T_cl); ++    } ++    writestr(T_se);		/* reset terminal */ ++    flush_tty(); ++    TerminalSet(tty, &d_ioval); ++    close_tty(); ++} ++ ++MySignalHandler ++reset_exit(SIGNAL_ARG) ++{ ++#ifdef USE_MOUSE ++    if (mouseActive) ++	mouse_end(); ++#endif				/* USE_MOUSE */ ++    reset_tty(); ++    w3m_exit(0); ++    SIGNAL_RETURN; ++} ++ ++MySignalHandler ++error_dump(SIGNAL_ARG) ++{ ++    mySignal(SIGIOT, SIG_DFL); ++    reset_tty(); ++    abort(); ++    SIGNAL_RETURN; ++} ++ ++void ++set_int(void) ++{ ++    mySignal(SIGHUP, reset_exit); ++    mySignal(SIGINT, reset_exit); ++    mySignal(SIGQUIT, reset_exit); ++    mySignal(SIGTERM, reset_exit); ++    mySignal(SIGILL, error_dump); ++    mySignal(SIGIOT, error_dump); ++    mySignal(SIGFPE, error_dump); ++#ifdef	SIGBUS ++    mySignal(SIGBUS, error_dump); ++#endif				/* SIGBUS */ ++    /* mySignal(SIGSEGV, error_dump); */ ++} ++ ++ ++static void ++setgraphchar(void) ++{ ++    int c, i, n; ++ ++    for (c = 0; c < 96; c++) ++	gcmap[c] = (char)(c + ' '); ++ ++    if (!T_ac) ++	return; ++ ++    n = strlen(T_ac); ++    for (i = 0; i < n - 1; i += 2) { ++	c = (unsigned)T_ac[i] - ' '; ++	if (c >= 0 && c < 96) ++	    gcmap[c] = T_ac[i + 1]; ++    } ++} ++ ++#define graphchar(c) (((unsigned)(c)>=' ' && (unsigned)(c)<128)? gcmap[(c)-' '] : (c)) ++#define GETSTR(v,s) {v = pt; suc = tgetstr(s,&pt); if (!suc) v = ""; else v = allocStr(suc, -1); } ++ ++void ++getTCstr(void) ++{ ++    char *ent; ++    char *suc; ++    char *pt = funcstr; ++    int r; ++ ++    ent = getenv("TERM") ? getenv("TERM") : DEFAULT_TERM; ++    if (ent == NULL) { ++	fprintf(stderr, "TERM is not set\n"); ++	reset_exit(SIGNAL_ARGLIST); ++    } ++ ++    r = tgetent(bp, ent); ++    if (r != 1) { ++	/* Can't find termcap entry */ ++	fprintf(stderr, "Can't find termcap entry %s\n", ent); ++	reset_exit(SIGNAL_ARGLIST); ++    } ++ ++    GETSTR(T_ce, "ce");		/* clear to the end of line */ ++    GETSTR(T_cd, "cd");		/* clear to the end of display */ ++    GETSTR(T_kr, "nd");		/* cursor right */ ++    if (suc == NULL) ++	GETSTR(T_kr, "kr"); ++    if (tgetflag("bs")) ++	T_kl = "\b";		/* cursor left */ ++    else { ++	GETSTR(T_kl, "le"); ++	if (suc == NULL) ++	    GETSTR(T_kl, "kb"); ++	if (suc == NULL) ++	    GETSTR(T_kl, "kl"); ++    } ++    GETSTR(T_cr, "cr");		/* carriage return */ ++    GETSTR(T_ta, "ta");		/* tab */ ++    GETSTR(T_sc, "sc");		/* save cursor */ ++    GETSTR(T_rc, "rc");		/* restore cursor */ ++    GETSTR(T_so, "so");		/* standout mode */ ++    GETSTR(T_se, "se");		/* standout mode end */ ++    GETSTR(T_us, "us");		/* underline mode */ ++    GETSTR(T_ue, "ue");		/* underline mode end */ ++    GETSTR(T_md, "md");		/* bold mode */ ++    GETSTR(T_me, "me");		/* bold mode end */ ++    GETSTR(T_cl, "cl");		/* clear screen */ ++    GETSTR(T_cm, "cm");		/* cursor move */ ++    GETSTR(T_al, "al");		/* append line */ ++    GETSTR(T_sr, "sr");		/* scroll reverse */ ++    GETSTR(T_ti, "ti");		/* terminal init */ ++    GETSTR(T_te, "te");		/* terminal end */ ++    GETSTR(T_nd, "nd");		/* move right one space */ ++    GETSTR(T_eA, "eA");		/* enable alternative charset */ ++    GETSTR(T_as, "as");		/* alternative (graphic) charset start */ ++    GETSTR(T_ae, "ae");		/* alternative (graphic) charset end */ ++    GETSTR(T_ac, "ac");		/* graphics charset pairs */ ++    GETSTR(T_op, "op");		/* set default color pair to its original value */ ++#if defined( CYGWIN ) && CYGWIN < 1 ++    /* for TERM=pcansi on MS-DOS prompt. */ ++#if 0 ++    T_eA = ""; ++    T_as = "\033[12m"; ++    T_ae = "\033[10m"; ++    T_ac = "l\001k\002m\003j\004x\005q\006n\020a\024v\025w\026u\027t\031"; ++#endif ++    T_eA = ""; ++    T_as = ""; ++    T_ae = ""; ++    T_ac = ""; ++#endif				/* CYGWIN */ ++ ++    LINES = COLS = 0; ++    setlinescols(); ++    setgraphchar(); ++} ++ ++void ++setlinescols(void) ++{ ++    char *p; ++    int i; ++#ifdef __EMX__ ++    { ++	int s[2]; ++	_scrsize(s); ++	COLS = s[0]; ++	LINES = s[1]; ++ ++	if (getenv("WINDOWID")) { ++	    FILE *fd = popen("scrsize", "rt"); ++	    if (fd) { ++		fscanf(fd, "%i %i", &COLS, &LINES); ++		pclose(fd); ++	    } ++	} ++    } ++#elif defined(HAVE_TERMIOS_H) && defined(TIOCGWINSZ) ++    struct winsize wins; ++ ++    i = ioctl(tty, TIOCGWINSZ, &wins); ++    if (i >= 0 && wins.ws_row != 0 && wins.ws_col != 0) { ++	LINES = wins.ws_row; ++	COLS = wins.ws_col; ++    } ++#endif				/* defined(HAVE-TERMIOS_H) && defined(TIOCGWINSZ) */ ++    if (LINES <= 0 && (p = getenv("LINES")) != NULL && (i = atoi(p)) >= 0) ++	LINES = i; ++    if (COLS <= 0 && (p = getenv("COLUMNS")) != NULL && (i = atoi(p)) >= 0) ++	COLS = i; ++    if (LINES <= 0) ++	LINES = tgetnum("li");	/* number of line */ ++    if (COLS <= 0) ++	COLS = tgetnum("co");	/* number of column */ ++    if (COLS > MAX_COLUMN) ++	COLS = MAX_COLUMN; ++    if (LINES > MAX_LINE) ++	LINES = MAX_LINE; ++#if defined(__CYGWIN__) ++    LASTLINE = LINES - (isWinConsole == TERM_CYGWIN_RESERVE_IME ? 2 : 1); ++#endif				/* defined(__CYGWIN__) */ ++} ++ ++void ++setupscreen(void) ++{ ++    int i; ++ ++    if (LINES + 1 > max_LINES) { ++	max_LINES = LINES + 1; ++	max_COLS = 0; ++	ScreenElem = New_N(Screen, max_LINES); ++	ScreenImage = New_N(Screen *, max_LINES); ++    } ++    if (COLS + 1 > max_COLS) { ++	max_COLS = COLS + 1; ++	for (i = 0; i < max_LINES; i++) { ++#ifdef USE_M17N ++	    ScreenElem[i].lineimage = New_N(char *, max_COLS); ++	    bzero((void *)ScreenElem[i].lineimage, max_COLS * sizeof(char *)); ++#else ++	    ScreenElem[i].lineimage = New_N(char, max_COLS); ++#endif ++	    ScreenElem[i].lineprop = New_N(l_prop, max_COLS); ++	} ++    } ++    for (i = 0; i < LINES; i++) { ++	ScreenImage[i] = &ScreenElem[i]; ++	ScreenImage[i]->lineprop[0] = S_EOL; ++	ScreenImage[i]->isdirty = 0; ++    } ++    for (; i < max_LINES; i++) { ++	ScreenElem[i].isdirty = L_UNUSED; ++    } ++ ++    clear(); ++} ++ ++/*  ++ * Screen initialize ++ */ ++int ++initscr(void) ++{ ++    if (set_tty() < 0) ++	return -1; ++    set_int(); ++    getTCstr(); ++    if (T_ti && !Do_not_use_ti_te) ++	writestr(T_ti); ++    setupscreen(); ++    return 0; ++} ++ ++static int ++write1(char c) ++{ ++    putc(c, ttyf); ++#ifdef SCREEN_DEBUG ++    flush_tty(); ++#endif				/* SCREEN_DEBUG */ ++    return 0; ++} ++ ++void ++move(int line, int column) ++{ ++    if (line >= 0 && line < LINES) ++	CurLine = line; ++    if (column >= 0 && column < COLS) ++	CurColumn = column; ++} ++ ++#ifdef USE_BG_COLOR ++#define M_SPACE (S_SCREENPROP|S_COLORED|S_BCOLORED|S_GRAPHICS) ++#else				/* not USE_BG_COLOR */ ++#define M_SPACE (S_SCREENPROP|S_COLORED|S_GRAPHICS) ++#endif				/* not USE_BG_COLOR */ ++ ++static int ++#ifdef USE_M17N ++need_redraw(char *c1, l_prop pr1, char *c2, l_prop pr2) ++{ ++    if (!c1 || !c2 || strcmp(c1, c2)) ++	return 1; ++    if (*c1 == ' ') ++#else ++need_redraw(char c1, l_prop pr1, char c2, l_prop pr2) ++{ ++    if (c1 != c2) ++	return 1; ++    if (c1 == ' ') ++#endif ++	return (pr1 ^ pr2) & M_SPACE & ~S_DIRTY; ++ ++    if ((pr1 ^ pr2) & ~S_DIRTY) ++	return 1; ++ ++    return 0; ++} ++ ++#define M_CEOL (~(M_SPACE|C_WHICHCHAR)) ++ ++#ifdef USE_M17N ++#define SPACE " " ++#else ++#define SPACE ' ' ++#endif ++ ++#ifdef USE_M17N ++void ++addch(char c) ++{ ++    addmch(&c, 1); ++} ++ ++void ++addmch(char *pc, size_t len) ++#else ++void ++addch(char pc) ++#endif ++{ ++    l_prop *pr; ++    int dest, i; ++    short *dirty; ++#ifdef USE_M17N ++    static Str tmp = NULL; ++    char **p; ++    char c = *pc; ++    int width = wtf_width((wc_uchar *) pc); ++ ++    if (tmp == NULL) ++	tmp = Strnew(); ++    Strcopy_charp_n(tmp, pc, len); ++    pc = tmp->ptr; ++#else ++    char *p; ++    char c = pc; ++#endif ++ ++    if (CurColumn == COLS) ++	wrap(); ++    if (CurColumn >= COLS) ++	return; ++    p = ScreenImage[CurLine]->lineimage; ++    pr = ScreenImage[CurLine]->lineprop; ++    dirty = &ScreenImage[CurLine]->isdirty; ++ ++#ifndef USE_M17N ++    /* Eliminate unprintables according to * iso-8859-*. ++     * Particularly 0x96 messes up T.Dickey's * (xfree-)xterm */ ++    if (IS_INTSPACE(c)) ++	c = ' '; ++#endif ++ ++    if (pr[CurColumn] & S_EOL) { ++	if (c == ' ' && !(CurrentMode & M_SPACE)) { ++	    CurColumn++; ++	    return; ++	} ++	for (i = CurColumn; i >= 0 && (pr[i] & S_EOL); i--) { ++	    SETCH(p[i], SPACE, 1); ++	    SETPROP(pr[i], (pr[i] & M_CEOL) | C_ASCII); ++	} ++    } ++ ++    if (c == '\t' || c == '\n' || c == '\r' || c == '\b') ++	SETCHMODE(CurrentMode, C_CTRL); ++#ifdef USE_M17N ++    else if (len > 1) ++	SETCHMODE(CurrentMode, C_WCHAR1); ++#endif ++    else if (!IS_CNTRL(c)) ++	SETCHMODE(CurrentMode, C_ASCII); ++    else ++	return; ++ ++    /* Required to erase bold or underlined character for some * terminal ++     * emulators. */ ++#ifdef USE_M17N ++    i = CurColumn + width - 1; ++#else ++    i = CurColumn; ++#endif ++    if (i < COLS && ++	(((pr[i] & S_BOLD) && need_redraw(p[i], pr[i], pc, CurrentMode)) || ++	 ((pr[i] & S_UNDERLINE) && !(CurrentMode & S_UNDERLINE)))) { ++	touch_line(); ++	i++; ++	if (i < COLS) { ++	    touch_column(i); ++	    if (pr[i] & S_EOL) { ++		SETCH(p[i], SPACE, 1); ++		SETPROP(pr[i], (pr[i] & M_CEOL) | C_ASCII); ++	    } ++#ifdef USE_M17N ++	    else { ++		for (i++; i < COLS && CHMODE(pr[i]) == C_WCHAR2; i++) ++		    touch_column(i); ++	    } ++#endif ++	} ++    } ++ ++#ifdef USE_M17N ++    if (CurColumn + width > COLS) { ++	touch_line(); ++	for (i = CurColumn; i < COLS; i++) { ++	    SETCH(p[i], SPACE, 1); ++	    SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII); ++	    touch_column(i); ++	} ++	wrap(); ++	if (CurColumn + width > COLS) ++	    return; ++	p = ScreenImage[CurLine]->lineimage; ++	pr = ScreenImage[CurLine]->lineprop; ++    } ++    if (CHMODE(pr[CurColumn]) == C_WCHAR2) { ++	touch_line(); ++	for (i = CurColumn - 1; i >= 0; i--) { ++	    l_prop l = CHMODE(pr[i]); ++	    SETCH(p[i], SPACE, 1); ++	    SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII); ++	    touch_column(i); ++	    if (l != C_WCHAR2) ++		break; ++	} ++    } ++#endif ++    if (CHMODE(CurrentMode) != C_CTRL) { ++	if (need_redraw(p[CurColumn], pr[CurColumn], pc, CurrentMode)) { ++	    SETCH(p[CurColumn], pc, len); ++	    SETPROP(pr[CurColumn], CurrentMode); ++	    touch_line(); ++	    touch_column(CurColumn); ++#ifdef USE_M17N ++	    SETCHMODE(CurrentMode, C_WCHAR2); ++	    for (i = CurColumn + 1; i < CurColumn + width; i++) { ++		SETCH(p[i], SPACE, 1); ++		SETPROP(pr[i], (pr[CurColumn] & ~C_WHICHCHAR) | C_WCHAR2); ++		touch_column(i); ++	    } ++	    for (; i < COLS && CHMODE(pr[i]) == C_WCHAR2; i++) { ++		SETCH(p[i], SPACE, 1); ++		SETPROP(pr[i], (pr[i] & ~C_WHICHCHAR) | C_ASCII); ++		touch_column(i); ++	    } ++	} ++	CurColumn += width; ++#else ++	} ++	CurColumn++; ++#endif ++    } ++    else if (c == '\t') { ++	dest = (CurColumn + tab_step) / tab_step * tab_step; ++	if (dest >= COLS) { ++	    wrap(); ++	    touch_line(); ++	    dest = tab_step; ++	    p = ScreenImage[CurLine]->lineimage; ++	    pr = ScreenImage[CurLine]->lineprop; ++	} ++	for (i = CurColumn; i < dest; i++) { ++	    if (need_redraw(p[i], pr[i], SPACE, CurrentMode)) { ++		SETCH(p[i], SPACE, 1); ++		SETPROP(pr[i], CurrentMode); ++		touch_line(); ++		touch_column(i); ++	    } ++	} ++	CurColumn = i; ++    } ++    else if (c == '\n') { ++	wrap(); ++    } ++    else if (c == '\r') {	/* Carriage return */ ++	CurColumn = 0; ++    } ++    else if (c == '\b' && CurColumn > 0) {	/* Backspace */ ++	CurColumn--; ++#ifdef USE_M17N ++	while (CurColumn > 0 && CHMODE(pr[CurColumn]) == C_WCHAR2) ++	    CurColumn--; ++#endif ++    } ++} ++ ++void ++wrap(void) ++{ ++    if (CurLine == LASTLINE) ++	return; ++    CurLine++; ++    CurColumn = 0; ++} ++ ++void ++touch_column(int col) ++{ ++    if (col >= 0 && col < COLS) ++	ScreenImage[CurLine]->lineprop[col] |= S_DIRTY; ++} ++ ++void ++touch_line(void) ++{ ++    if (!(ScreenImage[CurLine]->isdirty & L_DIRTY)) { ++	int i; ++	for (i = 0; i < COLS; i++) ++	    ScreenImage[CurLine]->lineprop[i] &= ~S_DIRTY; ++	ScreenImage[CurLine]->isdirty |= L_DIRTY; ++    } ++ ++} ++ ++void ++standout(void) ++{ ++    CurrentMode |= S_STANDOUT; ++} ++ ++void ++standend(void) ++{ ++    CurrentMode &= ~S_STANDOUT; ++} ++ ++void ++toggle_stand(void) ++{ ++#ifdef USE_M17N ++    int i; ++#endif ++    l_prop *pr = ScreenImage[CurLine]->lineprop; ++    pr[CurColumn] ^= S_STANDOUT; ++#ifdef USE_M17N ++    if (CHMODE(pr[CurColumn]) != C_WCHAR2) { ++	for (i = CurColumn + 1; CHMODE(pr[i]) == C_WCHAR2; i++) ++	    pr[i] ^= S_STANDOUT; ++    } ++#endif ++} ++ ++void ++bold(void) ++{ ++    CurrentMode |= S_BOLD; ++} ++ ++void ++boldend(void) ++{ ++    CurrentMode &= ~S_BOLD; ++} ++ ++void ++underline(void) ++{ ++    CurrentMode |= S_UNDERLINE; ++} ++ ++void ++underlineend(void) ++{ ++    CurrentMode &= ~S_UNDERLINE; ++} ++ ++void ++graphstart(void) ++{ ++    CurrentMode |= S_GRAPHICS; ++} ++ ++void ++graphend(void) ++{ ++    CurrentMode &= ~S_GRAPHICS; ++} ++ ++int ++graph_ok(void) ++{ ++    if (!UseGraphicChar) ++	return 0; ++    return T_as[0] != 0 && T_ae[0] != 0 && T_ac[0] != 0; ++} ++ ++void ++setfcolor(int color) ++{ ++    CurrentMode &= ~COL_FCOLOR; ++    if ((color & 0xf) <= 7) ++	CurrentMode |= (((color & 7) | 8) << 8); ++} ++ ++static char * ++color_seq(int colmode) ++{ ++    static char seqbuf[32]; ++    sprintf(seqbuf, "\033[%dm", ((colmode >> 8) & 7) + 30); ++    return seqbuf; ++} ++ ++#ifdef USE_BG_COLOR ++void ++setbcolor(int color) ++{ ++    CurrentMode &= ~COL_BCOLOR; ++    if ((color & 0xf) <= 7) ++	CurrentMode |= (((color & 7) | 8) << 12); ++} ++ ++static char * ++bcolor_seq(int colmode) ++{ ++    static char seqbuf[32]; ++    sprintf(seqbuf, "\033[%dm", ((colmode >> 12) & 7) + 40); ++    return seqbuf; ++} ++#endif				/* USE_BG_COLOR */ ++ ++#define RF_NEED_TO_MOVE    0 ++#define RF_CR_OK           1 ++#define RF_NONEED_TO_MOVE  2 ++#ifdef USE_BG_COLOR ++#define M_MEND (S_STANDOUT|S_UNDERLINE|S_BOLD|S_COLORED|S_BCOLORED|S_GRAPHICS) ++#else				/* not USE_BG_COLOR */ ++#define M_MEND (S_STANDOUT|S_UNDERLINE|S_BOLD|S_COLORED|S_GRAPHICS) ++#endif				/* not USE_BG_COLOR */ ++void ++refresh(void) ++{ ++    int line, col, pcol; ++    int pline = CurLine; ++    int moved = RF_NEED_TO_MOVE; ++#ifdef USE_M17N ++    char **pc; ++#else ++    char *pc; ++#endif ++    l_prop *pr, mode = 0; ++    l_prop color = COL_FTERM; ++#ifdef USE_BG_COLOR ++    l_prop bcolor = COL_BTERM; ++#endif				/* USE_BG_COLOR */ ++    short *dirty; ++ ++#ifdef USE_M17N ++    wc_putc_init(InnerCharset, DisplayCharset); ++#endif ++    for (line = 0; line <= LASTLINE; line++) { ++	dirty = &ScreenImage[line]->isdirty; ++	if (*dirty & L_DIRTY) { ++	    *dirty &= ~L_DIRTY; ++	    pc = ScreenImage[line]->lineimage; ++	    pr = ScreenImage[line]->lineprop; ++	    for (col = 0; col < COLS && !(pr[col] & S_EOL); col++) { ++		if (*dirty & L_NEED_CE && col >= ScreenImage[line]->eol) { ++		    if (need_redraw(pc[col], pr[col], SPACE, 0)) ++			break; ++		} ++		else { ++		    if (pr[col] & S_DIRTY) ++			break; ++		} ++	    } ++	    if (*dirty & (L_NEED_CE | L_CLRTOEOL)) { ++		pcol = ScreenImage[line]->eol; ++		if (pcol >= COLS) { ++		    *dirty &= ~(L_NEED_CE | L_CLRTOEOL); ++		    pcol = col; ++		} ++	    } ++	    else { ++		pcol = col; ++	    } ++	    if (line < LINES - 2 && pline == line - 1 && pcol == 0) { ++		switch (moved) { ++		case RF_NEED_TO_MOVE: ++		    MOVE(line, 0); ++		    moved = RF_CR_OK; ++		    break; ++		case RF_CR_OK: ++		    write1('\n'); ++		    write1('\r'); ++		    break; ++		case RF_NONEED_TO_MOVE: ++		    moved = RF_CR_OK; ++		    break; ++		} ++	    } ++	    else { ++		MOVE(line, pcol); ++		moved = RF_CR_OK; ++	    } ++	    if (*dirty & (L_NEED_CE | L_CLRTOEOL)) { ++		writestr(T_ce); ++		if (col != pcol) ++		    MOVE(line, col); ++	    } ++	    pline = line; ++	    pcol = col; ++	    for (; col < COLS; col++) { ++		if (pr[col] & S_EOL) ++		    break; ++ ++		/*  ++		 * some terminal emulators do linefeed when a ++		 * character is put on COLS-th column. this behavior ++		 * is different from one of vt100, but such terminal ++		 * emulators are used as vt100-compatible ++		 * emulators. This behaviour causes scroll when a ++		 * character is drawn on (COLS-1,LINES-1) point.  To ++		 * avoid the scroll, I prohibit to draw character on ++		 * (COLS-1,LINES-1). ++		 */ ++#if !defined(USE_BG_COLOR) || defined(__CYGWIN__) ++#ifdef __CYGWIN__ ++		if (isWinConsole) ++#endif ++		    if (line == LINES - 1 && col == COLS - 1) ++			break; ++#endif				/* !defined(USE_BG_COLOR) || defined(__CYGWIN__) */ ++		if ((!(pr[col] & S_STANDOUT) && (mode & S_STANDOUT)) || ++		    (!(pr[col] & S_UNDERLINE) && (mode & S_UNDERLINE)) || ++		    (!(pr[col] & S_BOLD) && (mode & S_BOLD)) || ++		    (!(pr[col] & S_COLORED) && (mode & S_COLORED)) ++#ifdef USE_BG_COLOR ++		    || (!(pr[col] & S_BCOLORED) && (mode & S_BCOLORED)) ++#endif				/* USE_BG_COLOR */ ++		    || (!(pr[col] & S_GRAPHICS) && (mode & S_GRAPHICS))) { ++		    if ((mode & S_COLORED) ++#ifdef USE_BG_COLOR ++			|| (mode & S_BCOLORED) ++#endif				/* USE_BG_COLOR */ ++			) ++			writestr(T_op); ++		    if (mode & S_GRAPHICS) ++			writestr(T_ae); ++		    writestr(T_me); ++		    mode &= ~M_MEND; ++		} ++		if ((*dirty & L_NEED_CE && col >= ScreenImage[line]->eol) ? ++		    need_redraw(pc[col], pr[col], SPACE, ++				0) : (pr[col] & S_DIRTY)) { ++		    if (pcol == col - 1) ++			writestr(T_nd); ++		    else if (pcol != col) ++			MOVE(line, col); ++ ++		    if ((pr[col] & S_STANDOUT) && !(mode & S_STANDOUT)) { ++			writestr(T_so); ++			mode |= S_STANDOUT; ++		    } ++		    if ((pr[col] & S_UNDERLINE) && !(mode & S_UNDERLINE)) { ++			writestr(T_us); ++			mode |= S_UNDERLINE; ++		    } ++		    if ((pr[col] & S_BOLD) && !(mode & S_BOLD)) { ++			writestr(T_md); ++			mode |= S_BOLD; ++		    } ++		    if ((pr[col] & S_COLORED) && (pr[col] ^ mode) & COL_FCOLOR) { ++			color = (pr[col] & COL_FCOLOR); ++			mode = ((mode & ~COL_FCOLOR) | color); ++			writestr(color_seq(color)); ++		    } ++#ifdef USE_BG_COLOR ++		    if ((pr[col] & S_BCOLORED) ++			&& (pr[col] ^ mode) & COL_BCOLOR) { ++			bcolor = (pr[col] & COL_BCOLOR); ++			mode = ((mode & ~COL_BCOLOR) | bcolor); ++			writestr(bcolor_seq(bcolor)); ++		    } ++#endif				/* USE_BG_COLOR */ ++		    if ((pr[col] & S_GRAPHICS) && !(mode & S_GRAPHICS)) { ++#ifdef USE_M17N ++			wc_putc_end(ttyf); ++#endif ++			if (!graph_enabled) { ++			    graph_enabled = 1; ++			    writestr(T_eA); ++			} ++			writestr(T_as); ++			mode |= S_GRAPHICS; ++		    } ++#ifdef USE_M17N ++		    if (pr[col] & S_GRAPHICS) ++			write1(graphchar(*pc[col])); ++		    else if (CHMODE(pr[col]) != C_WCHAR2) ++			wc_putc(pc[col], ttyf); ++#else ++		    write1((pr[col] & S_GRAPHICS) ? graphchar(pc[col]) : ++			   pc[col]); ++#endif ++		    pcol = col + 1; ++		} ++	    } ++	    if (col == COLS) ++		moved = RF_NEED_TO_MOVE; ++	    for (; col < COLS && !(pr[col] & S_EOL); col++) ++		pr[col] |= S_EOL; ++	} ++	*dirty &= ~(L_NEED_CE | L_CLRTOEOL); ++	if (mode & M_MEND) { ++	    if (mode & (S_COLORED ++#ifdef USE_BG_COLOR ++			| S_BCOLORED ++#endif				/* USE_BG_COLOR */ ++		)) ++		writestr(T_op); ++	    if (mode & S_GRAPHICS) { ++		writestr(T_ae); ++#ifdef USE_M17N ++		wc_putc_clear_status(); ++#endif ++	    } ++	    writestr(T_me); ++	    mode &= ~M_MEND; ++	} ++    } ++#ifdef USE_M17N ++    wc_putc_end(ttyf); ++#endif ++    MOVE(CurLine, CurColumn); ++    flush_tty(); ++} ++ ++void ++clear(void) ++{ ++    int i, j; ++    l_prop *p; ++    writestr(T_cl); ++    move(0, 0); ++    for (i = 0; i < LINES; i++) { ++	ScreenImage[i]->isdirty = 0; ++	p = ScreenImage[i]->lineprop; ++	for (j = 0; j < COLS; j++) { ++	    p[j] = S_EOL; ++	} ++    } ++    CurrentMode = C_ASCII; ++} ++ ++#ifdef USE_RAW_SCROLL ++static void ++scroll_raw(void) ++{				/* raw scroll */ ++    MOVE(LINES - 1, 0); ++    write1('\n'); ++} ++ ++void ++scroll(int n) ++{				/* scroll up */ ++    int cli = CurLine, cco = CurColumn; ++    Screen *t; ++    int i, j, k; ++ ++    i = LINES; ++    j = n; ++    do { ++	k = j; ++	j = i % k; ++	i = k; ++    } while (j); ++    do { ++	k--; ++	i = k; ++	j = (i + n) % LINES; ++	t = ScreenImage[k]; ++	while (j != k) { ++	    ScreenImage[i] = ScreenImage[j]; ++	    i = j; ++	    j = (i + n) % LINES; ++	} ++	ScreenImage[i] = t; ++    } while (k); ++ ++    for (i = 0; i < n; i++) { ++	t = ScreenImage[LINES - 1 - i]; ++	t->isdirty = 0; ++	for (j = 0; j < COLS; j++) ++	    t->lineprop[j] = S_EOL; ++	scroll_raw(); ++    } ++    move(cli, cco); ++} ++ ++void ++rscroll(int n) ++{				/* scroll down */ ++    int cli = CurLine, cco = CurColumn; ++    Screen *t; ++    int i, j, k; ++ ++    i = LINES; ++    j = n; ++    do { ++	k = j; ++	j = i % k; ++	i = k; ++    } while (j); ++    do { ++	k--; ++	i = k; ++	j = (LINES + i - n) % LINES; ++	t = ScreenImage[k]; ++	while (j != k) { ++	    ScreenImage[i] = ScreenImage[j]; ++	    i = j; ++	    j = (LINES + i - n) % LINES; ++	} ++	ScreenImage[i] = t; ++    } while (k); ++    if (T_sr && *T_sr) { ++	MOVE(0, 0); ++	for (i = 0; i < n; i++) { ++	    t = ScreenImage[i]; ++	    t->isdirty = 0; ++	    for (j = 0; j < COLS; j++) ++		t->lineprop[j] = S_EOL; ++	    writestr(T_sr); ++	} ++	move(cli, cco); ++    } ++    else { ++	for (i = 0; i < LINES; i++) { ++	    t = ScreenImage[i]; ++	    t->isdirty |= L_DIRTY | L_NEED_CE; ++	    for (j = 0; j < COLS; j++) { ++		t->lineprop[j] |= S_DIRTY; ++	    } ++	} ++    } ++} ++#endif ++ ++#if 0 ++void ++need_clrtoeol(void) ++{ ++    /* Clear to the end of line as the need arises */ ++    l_prop *lprop = ScreenImage[CurLine]->lineprop; ++ ++    if (lprop[CurColumn] & S_EOL) ++	return; ++ ++    if (!(ScreenImage[CurLine]->isdirty & (L_NEED_CE | L_CLRTOEOL)) || ++	ScreenImage[CurLine]->eol > CurColumn) ++	ScreenImage[CurLine]->eol = CurColumn; ++ ++    ScreenImage[CurLine]->isdirty |= L_NEED_CE; ++} ++#endif				/* 0 */ ++ ++/* XXX: conflicts with curses's clrtoeol(3) ? */ ++void ++clrtoeol(void) ++{				/* Clear to the end of line */ ++    int i; ++    l_prop *lprop = ScreenImage[CurLine]->lineprop; ++ ++    if (lprop[CurColumn] & S_EOL) ++	return; ++ ++    if (!(ScreenImage[CurLine]->isdirty & (L_NEED_CE | L_CLRTOEOL)) || ++	ScreenImage[CurLine]->eol > CurColumn) ++	ScreenImage[CurLine]->eol = CurColumn; ++ ++    ScreenImage[CurLine]->isdirty |= L_CLRTOEOL; ++    touch_line(); ++    for (i = CurColumn; i < COLS && !(lprop[i] & S_EOL); i++) { ++	lprop[i] = S_EOL | S_DIRTY; ++    } ++} ++ ++#ifdef USE_BG_COLOR ++void ++clrtoeol_with_bcolor(void) ++{ ++    int i, cli, cco; ++    l_prop pr; ++ ++    if (!(CurrentMode & S_BCOLORED)) { ++	clrtoeol(); ++	return; ++    } ++    cli = CurLine; ++    cco = CurColumn; ++    pr = CurrentMode; ++    CurrentMode = (CurrentMode & (M_CEOL | S_BCOLORED)) | C_ASCII; ++    for (i = CurColumn; i < COLS; i++) ++	addch(' '); ++    move(cli, cco); ++    CurrentMode = pr; ++} ++ ++void ++clrtoeolx(void) ++{ ++    clrtoeol_with_bcolor(); ++} ++#else				/* not USE_BG_COLOR */ ++ ++void ++clrtoeolx(void) ++{ ++    clrtoeol(); ++} ++#endif				/* not USE_BG_COLOR */ ++ ++void ++clrtobot_eol(void (*clrtoeol) ()) ++{ ++    int l, c; ++ ++    l = CurLine; ++    c = CurColumn; ++    (*clrtoeol) (); ++    CurColumn = 0; ++    CurLine++; ++    for (; CurLine < LINES; CurLine++) ++	(*clrtoeol) (); ++    CurLine = l; ++    CurColumn = c; ++} ++ ++void ++clrtobot(void) ++{ ++    clrtobot_eol(clrtoeol); ++} ++ ++void ++clrtobotx(void) ++{ ++    clrtobot_eol(clrtoeolx); ++} ++ ++#if 0 ++void ++no_clrtoeol(void) ++{ ++    int i; ++    l_prop *lprop = ScreenImage[CurLine]->lineprop; ++ ++    ScreenImage[CurLine]->isdirty &= ~L_CLRTOEOL; ++} ++#endif				/* 0 */ ++ ++void ++addstr(char *s) ++{ ++#ifdef USE_M17N ++    int len; ++ ++    while (*s != '\0') { ++	len = wtf_len((wc_uchar *) s); ++	addmch(s, len); ++	s += len; ++    } ++#else ++    while (*s != '\0') ++	addch(*(s++)); ++#endif ++} ++ ++void ++addnstr(char *s, int n) ++{ ++    int i; ++#ifdef USE_M17N ++    int len, width; ++ ++    for (i = 0; *s != '\0';) { ++	width = wtf_width((wc_uchar *) s); ++	if (i + width > n) ++	    break; ++	len = wtf_len((wc_uchar *) s); ++	addmch(s, len); ++	s += len; ++	i += width; ++    } ++#else ++    for (i = 0; i < n && *s != '\0'; i++) ++	addch(*(s++)); ++#endif ++} ++ ++void ++addnstr_sup(char *s, int n) ++{ ++    int i; ++#ifdef USE_M17N ++    int len, width; ++ ++    for (i = 0; *s != '\0';) { ++	width = wtf_width((wc_uchar *) s); ++	if (i + width > n) ++	    break; ++	len = wtf_len((wc_uchar *) s); ++	addmch(s, len); ++	s += len; ++	i += width; ++    } ++#else ++    for (i = 0; i < n && *s != '\0'; i++) ++	addch(*(s++)); ++#endif ++    for (; i < n; i++) ++	addch(' '); ++} ++ ++void ++crmode(void) ++#ifndef HAVE_SGTTY_H ++{ ++    ttymode_reset(ICANON, IXON); ++    ttymode_set(ISIG, 0); ++#ifdef HAVE_TERMIOS_H ++    set_cc(VMIN, 1); ++#else				/* not HAVE_TERMIOS_H */ ++    set_cc(VEOF, 1); ++#endif				/* not HAVE_TERMIOS_H */ ++} ++#else				/* HAVE_SGTTY_H */ ++{ ++    ttymode_set(CBREAK, 0); ++} ++#endif				/* HAVE_SGTTY_H */ ++ ++void ++nocrmode(void) ++#ifndef HAVE_SGTTY_H ++{ ++    ttymode_set(ICANON, 0); ++#ifdef HAVE_TERMIOS_H ++    set_cc(VMIN, 4); ++#else				/* not HAVE_TERMIOS_H */ ++    set_cc(VEOF, 4); ++#endif				/* not HAVE_TERMIOS_H */ ++} ++#else				/* HAVE_SGTTY_H */ ++{ ++    ttymode_reset(CBREAK, 0); ++} ++#endif				/* HAVE_SGTTY_H */ ++ ++void ++term_echo(void) ++{ ++    ttymode_set(ECHO, 0); ++} ++ ++void ++term_noecho(void) ++{ ++    ttymode_reset(ECHO, 0); ++} ++ ++void ++term_raw(void) ++#ifndef HAVE_SGTTY_H ++#ifdef IEXTEN ++#define TTY_MODE ISIG|ICANON|ECHO|IEXTEN ++#else				/* not IEXTEN */ ++#define TTY_MODE ISIG|ICANON|ECHO ++#endif				/* not IEXTEN */ ++{ ++    ttymode_reset(TTY_MODE, IXON | IXOFF); ++#ifdef HAVE_TERMIOS_H ++    set_cc(VMIN, 1); ++#else				/* not HAVE_TERMIOS_H */ ++    set_cc(VEOF, 1); ++#endif				/* not HAVE_TERMIOS_H */ ++} ++#else				/* HAVE_SGTTY_H */ ++{ ++    ttymode_set(RAW, 0); ++} ++#endif				/* HAVE_SGTTY_H */ ++ ++void ++term_cooked(void) ++#ifndef HAVE_SGTTY_H ++{ ++#ifdef __EMX__ ++    /* On XFree86/OS2, some scrambled characters ++     * will appear when asserting IEXTEN flag. ++     */ ++    ttymode_set((TTY_MODE) & ~IEXTEN, 0); ++#else ++    ttymode_set(TTY_MODE, 0); ++#endif ++#ifdef HAVE_TERMIOS_H ++    set_cc(VMIN, 4); ++#else				/* not HAVE_TERMIOS_H */ ++    set_cc(VEOF, 4); ++#endif				/* not HAVE_TERMIOS_H */ ++} ++#else				/* HAVE_SGTTY_H */ ++{ ++    ttymode_reset(RAW, 0); ++} ++#endif				/* HAVE_SGTTY_H */ ++ ++void ++term_cbreak(void) ++{ ++    term_cooked(); ++    term_noecho(); ++} ++ ++void ++term_title(char *s) ++{ ++    if (!fmInitialized) ++        return; ++    if (title_str != NULL) { ++#ifdef __CYGWIN__ ++	if (isLocalConsole && title_str == CYGWIN_TITLE) { ++	    Str buff; ++	    buff = Sprintf(title_str, s); ++	    if (buff->length > 1024) { ++		Strtruncate(buff, 1024); ++	    } ++	    SetConsoleTitle(buff->ptr); ++	} ++	else if (isLocalConsole || !isWinConsole) ++#endif ++        fprintf(ttyf, title_str, s); ++    } ++} ++ ++char ++getch(void) ++{ ++    char c; ++ ++    while ( ++#ifdef SUPPORT_WIN9X_CONSOLE_MBCS ++	      read_win32_console(&c, 1) ++#else ++	      read(tty, &c, 1) ++#endif ++	      < (int)1) { ++	if (errno == EINTR || errno == EAGAIN) ++	    continue; ++	/* error happend on read(2) */ ++	quitfm(); ++	break;			/* unreachable */ ++    } ++    return c; ++} ++ ++#ifdef USE_MOUSE ++#ifdef USE_GPM ++char ++wgetch(void *p) ++{ ++    char c; ++ ++    /* 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; ++} ++ ++int ++do_getch() ++{ ++    if (is_xterm) ++	return getch(); ++    else ++	return Gpm_Getch(); ++} ++#endif				/* USE_GPM */ ++ ++#ifdef USE_SYSMOUSE ++int ++sysm_getch() ++{ ++    fd_set rfd; ++    int key, x, y; ++ ++    FD_ZERO(&rfd); ++    FD_SET(tty, &rfd); ++    while (select(tty + 1, &rfd, NULL, NULL, NULL) <= 0) { ++	if (errno == EINTR) { ++	    x = xpix / cwidth; ++	    y = ypix / cheight; ++	    key = (*sysm_handler) (x, y, nbs, obs); ++	    if (key != 0) ++		return key; ++	} ++    } ++    return getch(); ++} ++ ++int ++do_getch() ++{ ++    if (is_xterm || !sysm_handler) ++	return getch(); ++    else ++	return sysm_getch(); ++} ++ ++MySignalHandler ++sysmouse(SIGNAL_ARG) ++{ ++    struct mouse_info mi; ++ ++    mi.operation = MOUSE_GETINFO; ++    if (ioctl(tty, CONS_MOUSECTL, &mi) == -1) ++	return; ++    xpix = mi.u.data.x; ++    ypix = mi.u.data.y; ++    obs = nbs; ++    nbs = mi.u.data.buttons & 0x7; ++    /* for cosmetic bug in syscons.c on FreeBSD 3.[34] */ ++    mi.operation = MOUSE_HIDE; ++    ioctl(tty, CONS_MOUSECTL, &mi); ++    mi.operation = MOUSE_SHOW; ++    ioctl(tty, CONS_MOUSECTL, &mi); ++} ++#endif				/* USE_SYSMOUSE */ ++#endif				/* USE_MOUSE */ ++ ++void ++bell(void) ++{ ++    write1(7); ++} ++ ++void ++skip_escseq(void) ++{ ++    int c; ++ ++    c = getch(); ++    if (c == '[' || c == 'O') { ++	c = getch(); ++#ifdef USE_MOUSE ++	if (is_xterm && c == 'M') { ++	    getch(); ++	    getch(); ++	    getch(); ++	} ++	else ++#endif ++	    while (IS_DIGIT(c)) ++		c = getch(); ++    } ++} ++ ++int ++sleep_till_anykey(int sec, int purge) ++{ ++    fd_set rfd; ++    struct timeval tim; ++    int er, c, ret; ++    TerminalMode ioval; ++ ++    TerminalGet(tty, &ioval); ++    term_raw(); ++ ++    tim.tv_sec = sec; ++    tim.tv_usec = 0; ++ ++    FD_ZERO(&rfd); ++    FD_SET(tty, &rfd); ++ ++    ret = select(tty + 1, &rfd, 0, 0, &tim); ++    if (ret > 0 && purge) { ++	c = getch(); ++	if (c == ESC_CODE) ++	    skip_escseq(); ++    } ++    er = TerminalSet(tty, &ioval); ++    if (er == -1) { ++	printf("Error occured: errno=%d\n", errno); ++	reset_exit(SIGNAL_ARGLIST); ++    } ++    return ret; ++} ++ ++#ifdef USE_MOUSE ++ ++#define XTERM_ON   {fputs("\033[?1001s\033[?1000h",ttyf); flush_tty();} ++#define XTERM_OFF  {fputs("\033[?1000l\033[?1001r",ttyf); flush_tty();} ++#define CYGWIN_ON  {fputs("\033[?1000h",ttyf); flush_tty();} ++#define CYGWIN_OFF {fputs("\033[?1000l",ttyf); flush_tty();} ++ ++#ifdef USE_GPM ++/* Linux console with GPM support */ ++ ++void ++mouse_init() ++{ ++    Gpm_Connect conn; ++    extern int gpm_process_mouse(Gpm_Event *, void *); ++    int r; ++ ++    if (mouseActive) ++	return; ++    conn.eventMask = ~0; ++    conn.defaultMask = 0; ++    conn.maxMod = 0; ++    conn.minMod = 0; ++ ++    r = Gpm_Open(&conn, 0); ++    if (r == -2) { ++	/* ++	 * If Gpm_Open() success, returns >= 0 ++	 * Gpm_Open() returns -2 in case of xterm. ++	 * Gpm_Close() is necessary here. Otherwise, ++	 * xterm is being left in the mode where the mouse clicks are ++	 * passed through to the application. ++	 */ ++	Gpm_Close(); ++	is_xterm = (NEED_XTERM_ON | NEED_XTERM_OFF); ++    } ++    else if (r >= 0) { ++	gpm_handler = gpm_process_mouse; ++	is_xterm = 0; ++    } ++    if (is_xterm) { ++	XTERM_ON; ++    } ++    mouseActive = 1; ++} ++ ++void ++mouse_end() ++{ ++    if (mouseActive == 0) ++	return; ++    if (is_xterm) { ++	XTERM_OFF; ++    } ++    else ++	Gpm_Close(); ++    mouseActive = 0; ++} ++ ++#elif	defined(USE_SYSMOUSE) ++/* *BSD console with sysmouse support */ ++void ++mouse_init() ++{ ++    mouse_info_t mi; ++    extern int sysm_process_mouse(); ++ ++    if (mouseActive) ++	return; ++    if (is_xterm) { ++	XTERM_ON; ++    } ++    else { ++#if defined(FBIO_MODEINFO) || defined(CONS_MODEINFO)	/* FreeBSD > 2.x */ ++#ifndef FBIO_GETMODE		/* FreeBSD 3.x */ ++#define FBIO_GETMODE    CONS_GET ++#define FBIO_MODEINFO   CONS_MODEINFO ++#endif				/* FBIO_GETMODE */ ++	video_info_t vi; ++ ++	if (ioctl(tty, FBIO_GETMODE, &vi.vi_mode) != -1 && ++	    ioctl(tty, FBIO_MODEINFO, &vi) != -1) { ++	    cwidth = vi.vi_cwidth; ++	    cheight = vi.vi_cheight; ++	} ++#endif				/* defined(FBIO_MODEINFO) || ++				 * defined(CONS_MODEINFO) */ ++	mySignal(SIGUSR2, SIG_IGN); ++	mi.operation = MOUSE_MODE; ++	mi.u.mode.mode = 0; ++	mi.u.mode.signal = SIGUSR2; ++	sysm_handler = NULL; ++	if (ioctl(tty, CONS_MOUSECTL, &mi) != -1) { ++	    mySignal(SIGUSR2, sysmouse); ++	    mi.operation = MOUSE_SHOW; ++	    ioctl(tty, CONS_MOUSECTL, &mi); ++	    sysm_handler = sysm_process_mouse; ++	} ++    } ++    mouseActive = 1; ++} ++ ++void ++mouse_end() ++{ ++    if (mouseActive == 0) ++	return; ++    if (is_xterm) { ++	XTERM_OFF; ++    } ++    else { ++	mouse_info_t mi; ++	mi.operation = MOUSE_MODE; ++	mi.u.mode.mode = 0; ++	mi.u.mode.signal = 0; ++	ioctl(tty, CONS_MOUSECTL, &mi); ++    } ++    mouseActive = 0; ++} ++ ++#else ++/* not GPM nor SYSMOUSE, but use mouse with xterm */ ++ ++void ++mouse_init() ++{ ++    if (mouseActive) ++	return; ++    if (is_xterm & NEED_XTERM_ON) { ++	XTERM_ON; ++    } ++#ifdef __CYGWIN__ ++    else if (is_xterm & NEED_CYGWIN_ON) { ++	CYGWIN_ON; ++    } ++#endif ++    mouseActive = 1; ++} ++ ++void ++mouse_end() ++{ ++    if (mouseActive == 0) ++	return; ++    if (is_xterm & NEED_XTERM_OFF) { ++	XTERM_OFF; ++    } ++#ifdef __CYGWIN__ ++    else if (is_xterm & NEED_CYGWIN_OFF) { ++	CYGWIN_OFF; ++    } ++#endif ++    mouseActive = 0; ++} ++ ++#endif				/* not USE_GPM nor USE_SYSMOUSE */ ++ ++ ++void ++mouse_active() ++{ ++    if (!mouseActive) ++	mouse_init(); ++} ++ ++void ++mouse_inactive() ++{ ++    if (mouseActive && is_xterm) ++	mouse_end(); ++} ++ ++#endif				/* USE_MOUSE */ ++ ++void ++flush_tty() ++{ ++    if (ttyf) ++	fflush(ttyf); ++} ++ ++#ifdef USE_IMAGE ++void ++touch_cursor() ++{ ++#ifdef USE_M17N ++    int i; ++#endif ++    touch_line(); ++#ifdef USE_M17N ++    for (i = CurColumn; i >= 0; i--) { ++	touch_column(i); ++	if (CHMODE(ScreenImage[CurLine]->lineprop[i]) != C_WCHAR2)  ++	    break; ++    } ++    for (i = CurColumn + 1; i < COLS; i++) { ++	if (CHMODE(ScreenImage[CurLine]->lineprop[i]) != C_WCHAR2)  ++	    break; ++	touch_column(i); ++    } ++#else ++    touch_column(CurColumn); ++#endif ++} ++#endif ++ ++#ifdef __MINGW32_VERSION ++ ++int tgetent(char *bp, char *name) ++{ ++  return 0; ++} ++ ++int tgetnum(char *id) ++{ ++  return -1; ++} ++ ++int tgetflag(char *id) ++{ ++  return 0; ++} ++ ++char *tgetstr(char *id, char **area) ++{ ++  id = ""; ++} ++ ++char *tgoto(char *cap, int col, int row) ++{ ++} ++ ++int tputs(char *str, int affcnt, int (*putc)(char)) ++{ ++} ++ ++char *ttyname(int tty) ++{ ++  return "CON"; ++} ++ ++#endif /* __MINGW32_VERSION */ diff --git a/debian/patches/120_config-file-handling.patch b/debian/patches/120_config-file-handling.patch new file mode 100644 index 0000000..ded2c85 --- /dev/null +++ b/debian/patches/120_config-file-handling.patch @@ -0,0 +1,38 @@ +Description: Fix segfault when changing options if ~/.w3m not accessible +Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=366284#5 +Author: Karsten Schoelzel <kuser@gmx.de> +Bug-Debian: http://bugs.debian.org/366284 + +diff --git a/rc.c b/rc.c +index 17f30d8..b88a3fd 100644 +--- a/rc.c ++++ b/rc.c +@@ -1253,7 +1253,7 @@ init_rc(void) + 	interpret_rc(f); + 	fclose(f); +     } +-    if ((f = fopen(config_file, "rt")) != NULL) { ++    if (config_file && (f = fopen(config_file, "rt")) != NULL) { + 	interpret_rc(f); + 	fclose(f); +     } +@@ -1265,6 +1265,8 @@ init_rc(void) + 	((tmp_dir = getenv("TMP")) == NULL || *tmp_dir == '\0') && + 	((tmp_dir = getenv("TEMP")) == NULL || *tmp_dir == '\0')) + 	tmp_dir = "/tmp"; ++    create_option_search_table(); ++    goto open_rc; + } +  +  +@@ -1446,8 +1448,8 @@ panel_set_option(struct parsed_tagarg *a +     FILE *f = NULL; +     char *p; +  +-    if (no_rc_dir) { +-	disp_message("There's no ~/.w3m directory... config not saved", FALSE); ++    if (config_file == NULL) { ++	disp_message("There's no config file... config not saved", FALSE); +     } +     else { + 	f = fopen(config_file, "wt"); diff --git a/debian/patches/130_rc-blank-line-fix.patch b/debian/patches/130_rc-blank-line-fix.patch new file mode 100644 index 0000000..b4c36c5 --- /dev/null +++ b/debian/patches/130_rc-blank-line-fix.patch @@ -0,0 +1,23 @@ +Description: Fix .w3m/config parser confused by blank lines +Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=537706#10 +Author: "Trent W. Buck" <twb@cybersource.com.au> +Bug-Debian: http://bugs.debian.org/537706 + +Index: w3m-0.5.2/rc.c +=================================================================== +--- w3m-0.5.2.orig/rc.c 2009-07-20 20:48:47.426565387 +1000 ++++ w3m-0.5.2/rc.c      2009-07-20 20:49:24.086565581 +1000 +@@ -1061,9 +1061,11 @@ +  +     for (;;) { + 	line = Strfgets(f); +-	Strchop(line); +-	if (line->length == 0) ++	if (line->length == 0)		/* end of file */ + 	    break; ++	Strchop(line); ++	if (line->length == 0)		/* blank line */ ++	    continue; + 	Strremovefirstspaces(line); + 	if (line->ptr[0] == '#')	/* comment */ + 	    continue; diff --git a/debian/patches/140_pseudo-inlines.patch b/debian/patches/140_pseudo-inlines.patch new file mode 100644 index 0000000..18cbea1 --- /dev/null +++ b/debian/patches/140_pseudo-inlines.patch @@ -0,0 +1,75 @@ +Description: New option "pseudo_inlines" + Add option pseudo_inlines (Display pseudo-ALTs for inline images with no + ALT or TITLE string) so + w3m -o pseudo_inlines=0 + works like + lynx -pseudo_inlines + If there is no ALT tag or it is "" and ignore_null_img_alt=1 then use TITLE + instead. +Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=329863#8 +Author: Karsten Schoelzel <kuser@gmx.de> +Bug-Debian: http://bugs.debian.org/329863 + +--- +commit 1c2e64c5ba38727f991c9787b95067391a4a0907 +tree 292b46472454ad69dee708029915cef0b0a718da +parent 1e6c13cac0c2954de5c377fe2120710c7c2b30fe +author Karsten Schoelzel <kuser@asus.karsten.local> Thu, 04 May 2006 13:05:03 +0200 +committer Karsten Schoelzel <kuser@asus.karsten.local> Thu, 04 May 2006 13:05:03 +0200 + + file.c |    7 +++++++ + fm.h   |    1 + + rc.c   |    3 +++ + 3 files changed, 11 insertions(+), 0 deletions(-) + +diff --git a/file.c b/file.c +index d067d47..913ac7c 100644 +--- a/file.c ++++ b/file.c +@@ -3171,6 +3171,13 @@ process_img(struct parsed_tag *tag, int  +     parsedtag_get_value(tag, ATTR_ALT, &q); +     t = q; +     parsedtag_get_value(tag, ATTR_TITLE, &t); ++    if (q == NULL || (*q == '\0' && ignore_null_img_alt)) { ++	if (!pseudoInlines && (t == NULL || ++			       (*t == '\0' && ignore_null_img_alt))) ++	    return tmp; ++	q = t; ++    } ++   +     w = -1; +     if (parsedtag_get_value(tag, ATTR_WIDTH, &w)) { + 	if (w < 0) { +diff --git a/fm.h b/fm.h +index a593a3f..e10c2a7 100644 +--- a/fm.h ++++ b/fm.h +@@ -926,6 +926,7 @@ global int image_map_list init(TRUE); + #else + global int displayImage init(FALSE);	/* XXX: emacs-w3m use display_image=off */ + #endif ++global int pseudoInlines init(TRUE); + global char *Editor init(DEF_EDITOR); + #ifdef USE_W3MMAILER + global char *Mailer init(NULL); +diff --git a/rc.c b/rc.c +index 2860a35..5d009bb 100644 +--- a/rc.c ++++ b/rc.c +@@ -76,6 +76,7 @@ static int OptionEncode = FALSE; + #define CMT_DECODE_URL   N_("Display decoded URL") + #define CMT_DISPLINEINFO N_("Display current line number") + #define CMT_DISP_IMAGE   N_("Display inline images") ++#define CMT_PSEUDO_INLINES N_("Display pseudo-ALTs for inline images with no ALT or TITLE string") + #ifdef USE_IMAGE + #define CMT_AUTO_IMAGE   N_("Load inline images automatically") + #define CMT_MAX_LOAD_IMAGE N_("Maximum processes for parallel image loading") +@@ -380,6 +381,8 @@ struct param_ptr params1[] = { +     /* XXX: emacs-w3m force to off display_image even if image options off */ +     {"display_image", P_INT, PI_ONOFF, (void *)&displayImage, CMT_DISP_IMAGE, +      NULL}, ++    {"pseudo_inlines", P_INT, PI_ONOFF, (void *)&pseudoInlines, ++     CMT_PSEUDO_INLINES, NULL}, + #ifdef USE_IMAGE +     {"auto_image", P_INT, PI_ONOFF, (void *)&autoImage, CMT_AUTO_IMAGE, NULL}, +     {"max_load_image", P_INT, PI_TEXT, (void *)&maxLoadImage, diff --git a/debian/patches/150_numbered-links.patch b/debian/patches/150_numbered-links.patch new file mode 100644 index 0000000..45e393a --- /dev/null +++ b/debian/patches/150_numbered-links.patch @@ -0,0 +1,163 @@ +Description: New option "display_link_number" +Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=329862#30 +Author: Karsten Schoelzel <kuser@gmx.de> +Bug-Debian: http://bugs.debian.org/329862 + +diff --git a/file.c b/file.c +index d537c8d..ea37647 100644 +--- a/file.c ++++ b/file.c +@@ -1671,6 +1678,12 @@ checkRedirection(ParsedURL *pu) +     return TRUE; + } +  ++Str ++getLinkNumberStr(int correction) ++{ ++    return Sprintf("[%d]", cur_hseq + correction); ++} ++ + /*  +  * loadGeneralFile: load file to buffer +  */ +@@ -3530,9 +3554,13 @@ process_input(struct parsed_tag *tag) +     case FORM_INPUT_TEXT: +     case FORM_INPUT_FILE: +     case FORM_INPUT_CHECKBOX: ++	if (displayLinkNumber) ++	    Strcat(tmp, getLinkNumberStr(0)); + 	Strcat_char(tmp, '['); + 	break; +     case FORM_INPUT_RADIO: ++	if (displayLinkNumber) ++	    Strcat(tmp, getLinkNumberStr(0)); + 	Strcat_char(tmp, '('); +     } +     Strcat(tmp, Sprintf("<input_alt hseq=\"%d\" fid=\"%d\" type=%s " +@@ -3573,6 +3601,8 @@ process_input(struct parsed_tag *tag) + 	case FORM_INPUT_SUBMIT: + 	case FORM_INPUT_BUTTON: + 	case FORM_INPUT_RESET: ++	    if (displayLinkNumber) ++		Strcat(tmp, getLinkNumberStr(-1)); + 	    Strcat_charp(tmp, "["); + 	    break; + 	} +@@ -3659,9 +3689,12 @@ process_select(struct parsed_tag *tag) +  + #ifdef MENU_SELECT +     if (!select_is_multiple) { +-	select_str = Sprintf("<pre_int>[<input_alt hseq=\"%d\" " ++	select_str = Strnew_charp("<pre_int>"); ++	if (displayLinkNumber) ++	    Strcat(select_str, getLinkNumberStr(0)); ++	Strcat(select_str, Sprintf("[<input_alt hseq=\"%d\" " + 			     "fid=\"%d\" type=select name=\"%s\" selectnumber=%d", +-			     cur_hseq++, cur_form_id, html_quote(p), n_select); ++			     cur_hseq++, cur_form_id, html_quote(p), n_select)); + 	Strcat_charp(select_str, ">"); + 	if (n_select == max_select) { + 	    max_select *= 2; +@@ -4688,6 +4721,8 @@ HTMLtagproc1(struct parsed_tag *tag, str + 	    obuf->anchor.hseq = cur_hseq; + 	    tmp = process_anchor(tag, h_env->tagbuf->ptr); + 	    push_tag(obuf, tmp->ptr, HTML_A); ++	    if (displayLinkNumber) ++		HTMLlineproc1(getLinkNumberStr(-1)->ptr, h_env); + 	    return 1; + 	} + 	return 0; +diff --git a/proto.h b/proto.h +index 8929580..6f02b5b 100644 +--- a/proto.h ++++ b/proto.h +@@ -776,6 +777,8 @@ extern void wrapToggle(void); + extern void saveBufferInfo(void); + #endif +  ++extern Str getLinkNumberStr(int correction); ++ + extern void dispVer(void); +  + #ifdef USE_INCLUDED_SRAND48 +diff --git a/rc.c b/rc.c +index f57b564..17f30d8 100644 +--- a/rc.c ++++ b/rc.c +@@ -72,6 +72,7 @@ static int OptionEncode = FALSE; + #define CMT_OPEN_TAB_BLANK N_("Open link on new tab if target is _blank or _new") + #define CMT_OPEN_TAB_DL_LIST N_("Open download list panel on new tab") + #define CMT_DISPLINK     N_("Display link URL automatically") ++#define CMT_DISPLINKNUMBER N_("Display link numbers") + #define CMT_DECODE_URL   N_("Display decoded URL") + #define CMT_DISPLINEINFO N_("Display current line number") + #define CMT_DISP_IMAGE   N_("Display inline images") +@@ -338,6 +357,8 @@ struct param_ptr params1[] = { +      CMT_OPEN_TAB_DL_LIST, NULL}, +     {"display_link", P_INT, PI_ONOFF, (void *)&displayLink, CMT_DISPLINK, +      NULL}, ++    {"display_link_number", P_INT, PI_ONOFF, (void *)&displayLinkNumber, ++     CMT_DISPLINKNUMBER, NULL}, +     {"decode_url", P_INT, PI_ONOFF, (void *)&DecodeURL, CMT_DECODE_URL, NULL}, +     {"display_lineinfo", P_INT, PI_ONOFF, (void *)&displayLineInfo, +      CMT_DISPLINEINFO, NULL}, +diff --git a/table.c b/table.c +index 2024632..94d61d6 100644 +--- a/table.c ++++ b/table.c +@@ -2937,6 +2937,12 @@ feed_table_tag(struct table *tbl, char * + 	    check_rowcol(tbl, mode); + 	    if (i == 0) { + 		Str tmp = process_anchor(tag, line); ++    		if (displayLinkNumber) ++		{ ++			Str t = getLinkNumberStr(-1); ++			feed_table_inline_tag(tbl, NULL, mode, t->length); ++			Strcat(tmp, t); ++		} + 		pushdata(tbl, tbl->row, tbl->col, tmp->ptr); + 	    } + 	    else +diff --git a/fm.h b/fm.h +index 8686866..1a1a60c 100644 +--- a/fm.h ++++ b/fm.h +@@ -909,6 +909,7 @@ global int label_topline init(FALSE); + global int nextpage_topline init(FALSE); + global char *displayTitleTerm init(NULL); + global int displayLink init(FALSE); ++global int displayLinkNumber init(FALSE); + global int displayLineInfo init(FALSE); + global int DecodeURL init(FALSE); + global int retryAsHttp init(TRUE); +diff --git a/main.c b/main.c +index 0d709ef..70c8c1d 100644 +--- a/main.c ++++ b/main.c +@@ -1239,8 +1239,25 @@ do_dump(Buffer *buf) + 	dump_head(buf); +     if (w3m_dump & DUMP_SOURCE) + 	dump_source(buf); +-    if (w3m_dump == DUMP_BUFFER) ++    if (w3m_dump == DUMP_BUFFER) { ++	int i; + 	saveBuffer(buf, stdout, FALSE); ++	if (displayLinkNumber && buf->href) { ++	    printf("\nReferences:\n\n"); ++	    for (i = 0; i < buf->href->nanchor; i++) { ++	        ParsedURL pu; ++	        static Str s = NULL; ++		if (buf->href->anchors[i].slave) ++		    continue; ++	        parseURL2(buf->href->anchors[i].url, &pu, baseURL(buf)); ++	        s = parsedURL2Str(&pu); ++    	        if (DecodeURL) ++		    s = Strnew_charp(url_unquote_conv ++				     (s->ptr, Currentbuf->document_charset)); ++	        printf("[%d] %s\n", buf->href->anchors[i].hseq + 1, s->ptr); ++	    } ++	} ++    } +     mySignal(SIGINT, prevtrap); + } +  diff --git a/debian/patches/160_tls-sni.patch b/debian/patches/160_tls-sni.patch new file mode 100644 index 0000000..0a2e83a --- /dev/null +++ b/debian/patches/160_tls-sni.patch @@ -0,0 +1,18 @@ +Description: Support for TLS SNI (Server Name Indication) +Origin: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=523159#5 +Author: Sascha Silbe <sascha-debian-bugs-w3m-1@silbe.org> +Bug-Debian: http://bugs.debian.org/523159 + +diff -ur w3m-0.5.2/url.c w3m-0.5.2-sni/url.c +--- w3m-0.5.2/url.c	2007-05-23 17:06:06.000000000 +0200 ++++ w3m-0.5.2-sni/url.c	2009-03-11 17:44:51.210620186 +0100 +@@ -374,6 +374,9 @@ + #if SSLEAY_VERSION_NUMBER >= 0x00905100 +     init_PRNG(); + #endif				/* SSLEAY_VERSION_NUMBER >= 0x00905100 */ ++#if (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT) ++    SSL_set_tlsext_host_name(handle,hostname); ++#endif				/* (SSLEAY_VERSION_NUMBER >= 0x00908070) && !defined(OPENSSL_NO_TLSEXT) */ +     if (SSL_connect(handle) > 0) { + 	Str serv_cert = ssl_get_certificate(handle, hostname); + 	if (serv_cert) { diff --git a/debian/patches/170_number-prefix.patch b/debian/patches/170_number-prefix.patch new file mode 100644 index 0000000..5ad5f13 --- /dev/null +++ b/debian/patches/170_number-prefix.patch @@ -0,0 +1,39 @@ +Description: Make number prefixes working when vi_prec_num=0 + * [w3m-dev 04271] vi_prec_num + * main.c: make number prefixes working when vi_prec_num=0. +Origin: upstream, http://w3m.cvs.sourceforge.net/viewvc/w3m/w3m/ +Author: Hironori Sakamoto <hsaka@mth.biglobe.ne.jp> + +diff -urN w3m-0.5.2.orig/main.c w3m/main.c +--- w3m-0.5.2.orig/main.c	2007-05-31 10:19:50.000000000 +0900 ++++ w3m/main.c	2007-06-04 22:21:10.000000000 +0900 +@@ -1,4 +1,4 @@ +-/* $Id: main.c,v 1.258 2007/05/31 01:19:50 inu Exp $ */ ++/* $Id: main.c,v 1.259 2007/06/04 13:21:10 inu Exp $ */ + #define MAINPROGRAM + #include "fm.h" + #include <signal.h> +@@ -1152,18 +1152,11 @@ + 	    mouse_inactive(); + #endif				/* USE_MOUSE */ + 	if (IS_ASCII(c)) {	/* Ascii */ +-	    if( vi_prec_num ){ +-		if(((prec_num && c == '0') || '1' <= c) && (c <= '9')) { +-		    prec_num = prec_num * 10 + (int)(c - '0'); +-		    if (prec_num > PREC_LIMIT) +-			prec_num = PREC_LIMIT; +-		} +-		else { +-		    set_buffer_environ(Currentbuf); +-		    save_buffer_position(Currentbuf); +-		    keyPressEventProc((int)c); +-		    prec_num = 0; +-		} ++	    if (('0' <= c) && (c <= '9') && ++		(prec_num || (GlobalKeymap[c] == FUNCNAME_nulcmd))) { ++		prec_num = prec_num * 10 + (int)(c - '0'); ++		if (prec_num > PREC_LIMIT) ++		   prec_num = PREC_LIMIT; + 	    } + 	    else { + 		set_buffer_environ(Currentbuf); diff --git a/debian/patches/180_non-xterm.patch b/debian/patches/180_non-xterm.patch new file mode 100644 index 0000000..a531e64 --- /dev/null +++ b/debian/patches/180_non-xterm.patch @@ -0,0 +1,32 @@ +Description: Fix segfault on non-xterm + * [w3m-dev 04278] Re: segfault on CentOS4.5/libgc6.8 + * term.c: add handling xterm-incompatible terminals without gpm. +Origin: upstream, http://w3m.cvs.sourceforge.net/viewvc/w3m/w3m/ +Author: Hironori Sakamoto <hsaka@mth.biglobe.ne.jp> + +diff -urN w3m-0.5.2.orig/terms.c w3m/terms.c +--- w3m-0.5.2.orig/terms.c	2007-05-30 13:44:00.000000000 +0900 ++++ w3m/terms.c	2007-06-07 19:54:10.000000000 +0900 +@@ -1,4 +1,4 @@ +-/* $Id: terms.c,v 1.57 2007/05/30 04:44:00 inu Exp $ */ ++/* $Id: terms.c,v 1.58 2007/06/07 10:54:10 inu Exp $ */ + /*  +  * An original curses library for EUC-kanji by Akinori ITO,     December 1989 +  * revised by Akinori ITO, January 1995 +@@ -1897,7 +1897,7 @@ + int + do_getch() + { +-    if (is_xterm) ++    if (is_xterm || !gpm_handler) + 	return getch(); +     else + 	return Gpm_Getch(); +@@ -2037,6 +2037,7 @@ +     conn.maxMod = 0; +     conn.minMod = 0; +  ++    gpm_handler = NULL; +     r = Gpm_Open(&conn, 0); +     if (r == -2) { + 	/* diff --git a/debian/patches/190_codepage.patch b/debian/patches/190_codepage.patch new file mode 100644 index 0000000..8e30d05 --- /dev/null +++ b/debian/patches/190_codepage.patch @@ -0,0 +1,196 @@ +Description: Handling of codepage with wc_codepage + * [w3m-dev 04279] charset + * libwc/ces.h, libwc/charset.c: set charset to Shift_JIS, when locale  +   is japanese, jp_JP.PCK, ja_JP.IBM-932, ja_JP.IBM-943, or windows-31j. +Origin: upstream, http://w3m.cvs.sourceforge.net/viewvc/w3m/w3m/ +Author: Hironori Sakamoto <hsaka@mth.biglobe.ne.jp> + +diff -urN w3m-0.5.2.orig/libwc/ces.h w3m/libwc/ces.h +--- w3m-0.5.2.orig/libwc/ces.h	2003-09-23 06:02:23.000000000 +0900 ++++ w3m/libwc/ces.h	2007-06-07 19:59:52.000000000 +0900 +@@ -176,6 +176,7 @@ +  + #define WC_CES_SHIFT_JIS	(WC_CES_E_PRIV2|WC_CES_N_SHIFT_JIS) + #define WC_CES_CP932		WC_CES_SHIFT_JIS ++#define WC_CES_CP943		WC_CES_SHIFT_JIS + #define WC_CES_SHIFT_JISX0213	(WC_CES_E_PRIV2|WC_CES_N_SHIFT_JISX0213) + #define WC_CES_GBK		(WC_CES_E_PRIV2|WC_CES_N_GBK) + #define WC_CES_CP936		WC_CES_GBK +diff -urN w3m-0.5.2.orig/libwc/charset.c w3m/libwc/charset.c +--- w3m-0.5.2.orig/libwc/charset.c	2007-05-23 21:34:20.000000000 +0900 ++++ w3m/libwc/charset.c	2007-06-07 19:59:52.000000000 +0900 +@@ -32,6 +32,46 @@ +   { NULL, 0 } + }; +  ++static wc_ces ++wc_codepage(int n) ++{ ++	switch (n) { ++	case 437: return WC_CES_CP437; ++	case 737: return WC_CES_CP737; ++	case 775: return WC_CES_CP775; ++	case 850: return WC_CES_CP850; ++	case 852: return WC_CES_CP852; ++	case 855: return WC_CES_CP855; ++	case 856: return WC_CES_CP856; ++	case 857: return WC_CES_CP857; ++	case 860: return WC_CES_CP860; ++	case 861: return WC_CES_CP861; ++	case 862: return WC_CES_CP862; ++	case 863: return WC_CES_CP863; ++	case 864: return WC_CES_CP864; ++	case 865: return WC_CES_CP865; ++	case 866: return WC_CES_CP866; ++	case 869: return WC_CES_CP869; ++	case 874: return WC_CES_CP874; ++	case 932: return WC_CES_CP932;		/* CP932 = Shift_JIS */ ++	case 936: return WC_CES_CP936;		/* CP936 = GBK > EUC_CN */ ++	case 943: return WC_CES_CP943;		/* CP943 = Shift_JIS */ ++	case 949: return WC_CES_CP949;		/* CP949 = UHC > EUC_KR */ ++	case 950: return WC_CES_CP950;		/* CP950 = Big5 */ ++	case 1006: return WC_CES_CP1006; ++	case 1250: return WC_CES_CP1250; ++	case 1251: return WC_CES_CP1251; ++	case 1252: return WC_CES_CP1252; ++	case 1253: return WC_CES_CP1253; ++	case 1254: return WC_CES_CP1254; ++	case 1255: return WC_CES_CP1255; ++	case 1256: return WC_CES_CP1256; ++	case 1257: return WC_CES_CP1257; ++	case 1258: return WC_CES_CP1258; ++	} ++	return 0; ++} ++ + wc_ces + wc_guess_charset(char *charset, wc_ces orig) + { +@@ -119,6 +159,11 @@ + 	    if (n >= 1 && n <= 16 && n != 12) + 		return (WC_CES_E_ISO_8859 | n); + 	    return WC_CES_ISO_8859_1; ++	} else if (! strncmp(p, "ibm", 3)) { ++	    p += 3; ++	    if (*p >= '1' && *p <= '9') ++	    	return wc_codepage(atoi(p)); ++	    return wc_charset_to_ces(p); + 	} + 	break; +     case 'j': +@@ -135,6 +180,10 @@ + 	    ! strncmp(p, "sjis", 4)) + 	    return WC_CES_SHIFT_JIS; + 	break; ++    case 'p': ++	if (! strncmp(p, "pck", 3)) ++	    return WC_CES_SHIFT_JIS; ++	break; +     case 'g': + 	if (! strncmp(p, "gb18030", 7) || + 	    ! strncmp(p, "gbk2k", 5)) +@@ -210,58 +259,18 @@ + 	    return WC_CES_EUC_CN; + 	if (*(p+1) != 'p') + 	    break; +-	n = atoi(p + 2); +-	switch (n) { +-	case 437: return WC_CES_CP437; +-	case 737: return WC_CES_CP737; +-	case 775: return WC_CES_CP775; +-	case 850: return WC_CES_CP850; +-	case 852: return WC_CES_CP852; +-	case 855: return WC_CES_CP855; +-	case 856: return WC_CES_CP856; +-	case 857: return WC_CES_CP857; +-	case 860: return WC_CES_CP860; +-	case 861: return WC_CES_CP861; +-	case 862: return WC_CES_CP862; +-	case 863: return WC_CES_CP863; +-	case 864: return WC_CES_CP864; +-	case 865: return WC_CES_CP865; +-	case 866: return WC_CES_CP866; +-	case 869: return WC_CES_CP869; +-	case 874: return WC_CES_CP874; +-	case 932: return WC_CES_CP932;		/* CP932 = Shift_JIS */ +-	case 936: return WC_CES_CP936;		/* CP936 = GBK > EUC_CN */ +-	case 949: return WC_CES_CP949;		/* CP949 = UHC > EUC_KR */ +-	case 950: return WC_CES_CP950;		/* CP950 = Big5 */ +-	case 1006: return WC_CES_CP1006; +-	case 1250: return WC_CES_CP1250; +-	case 1251: return WC_CES_CP1251; +-	case 1252: return WC_CES_CP1252; +-	case 1253: return WC_CES_CP1253; +-	case 1254: return WC_CES_CP1254; +-	case 1255: return WC_CES_CP1255; +-	case 1256: return WC_CES_CP1256; +-	case 1257: return WC_CES_CP1257; +-	case 1258: return WC_CES_CP1258; +-	} ++	p += 2; ++	if (*p >= '1' &&  *p <= '9') ++	    return wc_codepage(atoi(p)); + 	break; +     case 'w': + 	if (strncmp(p, "windows", 7)) + 	    break; ++	p += 7; + 	if (! strncmp(p, "31j", 3)) + 	    return WC_CES_CP932; +-	n = atoi(p + 7); +-	switch (n) { +-	case 1250: return WC_CES_CP1250; +-	case 1251: return WC_CES_CP1251; +-	case 1252: return WC_CES_CP1252; +-	case 1253: return WC_CES_CP1253; +-	case 1254: return WC_CES_CP1254; +-	case 1255: return WC_CES_CP1255; +-	case 1256: return WC_CES_CP1256; +-	case 1257: return WC_CES_CP1257; +-	case 1258: return WC_CES_CP1258; +-	} ++	if (*p >= '1' &&  *p <= '9') ++	    return wc_codepage(atoi(p)); + 	break; +     } +     return 0; +@@ -345,18 +354,9 @@ +     case 'c': + 	return WC_CES_ISO_2022_CN; +     case 'w': +-	n = atoi(p + 1); +-	switch (n) { +-	case 1250: return WC_CES_CP1250; +-	case 1251: return WC_CES_CP1251; +-	case 1252: return WC_CES_CP1252; +-	case 1253: return WC_CES_CP1253; +-	case 1254: return WC_CES_CP1254; +-	case 1255: return WC_CES_CP1255; +-	case 1256: return WC_CES_CP1256; +-	case 1257: return WC_CES_CP1257; +-	case 1258: return WC_CES_CP1258; +-	} ++	p++; ++	if (*p >= '1' &&  *p <= '9') ++	    return wc_codepage(atoi(p)); + 	break; +     case 'r': + 	return WC_CES_RAW; +@@ -368,7 +368,7 @@ + wc_locale_to_ces(char *locale) + { +     char *p = locale; +-    char buf[6]; ++    char buf[8]; +     int n; +  +     if (*p == 'C' && *(p+1) == '\0') +@@ -380,7 +380,7 @@ + 	    return wc_charset_to_ces(cs); +     } + #endif +-    for (n = 0; *p && *p != '.' && n < 5; p++) { ++    for (n = 0; *p && *p != '.' && n < 7; p++) { + 	if ((unsigned char)*p > 0x20) + 	    buf[n++] = tolower(*p); +     } diff --git a/debian/patches/series b/debian/patches/series index e6327bd..bf0fbe2 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -7,3 +7,13 @@  070_form-update.patch  080_xhtml-support.patch  090_simple-preserve-space.patch +100_download-error-short-write.patch +110_no-graph-restriction.patch +120_config-file-handling.patch +130_rc-blank-line-fix.patch +140_pseudo-inlines.patch +150_numbered-links.patch +160_tls-sni.patch +170_number-prefix.patch +180_non-xterm.patch +190_codepage.patch | 
