diff options
Diffstat (limited to 'debian/patches/110_no-graph-restriction.patch')
-rw-r--r-- | debian/patches/110_no-graph-restriction.patch | 11756 |
1 files changed, 11756 insertions, 0 deletions
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 */ |