/* $Id: main.c,v 1.1 2001/11/08 05:15:13 a-ito Exp $ */ #define MAINPROGRAM #include "fm.h" #include #include #include #include #include #include "terms.h" #include "myctype.h" #ifdef MOUSE #ifdef USE_GPM #include #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 #define DSTR_LEN 256 Hist *LoadHist; Hist *SaveHist; Hist *URLHist; Hist *ShellHist; Hist *TextHist; #define N_EVENT_QUEUE 10 typedef struct { int cmd; void *user_data; } Event; static Event eventQueue[N_EVENT_QUEUE]; static int n_event_queue; #ifdef USE_MARK static char *MarkString = NULL; #endif static char *SearchString = NULL; int (*searchRoutine) (Buffer *, char *); JMP_BUF IntReturn; static void cmd_loadfile(char *path); static void cmd_loadURL(char *url, ParsedURL * current); static void cmd_loadBuffer(Buffer * buf, int prop, int link); static void keyPressEventProc(int c); #ifdef USE_MARK static void cmd_mark(Lineprop * p); #endif /* USE_MARK */ #ifdef SHOW_PARAMS int show_params_p = 0; void show_params(FILE * fp); #endif static int display_ok = FALSE; int w3m_dump = 0; int w3m_dump_source = 0; int w3m_dump_head = 0; static void dump_source(Buffer *); static void dump_head(Buffer *); int prec_num = 0; int prev_key = -1; int on_target = 1; static void _goLine(char*); #define PREC_NUM (prec_num ? prec_num : 1) #define PREC_LIMIT 10000 #if 0 static int searchKeyNum(void); #endif #include "gcmain.c" #define help() fusage(stdout, 0) #define usage() fusage(stderr, 1) static void fusage(FILE *f, int err) { fprintf(f, "version %s\n", version); 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 JP_CHARSET #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 fprintf(f, " -I e|s document code\n"); #endif /* JP_CHARSET */ 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 COLOR fprintf(f, " -M monochrome display\n"); #endif /* COLOR */ fprintf(f, " -F automatically render frame\n"); fprintf(f, " -dump dump formatted page into stdout\n"); fprintf(f, " -cols width specify column width (used with -dump)\n"); fprintf(f, " -ppc count specify the number of pixels per character (4.0...32.0)\n"); fprintf(f, " -dump_source dump page source into stdout\n"); fprintf(f, " -dump_head dump response of HEAD request into stdout\n"); fprintf(f, " + goto line\n"); fprintf(f, " -num show line number\n"); fprintf(f, " -no-proxy don't use proxy\n"); #ifdef MOUSE fprintf(f, " -no-mouse don't use mouse\n"); #endif /* MOUSE */ #ifdef USE_COOKIE fprintf(f, " -cookie use cookie (-no-cookie: don't use cookie)\n"); fprintf(f, " -pauth user:pass proxy authentication\n"); #endif /* USE_COOKIE */ #ifndef KANJI_SYMBOLS fprintf(f, " -no-graph don't use graphic character\n"); #endif /* not KANJI_SYMBOLS */ #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, " -o opt=value assign value to config option\n"); fprintf(f, " -config file specify config file\n"); fprintf(f, " -debug DO NOT USE\n"); #ifdef SHOW_PARAMS if (show_params_p) show_params(f); #endif exit(err); } static int option_assigned = 0; extern void parse_proxy(void); 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) { static struct { char *msg; GC_word arg; } msg_ring[GC_WARN_KEEP_MAX] = { {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, {NULL, 0}, }; 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]); disp_message_nsec(Sprintf(msg_ring[i].msg, (unsigned long)msg_ring[i].arg)->ptr, FALSE, 1, TRUE, FALSE); } lock = 0; } } else if (orig_GC_warn_proc) orig_GC_warn_proc(msg, arg); else fprintf(stderr, msg, (unsigned long)arg); } 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; #ifndef SYS_ERRLIST prepare_sys_errlist(); #endif /* not SYS_ERRLIST */ srand48(time(0)); NO_proxy_domains = newTextList(); fileToDelete = newTextList(); load_argv = New_N(char *, argc - 1); load_argc = 0; CurrentDir = currentdir(); BookmarkFile = NULL; rc_dir = expandName(RC_DIR); i = strlen(rc_dir); if (i > 1 && rc_dir[i - 1] == '/') rc_dir[i - 1] = '\0'; config_file = rcFile(CONFIG_FILE); create_option_search_table(); /* 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])) help(); } } /* initializations */ init_rc(config_file); initKeymap(); #ifdef MENU initMenu(); CurrentMenuData = NULL; #endif /* MENU */ #ifdef USE_COOKIE initCookie(); #endif /* USE_COOKIE */ setLocalCookie(); /* setup cookie for local CGI */ LoadHist = newHist(); SaveHist = newHist(); ShellHist = newHist(); TextHist = newHist(); URLHist = newHist(); #ifdef USE_HISTORY loadHistory(URLHist); #endif /* not USE_HISTORY */ if (!non_null(HTTP_proxy) && ((p = getenv("HTTP_PROXY")) || (p = getenv("http_proxy")) || (p = getenv("HTTP_proxy")))) { HTTP_proxy = p; parseURL(p, &HTTP_proxy_parsed, NULL); } #ifdef USE_GOPHER if (!non_null(GOPHER_proxy) && ((p = getenv("GOPHER_PROXY")) || (p = getenv("gopher_proxy")) || (p = getenv("GOPHER_proxy")))) { GOPHER_proxy = p; parseURL(p, &GOPHER_proxy_parsed, NULL); } #endif /* USE_GOPHER */ if (!non_null(FTP_proxy) && ((p = getenv("FTP_PROXY")) || (p = getenv("ftp_proxy")) || (p = getenv("FTP_proxy")))) { FTP_proxy = p; parseURL(p, &FTP_proxy_parsed, NULL); } if (!non_null(NO_proxy) && ((p = getenv("NO_PROXY")) || (p = getenv("no_proxy")) || (p = getenv("NO_proxy")))) { NO_proxy = p; set_no_proxy(p); } if (Editor == NULL && (p = getenv("EDITOR")) != NULL) Editor = p; if (Mailer == NULL && (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(); PagerMax = atoi(argv[i]); } #ifdef JP_CHARSET #ifndef DEBIAN /* XXX: use -o kanjicode={S|J|E} */ else if (!strcmp("-s", argv[i])) DisplayCode = CODE_SJIS; else if (!strcmp("-j", argv[i])) DisplayCode = CODE_JIS_n; else if (!strcmp("-e", argv[i])) DisplayCode = CODE_EUC; #endif else if (!strcmp("-I", argv[i])) { if (++i >= argc) usage(); DocumentCode = str_to_code(argv[i]); } #endif /* JP_CHARSET */ #ifndef KANJI_SYMBOLS else if (!strcmp("-no-graph", argv[i])) no_graphic_char = TRUE; #endif /* not KANJI_SYMBOLS */ else if (!strcmp("-T", argv[i])) { if (++i >= argc) usage(); DefaultType = argv[i]; } else if (!strcmp("-m", argv[i])) SearchHeader = TRUE; else if (!strcmp("-v", argv[i])) visual_start = TRUE; #ifdef COLOR else if (!strcmp("-M", argv[i])) useColor = FALSE; #endif /* 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 (WrapSearch) { WrapSearch = FALSE; } else { WrapSearch = TRUE; } } else if (!strcmp("-dump", argv[i])) { w3m_dump = TRUE; w3m_dump_source = FALSE; w3m_dump_head = FALSE; w3m_halfdump = FALSE; if (COLS == 0) COLS = 80; } else if (!strcmp("-dump_source", argv[i])) { w3m_dump = TRUE; w3m_dump_source = TRUE; w3m_dump_head = FALSE; w3m_halfdump = FALSE; if (COLS == 0) COLS = 80; } else if (!strcmp("-dump_head", argv[i])) { w3m_dump = TRUE; w3m_dump_head = TRUE; w3m_dump_source = FALSE; w3m_halfdump = FALSE; if (COLS == 0) COLS = 80; } else if (!strcmp("-halfdump", argv[i])) { w3m_halfdump = TRUE; w3m_dump = FALSE; if (COLS == 0) COLS = 80; } else if (!strcmp("-halfload", argv[i])) { w3m_halfload = TRUE; w3m_dump = FALSE; w3m_halfdump = FALSE; } 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; } else if (!strcmp("-num", argv[i])) showLineNum = TRUE; else if (!strcmp("-no-proxy", argv[i])) Do_not_use_proxy = TRUE; #ifdef MOUSE else if (!strcmp("-no-mouse", argv[i])) { mouse_end(); use_mouse = FALSE; } #endif /* MOUSE */ #ifdef USE_COOKIE else if (!strcmp("-no-cookie", argv[i])) { use_cookie = FALSE; } else if (!strcmp("-cookie", argv[i])) { use_cookie = TRUE; } else if (!strcmp("-pauth", argv[i])) { if (++i >= argc) usage(); proxy_auth_cookie = encodeB(argv[i]); while (argv[i][0]) { argv[i][0] = '\0'; argv[i]++; } } #endif /* USE_COOKIE */ #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("-o", argv[i])) { #ifdef SHOW_PARAMS if (++i >= argc || !strcmp(argv[i], "?")) { show_params_p = 1; usage(); } #else if (++i >= argc) usage(); #endif if (!set_param_option(argv[i])) { /* option set failed */ fprintf(stderr, "%s: bad option\n", argv[i]); #ifdef SHOW_PARAMS show_params_p = 1; usage(); #else exit(1); #endif } option_assigned = 1; } else if (!strcmp("-dummy", argv[i])) { /* do nothing */ } else if (!strcmp("-debug", argv[i])) w3m_debug = TRUE; else { usage(); } } else if (*argv[i] == '+') { line_str = argv[i] + 1; } else { load_argv[load_argc++] = argv[i]; } i++; } if (option_assigned) { parse_proxy(); } #ifdef __WATT32__ if (w3m_debug) dbug_init(); sock_init(); #endif Firstbuf = NULL; Currentbuf = NULL; CurrentKey = -1; if (BookmarkFile == NULL) BookmarkFile = rcFile(BOOKMARK); if (!isatty(1) && !w3m_dump && !w3m_halfdump) { /* redirected output */ w3m_dump = TRUE; if (COLS == 0) COLS = 80; } if (w3m_backend) backend(); if (!w3m_dump && !w3m_halfdump) fmInit(); orig_GC_warn_proc = GC_set_warn_proc(wrap_GC_warn_proc); if (w3m_halfdump) printf("
\n");

    if (load_argc == 0) {
	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)
		fprintf(stderr, "w3m: Can't load bookmark\n");
	}
	else if (visual_start) {
	    Str s_page;
	    s_page = Strnew_charp("W3M startup page
Welcome to "); #ifdef JP_CHARSET Strcat_charp(s_page, ""); #else Strcat_charp(s_page, ""); #endif /* JP_CHARSET */ Strcat_m_charp(s_page, "w3m!

This is w3m version ", version, "
Written by Akinori Ito", NULL); #ifdef DEBIAN Strcat_m_charp(s_page, "

Debian package is maintained by Fumitoshi UKAI.", "You can read w3m documents on your local system.", NULL); #endif /* DEBIAN */ newbuf = loadHTMLString(s_page); if (newbuf == NULL) fprintf(stderr, "w3m: Can't load string\n"); else 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) fprintf(stderr, "w3m: Can't load %s\n", p); } else { if (fmInitialized) fmTerm(); usage(); } if (newbuf == NULL) { deleteFiles(); if (fmInitialized) { sleep_till_anykey(1, 0); fmTerm(); } exit(2); } i = -1; } else { i = 0; } for (; i < load_argc; i++) { if (i >= 0) { if (w3m_dump && w3m_dump_head) { request = New(FormList); request->method = FORM_METHOD_HEAD; newbuf = loadGeneralFile(load_argv[i], NULL, NO_REFERER, 0, request); } else { newbuf = loadGeneralFile(load_argv[i], NULL, NO_REFERER, 0, NULL); } if (newbuf == NULL) { fprintf(stderr, "w3m: Can't load %s\n", load_argv[i]); continue; } else if (newbuf == NO_BUFFER) continue; switch (newbuf->real_scheme) { #ifdef USE_NNTP case SCM_NNTP: case SCM_NEWS: #endif /* USE_NNTP */ case SCM_MAILTO: break; case SCM_LOCAL: case SCM_LOCAL_CGI: unshiftHist(LoadHist, load_argv[i]); break; default: pushHashHist(URLHist, parsedURL2Str(&newbuf->currentURL)->ptr); break; } } if (newbuf == NO_BUFFER) continue; if (w3m_halfdump) { Currentbuf = Firstbuf = newbuf; printf("

%s\n", htmlquote_str(newbuf->buffername)); deleteFiles(); exit(0); } if (w3m_dump) { Currentbuf = Firstbuf = newbuf; if (w3m_dump_source) dump_source(Currentbuf); else if (w3m_dump_head) dump_head(Currentbuf); else { if (Currentbuf->frameset != NULL && RenderFrame) rFrame(); saveBuffer(Currentbuf, stdout); } deleteFiles(); #ifdef USE_COOKIES save_cookies(); #endif /* USE_COOKIES */ exit(0); } if (Currentbuf == NULL) Firstbuf = Currentbuf = newbuf; else { Currentbuf->nextBuffer = newbuf; Currentbuf = newbuf; } if (Currentbuf && Currentbuf != NO_BUFFER && RenderFrame && Currentbuf->frameset != NULL) { rFrame(); Currentbuf = newbuf; } #ifdef BUFINFO saveBufferInfo(); #endif } if (!Firstbuf || Firstbuf == NO_BUFFER) { if (newbuf == NO_BUFFER) { if (fmInitialized) inputStr("Hit any key to quit w3m:", ""); quitfm(); } deleteFiles(); if (fmInitialized) { sleep_till_anykey(1, 0); fmTerm(); } exit(2); } #ifdef SIGWINCH signal(SIGWINCH, resize_hook); #else /* not SIGWINCH */ setlinescols(); setupscreen(); #endif /* not SIGWINCH */ Currentbuf = Firstbuf; displayBuffer(Currentbuf, B_NORMAL); onA(); if (line_str) { _goLine(line_str); } for (;;) { /* event processing */ if (n_event_queue > 0) { for (i = 0; i < n_event_queue; i++) { CurrentKey = -1; CurrentKeyData = eventQueue[i].user_data; #ifdef MENU CurrentMenuData = NULL; #endif w3mFuncList[eventQueue[i].cmd].func(); } n_event_queue = 0; } CurrentKeyData = NULL; /* get keypress event */ #ifdef MOUSE if (use_mouse) mouse_active(); #endif /* MOUSE */ c = getch(); #ifdef MOUSE if (use_mouse) mouse_inactive(); #endif /* MOUSE */ if (IS_ASCII(c)) { /* Ascii */ 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 { keyPressEventProc((int) c); prec_num = 0; } } prev_key = CurrentKey; CurrentKey = -1; } } static void keyPressEventProc(int c) { CurrentKey = c; w3mFuncList[(int) GlobalKeymap[c]].func(); onA(); } void pushEvent(int event, void *user_data) { if (n_event_queue < N_EVENT_QUEUE) { eventQueue[n_event_queue].cmd = event; eventQueue[n_event_queue].user_data = user_data; n_event_queue++; } } 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) return; for (ti = buf->document_header->first; ti; ti = ti->next) { printf("%s", ti->ptr); } puts(""); } void nulcmd(void) { /* do nothing */ } #ifdef __EMX__ void pcmap(void) { w3mFuncList[(int) PcKeymap[(int) getch()].func(); } #else /* not __EMX__ */ void pcmap(void) { } #endif void escmap(void) { char c; c = getch(); if (IS_ASCII(c)) { CurrentKey = K_ESC | c; w3mFuncList[(int) EscKeymap[(int) c]].func(); } } void escbmap(void) { char c; c = getch(); if (IS_DIGIT(c)) escdmap(c); else if (IS_ASCII(c)) { CurrentKey = K_ESCB | c; w3mFuncList[(int) EscBKeymap[(int) c]].func(); } } 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 == '~') { CurrentKey = K_ESCD | d; w3mFuncList[(int) EscDKeymap[d]].func(); } } 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); void saveBufferInfo() { FILE *fp; if ((fp = fopen(rcFile("bufinfo"), "w")) == NULL) { return; } else { fprintf(fp, "%s\n", currentURL()->ptr); fclose(fp); } } static void pushBuffer(Buffer * buf) { Buffer *b; 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 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 MySignalHandler resize_hook(SIGNAL_ARG) { setlinescols(); setupscreen(); if (Currentbuf) displayBuffer(Currentbuf, B_FORCE_REDRAW); signal(SIGWINCH, resize_hook); SIGNAL_RETURN; } #endif /* SIGWINCH */ /* * Command functions: These functions are called with a keystroke. */ #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) static void nscroll(int n, int mode) { Line *curtop = Currentbuf->topLine; int lnum, tlnum, llnum, diff_n; if (Currentbuf->firstLine == NULL) return; lnum = Currentbuf->currentLine->linenumber; Currentbuf->topLine = lineSkip(Currentbuf, curtop, n, FALSE); if (Currentbuf->topLine == curtop) { lnum += n; if (lnum < Currentbuf->topLine->linenumber) lnum = Currentbuf->topLine->linenumber; else if (lnum > Currentbuf->lastLine->linenumber) lnum = Currentbuf->lastLine->linenumber; } else { tlnum = Currentbuf->topLine->linenumber; llnum = Currentbuf->topLine->linenumber + LASTLINE - 1; diff_n = n - (tlnum - curtop->linenumber); if (lnum < tlnum) lnum = tlnum + diff_n; if (lnum > llnum) lnum = llnum + diff_n; } gotoLine(Currentbuf, lnum); arrangeLine(Currentbuf); displayBuffer(Currentbuf, mode); } /* Move page forward */ void pgFore(void) { #ifdef VI_PREC_NUM nscroll(PREC_NUM * (LASTLINE - 1), B_NORMAL); #else /* not VI_PREC_NUM */ nscroll(prec_num ? prec_num : (LASTLINE - 1), prec_num ? B_SCROLL : B_NORMAL); #endif /* not VI_PREC_NUM */ } /* Move page backward */ void pgBack(void) { #ifdef VI_PREC_NUM nscroll(- PREC_NUM * (LASTLINE - 1), B_NORMAL); #else /* not VI_PREC_NUM */ nscroll(- (prec_num ? prec_num : (LASTLINE - 1)), prec_num ? B_SCROLL : B_NORMAL); #endif /* not VI_PREC_NUM */ } /* 1 line up */ void lup1(void) { nscroll(PREC_NUM, B_SCROLL); } /* 1 line down */ void ldown1(void) { nscroll(-PREC_NUM, B_SCROLL); } /* move cursor position to the center of screen */ void ctrCsrV(void) { int offsety; if (Currentbuf->firstLine == NULL) return; offsety = LASTLINE / 2 - Currentbuf->cursorY; if (offsety != 0) { /* Currentbuf->currentLine = lineSkip(Currentbuf, * Currentbuf->currentLine,offsety, FALSE); */ Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->topLine, -offsety, FALSE); arrangeLine(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } } void ctrCsrH(void) { int offsetx; if (Currentbuf->firstLine == NULL) return; offsetx = Currentbuf->cursorX - COLS / 2; if (offsetx != 0) { columnSkip(Currentbuf, offsetx); arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } } /* Redraw screen */ void rdrwSc(void) { clear(); arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_FORCE_REDRAW); } /* Search regular expression forward */ void srchfor(void) { MySignalHandler(*prevtrap) (); char *str; int i; int wrapped = 0; str = inputStrHist("Forward: ", NULL, TextHist); if (str != NULL && *str == '\0') str = SearchString; if (str == NULL || *str == '\0') { displayBuffer(Currentbuf, B_NORMAL); return; } SearchString = str; prevtrap = signal(SIGINT, intTrap); crmode(); if (SETJMP(IntReturn) == 0) for (i = 0; i < PREC_NUM; i++) wrapped = forwardSearch(Currentbuf, SearchString); signal(SIGINT, prevtrap); term_raw(); displayBuffer(Currentbuf, B_NORMAL); if (wrapped) { disp_message("Search wrapped", FALSE); } searchRoutine = forwardSearch; } /* Search regular expression backward */ void srchbak(void) { MySignalHandler(*prevtrap) (); char *str; int i; int wrapped = 0; str = inputStrHist("Backward: ", NULL, TextHist); if (str != NULL && *str == '\0') str = SearchString; if (str == NULL || *str == '\0') { displayBuffer(Currentbuf, B_NORMAL); return; } SearchString = str; prevtrap = signal(SIGINT, intTrap); crmode(); if (SETJMP(IntReturn) == 0) for (i = 0; i < PREC_NUM; i++) wrapped = backwardSearch(Currentbuf, SearchString); signal(SIGINT, prevtrap); term_raw(); displayBuffer(Currentbuf, B_NORMAL); if (wrapped) { disp_message("Search wrapped", FALSE); } searchRoutine = backwardSearch; } static void srch_nxtprv(int reverse) { int i; int wrapped = 0; static int (*routine[2]) (Buffer *, char *) = { forwardSearch, backwardSearch }; MySignalHandler(*prevtrap) (); if (searchRoutine == NULL) { disp_message("No previous regular expression", TRUE); return; } move(LASTLINE, 0); addstr(searchRoutine == forwardSearch ? "Forward: " : "Backward: "); addstr(SearchString); clrtoeolx(); move(LASTLINE, 0); refresh(); if (reverse != 0) reverse = 1; if (searchRoutine == backwardSearch) reverse ^= 1; prevtrap = signal(SIGINT, intTrap); crmode(); if (SETJMP(IntReturn) == 0) for (i = 0; i < PREC_NUM; i++) wrapped = (*routine[reverse]) (Currentbuf, SearchString); signal(SIGINT, prevtrap); term_raw(); displayBuffer(Currentbuf, B_NORMAL); if (wrapped) { disp_message("Search wrapped", FALSE); } } /* Search next matching */ void srchnxt(void) { srch_nxtprv(0); } /* Search previous matching */ void srchprv(void) { srch_nxtprv(1); } static void shiftvisualpos(Buffer * buf, int shift) { buf->visualpos -= shift; if (buf->visualpos >= COLS) buf->visualpos = COLS - 1; else if (buf->visualpos < 0) buf->visualpos = 0; arrangeLine(buf); if (buf->visualpos == -shift && buf->cursorX == 0) buf->visualpos = 0; } /* Shift screen left */ void shiftl(void) { int column; if (Currentbuf->firstLine == NULL) return; column = Currentbuf->currentColumn; columnSkip(Currentbuf, PREC_NUM * (-COLS + 1) + 1); shiftvisualpos(Currentbuf, Currentbuf->currentColumn - column); displayBuffer(Currentbuf, B_NORMAL); } /* Shift screen right */ void shiftr(void) { int column; if (Currentbuf->firstLine == NULL) return; column = Currentbuf->currentColumn; columnSkip(Currentbuf, PREC_NUM * (COLS - 1) - 1); shiftvisualpos(Currentbuf, Currentbuf->currentColumn - column); displayBuffer(Currentbuf, B_NORMAL); } void col1R(void) { Buffer *buf = Currentbuf; Line *l = buf->currentLine; int j, column; if (l == NULL) return; for (j = 0; j < PREC_NUM; j++) { column = buf->currentColumn; columnSkip(Currentbuf, 1); if (column == buf->currentColumn) break; shiftvisualpos(Currentbuf, 1); } displayBuffer(Currentbuf, B_NORMAL); } void col1L(void) { Buffer *buf = Currentbuf; Line *l = buf->currentLine; int j; if (l == NULL) return; for (j = 0; j < PREC_NUM; j++) { if (buf->currentColumn == 0) break; columnSkip(Currentbuf, -1); shiftvisualpos(Currentbuf, -1); } displayBuffer(Currentbuf, B_NORMAL); } /* Execute shell command and read output ac pipe. */ void pipesh(void) { 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 == '\0') { displayBuffer(Currentbuf, B_NORMAL); return; } } buf = getpipe(cmd); if (buf == NULL) { disp_message("Execution failed", FALSE); } 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 */ void readsh(void) { 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 == '\0') { displayBuffer(Currentbuf, B_NORMAL); return; } } prevtrap = signal(SIGINT, intTrap); crmode(); buf = getshell(cmd); signal(SIGINT, prevtrap); term_raw(); if (buf == NULL) { disp_message("Execution failed", FALSE); } 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 */ void execsh(void) { #ifdef MOUSE int use_m = use_mouse; #endif 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 != '\0') { fmTerm(); system(cmd); printf("\n[Hit any key]"); fflush(stdout); #ifdef MOUSE use_mouse = FALSE; #endif fmInit(); getch(); #ifdef MOUSE use_mouse = use_m; if (use_mouse) mouse_init(); #endif } displayBuffer(Currentbuf, B_FORCE_REDRAW); } /* Load file */ void ldfile(void) { char *fn; fn = searchKeyData(); if (fn == NULL || *fn == '\0') { fn = inputFilenameHist("(Load)Filename? ", NULL, LoadHist); if (fn == NULL || *fn == '\0') { displayBuffer(Currentbuf, B_NORMAL); return; } } cmd_loadfile(fn); } /* Load help file */ void ldhelp(void) { cmd_loadURL(helpFile(HELP_FILE), NULL); } static void cmd_loadfile(char *fn) { Buffer *buf; buf = loadGeneralFile(fn, NULL, NO_REFERER, 0, NULL); if (buf == NULL) { char *emsg = Sprintf("%s not found", 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 */ void movL(void) { int i; if (Currentbuf->firstLine == NULL) return; for (i = 0; i < PREC_NUM; i++) cursorLeft(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } /* Move cursor downward */ void movD(void) { int i; if (Currentbuf->firstLine == NULL) return; for (i = 0; i < PREC_NUM; i++) cursorDown(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } /* move cursor upward */ void movU(void) { int i; if (Currentbuf->firstLine == NULL) return; for (i = 0; i < PREC_NUM; i++) cursorUp(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } /* Move cursor right */ void movR(void) { int i; if (Currentbuf->firstLine == NULL) return; for (i = 0; i < PREC_NUM; i++) cursorRight(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } /* movLW, movRW */ /* * From: Takashi Nishimoto 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; } void movLW(void) { char *lb; Lineprop *pb; Line *pline; int ppos; int i; if (Currentbuf->firstLine == NULL) return; for (i = 0; i < PREC_NUM; 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; } void movRW(void) { char *lb; Lineprop *pb; Line *pline; int ppos; int i; if (Currentbuf->firstLine == NULL) return; for (i = 0; i < PREC_NUM; 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); } /* Question and Quit */ void qquitfm(void) { char *ans; if (!confirm_on_quit) quitfm(); ans = inputStr("Do you want to exit w3m? (y or n)", ""); if (ans != NULL && tolower(*ans) == 'y') quitfm(); displayBuffer(Currentbuf, B_NORMAL); } /* Quit */ void quitfm(void) { fmTerm(); deleteFiles(); #ifdef USE_COOKIE save_cookies(); #endif /* USE_COOKIE */ #ifdef USE_HISTORY if (SaveURLHist) saveHistory(URLHist, URLHistSize); #endif /* USE_HISTORY */ exit(0); } /* Select buffer */ void selBuf(void) { 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); if (clear_buffer) { for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer) tmpClearBuffer(buf); } displayBuffer(Currentbuf, B_FORCE_REDRAW); } /* Suspend (on BSD), or run interactive shell (on SysV) */ void susp(void) { #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, -(LASTLINE + 1) / 2, TRUE); Currentbuf->currentLine = Currentbuf->lastLine; } else gotoRealLine(Currentbuf, atoi(l)); arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_FORCE_REDRAW); } void goLine(void) { char *l = inputStr("Goto line: ", ""); prec_num = 0; _goLine(l); } void goLineF(void) { _goLine("^"); } void goLineL(void) { _goLine("$"); } /* Go to the beginning of the line */ void linbeg(void) { if (Currentbuf->firstLine == NULL) return; Currentbuf->pos = 0; arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } /* Go to the bottom of the line */ void linend(void) { if (Currentbuf->firstLine == NULL) return; Currentbuf->pos = Currentbuf->currentLine->len - 1; arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } /* Run editor on the current buffer */ void editBf(void) { char *fn = Currentbuf->filename; char *type = Currentbuf->type; int top, linenum, cursorY, pos, currentColumn; Buffer *buf, *fbuf = NULL; 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->frameset != NULL) fbuf = Currentbuf->linkBuffer[LB_FRAME]; if (Currentbuf->firstLine == NULL) { top = 1; linenum = 1; } else { top = Currentbuf->topLine->linenumber; linenum = Currentbuf->currentLine->linenumber; } cursorY = Currentbuf->cursorY; pos = Currentbuf->pos; currentColumn = Currentbuf->currentColumn; if (Currentbuf->edit) { cmd = unquote_mailcap(Currentbuf->edit, Currentbuf->real_type, quoteShell(fn)->ptr, NULL); } else { char *file = quoteShell(fn)->ptr; if (strcasestr(Editor, "%s")) { if (strcasestr(Editor, "%d")) cmd = Sprintf(Editor, linenum, file); else cmd = Sprintf(Editor, file); } else { if (strcasestr(Editor, "%d")) cmd = Sprintf(Editor, linenum); else if (strcasestr(Editor, "vi")) cmd = Sprintf("%s +%d", Editor, linenum); else cmd = Strnew_charp(Editor); Strcat_m_charp(cmd, " ", file, NULL); } } fmTerm(); system(cmd->ptr); fmInit(); buf = loadGeneralFile(fn, NULL, NO_REFERER, 0, NULL); if (buf == NULL) { disp_err_message("Re-loading failed", FALSE); buf = nullBuffer(); } else if (buf == NO_BUFFER) { buf = nullBuffer(); } if (fbuf != NULL) Firstbuf = deleteBuffer(Firstbuf, fbuf); repBuffer(Currentbuf, buf); if ((type != NULL) && (buf->type != NULL) && ((!strcasecmp(buf->type, "text/plain") && !strcasecmp(type, "text/html")) || (!strcasecmp(buf->type, "text/html") && !strcasecmp(type, "text/plain")))) { vwSrc(); if (Currentbuf != buf) Firstbuf = deleteBuffer(Firstbuf, buf); } if (Currentbuf->firstLine == NULL) { displayBuffer(Currentbuf, B_FORCE_REDRAW); return; } Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->topLine, top - 1, FALSE); gotoLine(Currentbuf, linenum); Currentbuf->pos = pos; Currentbuf->currentColumn = currentColumn; arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_FORCE_REDRAW); } /* Run editor on the current screen */ void editScr(void) { int lnum; Str cmd; Str tmpf; FILE *f; tmpf = tmpfname(TMPF_DFL, NULL); f = fopen(tmpf->ptr, "w"); if (f == NULL) { cmd = Sprintf("Can't open %s\n", tmpf->ptr); disp_err_message(cmd->ptr, TRUE); return; } saveBuffer(Currentbuf, f); fclose(f); if (Currentbuf->currentLine) lnum = Currentbuf->currentLine->linenumber; else lnum = 1; if (strcasestr(Editor, "%s")) { if (strcasestr(Editor, "%d")) cmd = Sprintf(Editor, lnum, tmpf->ptr); else cmd = Sprintf(Editor, tmpf->ptr); } else { if (strcasestr(Editor, "%d")) cmd = Sprintf(Editor, lnum); else if (strcasestr(Editor, "vi")) cmd = Sprintf("%s +%d", Editor, lnum); else cmd = Strnew_charp(Editor); Strcat_m_charp(cmd, " ", tmpf->ptr, NULL); } fmTerm(); system(cmd->ptr); fmInit(); unlink(tmpf->ptr); gotoLine(Currentbuf, lnum); arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_FORCE_REDRAW); } #ifdef USE_MARK /* Set / unset mark */ void _mark(void) { Line *l; if (Currentbuf->firstLine == NULL) return; l = Currentbuf->currentLine; cmd_mark(&l->propBuf[Currentbuf->pos]); redrawLine(Currentbuf, l, l->linenumber - Currentbuf->topLine->linenumber); } static void cmd_mark(Lineprop * p) { if ((*p & PM_MARK) && (*p & PE_STAND)) *p &= ~PE_STAND; else if (!(*p & PM_MARK) && !(*p & PE_STAND)) *p |= PE_STAND; *p ^= PM_MARK; } /* Go to next mark */ void nextMk(void) { Line *l; int i; 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] & PM_MARK) { Currentbuf->currentLine = l; Currentbuf->pos = i; arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); return; } } l = l->next; i = 0; } disp_message("No mark exist after here", TRUE); } /* Go to previous mark */ void prevMk(void) { Line *l; int i; 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] & PM_MARK) { Currentbuf->currentLine = l; Currentbuf->pos = i; arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); return; } } l = l->prev; if (l != NULL) i = l->len - 1; } disp_message("No mark exist before here", TRUE); } /* Mark place to which the regular expression matches */ void reMark(void) { Line *l; char *str; char *p, *p1, *p2; str = inputStrHist("(Mark)Regexp: ", MarkString, TextHist); if (str == NULL || *str == '\0') { displayBuffer(Currentbuf, B_NORMAL); return; } MarkString = str; if ((MarkString = regexCompile(MarkString, 1)) != NULL) { disp_message(MarkString, TRUE); return; } 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); cmd_mark(l->propBuf + (p1 - l->lineBuf)); p = p2; } else break; } } displayBuffer(Currentbuf, B_FORCE_REDRAW); } #endif /* USE_MARK */ #ifdef JP_CHARSET static char * cURLcode(char *url, Buffer * buf) { char *p; Str s; for (p = url; *p; p++) { if (!IS_ASCII(*p)) { /* URL contains Kanji... uugh */ s = conv(url, InnerCode, buf->document_code); return s->ptr; } } return url; } #else /* not JP_CHARSET */ #define cURLcode(url,buf) (url) #endif /* not JP_CHARSET */ 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\n", 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(cURLcode(url, Currentbuf), baseURL(Currentbuf), referer, flag, request); if (buf == NULL) { char *emsg = Sprintf("Can't load %s\n", 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 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->currentLine ? Currentbuf->currentLine->linenumber : 0, Currentbuf->pos); /* 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); 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) { 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, 0); pushHashHist(URLHist, parsedURL2Str(&buf->currentURL)->ptr); (*buf->clone)++; pushBuffer(buf); gotoLine(Currentbuf, al->start.line); Currentbuf->pos = al->start.pos; arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_FORCE_REDRAW); return; } /* follow HREF link */ void followA(void) { Line *l; Anchor *a; ParsedURL u; if (Currentbuf->firstLine == NULL) return; l = Currentbuf->currentLine; a = retrieveCurrentAnchor(Currentbuf); if (a == NULL) { followForm(); return; } if (*a->url == '#') { /* index within this buffer */ gotoLabel(a->url + 1); return; } parseURL2(a->url, &u, baseURL(Currentbuf)); if (u.scheme == Currentbuf->currentURL.scheme && u.port == Currentbuf->currentURL.port && ((u.host == NULL && Currentbuf->currentURL.host == NULL) || (u.host != NULL && Currentbuf->currentURL.host != NULL && strcasecmp(u.host, Currentbuf->currentURL.host) == 0)) && ((u.file == NULL && Currentbuf->currentURL.file == NULL) || (u.file != NULL && Currentbuf->currentURL.file != NULL && strcmp(u.file, Currentbuf->currentURL.file) == 0))) { /* index within this buffer */ if (u.label) { gotoLabel(u.label); return; } } if (!strncasecmp(a->url, "mailto:", 7)) { /* invoke external mailer */ Str tmp; char *to = quoteShell(a->url + 7)->ptr; if (strcasestr(Mailer, "%s")) tmp = Sprintf(Mailer, to); else tmp = Strnew_m_charp(Mailer, " ", to, NULL); fmTerm(); system(tmp->ptr); fmInit(); displayBuffer(Currentbuf, B_FORCE_REDRAW); return; } #ifdef USE_NNTP else if (!strncasecmp(a->url, "news:", 5) && strchr(a->url, '@') == NULL) { /* news:newsgroup is not supported */ disp_err_message("news:newsgroup_name is not supported", TRUE); return; } #endif /* USE_NNTP */ loadLink(a->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 */ void followI(void) { Line *l; Anchor *a; Buffer *buf; if (Currentbuf->firstLine == NULL) return; l = Currentbuf->currentLine; a = retrieveCurrentImg(Currentbuf); if (a == NULL) return; message(Sprintf("loading %s\n", a->url)->ptr, 0, 0); refresh(); buf = loadGeneralFile(cURLcode(a->url, Currentbuf), baseURL(Currentbuf), NULL, 0, NULL); if (buf == NULL) { char *emsg = Sprintf("Can't load %s\n", a->url)->ptr; disp_err_message(emsg, FALSE); } else if (buf != NO_BUFFER) { pushBuffer(buf); } displayBuffer(Currentbuf, B_NORMAL); } static void do_update_form_radio(FormItemList * f, void *data) { Buffer *buf = (Buffer *) data; formUpdateBuffer(&buf->formitem->anchors[f->anchor_num], buf, f); } 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); list->charset = srclist->charset; 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; #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; } 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", getpid(), 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; /* 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) { *query = Strdup(f2->name); Strcat_charp(*query, ".x"); form_write_data(body, fi->parent->boundary, (*query)->ptr, "1"); *query = Strdup(f2->name); Strcat_charp(*query, ".y"); form_write_data(body, fi->parent->boundary, (*query)->ptr, "1"); } else if (f2->name && f2->name->length > 0) { /* not IMAGE */ if (f2->value != NULL) { #ifdef JP_CHARSET if (fi->parent->charset != 0) *query = conv_str(f2->value, InnerCode, fi->parent->charset); else *query = conv_str(f2->value, InnerCode, Currentbuf->document_code); #else /* not JP_CHARSET */ *query = f2->value; #endif /* not JP_CHARSET */ } if (f2->type == FORM_INPUT_FILE) form_write_form_file(body, fi->parent->boundary, f2->name->ptr, (*query)->ptr); else form_write_data(body, fi->parent->boundary, f2->name->ptr, (*query)->ptr); } } else { /* not multipart */ if (f2->type == FORM_INPUT_IMAGE) { Strcat(*query, f2->name); Strcat_charp(*query, ".x=1&"); Strcat(*query, f2->name); Strcat_charp(*query, ".y=1"); } else { /* not IMAGE */ if (f2->name && f2->name->length > 0) { Strcat(*query, form_quote(f2->name)); Strcat_char(*query, '='); } if (f2->value != NULL) { if (fi->parent->method == FORM_METHOD_INTERNAL) Strcat(*query, form_quote(f2->value)); else { #ifdef JP_CHARSET if (fi->parent->charset != 0) Strcat(*query, form_quote(conv_str(f2->value, InnerCode, fi->parent->charset))); else Strcat(*query, form_quote(conv_str(f2->value, InnerCode, Currentbuf->document_code))); #else /* not JP_CHARSET */ Strcat(*query, form_quote(f2->value)); #endif /* not JP_CHARSET */ } } } 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); } } /* process form */ void followForm(void) { Line *l; Anchor *a; char *p; FormItemList *fi, *f2; Str tmp = Strnew(), tmp2 = Strnew(); int multipart = 0; 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: p = inputStrHist("TEXT:", fi->value ? fi->value->ptr : NULL, TextHist); if (p == NULL) return; fi->value = Strnew_charp(p); formUpdateBuffer(a, Currentbuf, fi); if (fi->accept || fi->parent->nitems == 1) goto do_submit; break; case FORM_INPUT_FILE: p = inputFilenameHist("Filename:", fi->value ? fi->value->ptr : NULL, NULL); if (p == NULL) return; fi->value = Strnew_charp(p); formUpdateBuffer(a, Currentbuf, fi); if (fi->accept || fi->parent->nitems == 1) goto do_submit; break; case FORM_INPUT_PASSWORD: p = inputLine("TEXT:", fi->value ? fi->value->ptr : NULL, IN_PASSWORD); if (p == NULL) return; fi->value = Strnew_charp(p); formUpdateBuffer(a, Currentbuf, fi); if (fi->accept) goto do_submit; break; case FORM_TEXTAREA: if (fi->rows == 1) { p = inputStrHist("TEXT:", fi->value ? fi->value->ptr : NULL, TextHist); if (p == NULL) return; fi->value = Strnew_charp(p); } else input_textarea(fi); formUpdateBuffer(a, Currentbuf, fi); break; case FORM_INPUT_RADIO: form_recheck_radio(fi, Currentbuf, do_update_form_radio); break; case FORM_INPUT_CHECKBOX: fi->checked = !fi->checked; formUpdateBuffer(a, Currentbuf, fi); break; #ifdef MENU_SELECT case FORM_SELECT: formChooseOptionByMenu(fi, Currentbuf->cursorX - Currentbuf->pos + a->start.pos, Currentbuf->cursorY); formUpdateBuffer(a, Currentbuf, fi); break; #endif /* MENU_SELECT */ case FORM_INPUT_IMAGE: case FORM_INPUT_SUBMIT: case FORM_INPUT_BUTTON: do_submit: 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 (fi->parent->method == FORM_METHOD_GET) { 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") == 0) || Currentbuf->bufferprop & BP_INTERNAL) { /* internal */ do_internal(tmp2->ptr, tmp->ptr); return; } else { disp_err_message("Can't send form because of illegal method.", FALSE); } break; case FORM_INPUT_RESET: for (f2 = fi->parent->item; f2; f2 = f2->next) { if (f2->name && f2->value && f2->type != FORM_INPUT_RADIO && f2->type != FORM_INPUT_CHECKBOX && f2->type != FORM_INPUT_SUBMIT && f2->type != FORM_INPUT_HIDDEN && f2->type != FORM_INPUT_RESET) { f2->value = Strnew(); formUpdateBuffer(&Currentbuf->formitem->anchors[f2->anchor_num], Currentbuf, f2); } } break; case FORM_INPUT_HIDDEN: default: break; } displayBuffer(Currentbuf, B_FORCE_REDRAW); } static void drawAnchorCursor0(Buffer * buf, int hseq, int prevhseq, int tline, int eline, int active) { int i, j; Line *l; Anchor *an; l = buf->topLine; for (j = 0; j < buf->href->nanchor; j++) { an = &buf->href->anchors[j]; if (an->start.line < tline) continue; if (an->start.line >= eline) return; for (;; l = l->next) { if (l == NULL) return; if (l->linenumber == an->start.line) break; } if (hseq >= 0 && an->hseq == hseq) { for (i = an->start.pos; i < an->end.pos; i++) { if (l->propBuf[i] & (PE_IMAGE | PE_ANCHOR | PE_FORM)) { if (active) l->propBuf[i] |= PE_ACTIVE; else l->propBuf[i] &= ~PE_ACTIVE; } } if (active) redrawLineRegion(buf, l, l->linenumber - tline, an->start.pos, an->end.pos); } else if (prevhseq >= 0 && an->hseq == prevhseq) { if (active) redrawLineRegion(buf, l, l->linenumber - tline, an->start.pos, an->end.pos); } } } void drawAnchorCursor(Buffer * buf) { Anchor *an; int hseq, prevhseq; int tline, eline; if (buf->firstLine == NULL) return; if (buf->href == NULL) return; an = retrieveCurrentAnchor(buf); if (an != NULL) hseq = an->hseq; else hseq = -1; tline = buf->topLine->linenumber; eline = tline + LASTLINE; prevhseq = buf->hmarklist->prevhseq; drawAnchorCursor0(buf, hseq, prevhseq, tline, eline, 1); drawAnchorCursor0(buf, hseq, -1, tline, eline, 0); buf->hmarklist->prevhseq = hseq; } /* underline an anchor if cursor is on the anchor. */ void onA(void) { drawAnchorCursor(Currentbuf); displayBuffer(Currentbuf, B_NORMAL); } /* go to the top anchor */ void topA(void) { HmarkerList *hl = Currentbuf->hmarklist; BufferPoint *po; Anchor *an; int hseq; if (Currentbuf->firstLine == NULL) return; if (!hl || hl->nmark == 0) return; hseq = 0; 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 */ void lastA(void) { HmarkerList *hl = Currentbuf->hmarklist; BufferPoint *po; Anchor *an; int hseq; if (Currentbuf->firstLine == NULL) return; if (!hl || hl->nmark == 0) return; 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 */ void nextA(void) { HmarkerList *hl = Currentbuf->hmarklist; BufferPoint *po; Anchor *an, *pan; int i, x, y; if (Currentbuf->firstLine == NULL) return; if (!hl || hl->nmark == 0) return; an = retrieveCurrentAnchor(Currentbuf); if (an == NULL) an = retrieveCurrentForm(Currentbuf); y = Currentbuf->currentLine->linenumber; x = Currentbuf->pos; for (i = 0; i < PREC_NUM; i++) { pan = an; if (an && an->hseq >= 0) { int hseq = an->hseq + 1; do { if (hseq >= hl->nmark) { pan = an; goto _end; } 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 || an == pan); } else { an = closest_next_anchor(Currentbuf->href, NULL, x, y); an = closest_next_anchor(Currentbuf->formitem, an, x, y); if (an == NULL) { an = pan; break; } x = an->start.pos; y = an->start.line; } } _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 */ void prevA(void) { HmarkerList *hl = Currentbuf->hmarklist; BufferPoint *po; Anchor *an, *pan; int i, x, y; if (Currentbuf->firstLine == NULL) return; if (!hl || hl->nmark == 0) return; an = retrieveCurrentAnchor(Currentbuf); if (an == NULL) an = retrieveCurrentForm(Currentbuf); y = Currentbuf->currentLine->linenumber; x = Currentbuf->pos; for (i = 0; i < PREC_NUM; i++) { pan = an; if (an && an->hseq >= 0) { int hseq = an->hseq - 1; do { if (hseq < 0) { an = pan; goto _end; } 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 || an == pan); } else { an = closest_prev_anchor(Currentbuf->href, NULL, x, y); an = closest_prev_anchor(Currentbuf->formitem, an, x, y); if (an == NULL) { an = pan; break; } x = an->start.pos; y = an->start.line; } } _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); } 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 */ void backBf(void) { Buffer *buf = Currentbuf->linkBuffer[LB_N_FRAME]; if (!checkBackBuffer(Currentbuf)) { disp_message("Can't back...", TRUE); return; } delBuffer(Currentbuf); if (buf) { if (buf->frameQ) { long linenumber; short pos; struct frameset *fs; fs = popFrameTree(&(buf->frameQ), &linenumber, &pos); deleteFrameSet(buf->frameset); buf->frameset = fs; if (buf == Currentbuf) { rFrame(); gotoLine(Currentbuf, linenumber); arrangeCursor(Currentbuf); } } else if (RenderFrame && buf == Currentbuf) { delBuffer(Currentbuf); } } clear(); displayBuffer(Currentbuf, B_FORCE_REDRAW); } void deletePrevBuf() { Buffer *buf = Currentbuf->nextBuffer; if (buf) delBuffer(buf); } static void cmd_loadURL(char *url, ParsedURL * current) { Buffer *buf; if (!strncasecmp(url, "mailto:", 7)) { /* invoke external mailer */ Str tmp; char *to = quoteShell(url + 7)->ptr; if (strcasestr(Mailer, "%s")) tmp = Sprintf(Mailer, to); else tmp = Strnew_m_charp(Mailer, " ", to, NULL); fmTerm(); system(tmp->ptr); fmInit(); displayBuffer(Currentbuf, B_FORCE_REDRAW); return; } #ifdef USE_NNTP else if (!strncasecmp(url, "news:", 5) && strchr(url, '@') == NULL) { /* news:newsgroup is not supported */ disp_err_message("news:newsgroup_name is not supported", TRUE); return; } #endif /* USE_NNTP */ /* message(Sprintf("loading %s\n", url)->ptr, 0, 0); */ refresh(); buf = loadGeneralFile(url, current, NO_REFERER, 0, NULL); if (buf == NULL) { char *emsg = Sprintf("Can't load %s\n", 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 */ void goURL(void) { char *url; ParsedURL p_url; url = searchKeyData(); if (url == NULL) { if (!(Currentbuf->bufferprop & BP_INTERNAL)) pushHashHist(URLHist, parsedURL2Str(&Currentbuf->currentURL)->ptr); url = inputLineHist("Goto URL: ", NULL, IN_URL, URLHist); if (url != NULL) SKIP_BLANKS(url); } if (url == NULL || *url == '\0') { displayBuffer(Currentbuf, B_FORCE_REDRAW); return; } if (*url == '#') { gotoLabel(url + 1); return; } parseURL2(url, &p_url, NULL); pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr); cmd_loadURL(url, baseURL(Currentbuf)); } static void cmd_loadBuffer(Buffer * buf, int prop, int link) { 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 (link != LB_NOLINK) { buf->linkBuffer[REV_LB[link]] = Currentbuf; Currentbuf->linkBuffer[link] = buf; } pushBuffer(buf); } displayBuffer(Currentbuf, B_FORCE_REDRAW); } /* load bookmark */ void ldBmark(void) { cmd_loadURL(BookmarkFile, NULL); } /* Add current to bookmark */ void adBmark(void) { Str url, title, tmp; /* cmd_loadBuffer(load_bookmark_panel(Currentbuf), BP_NO_URL, * * LB_NOLINK); */ url = form_quote(parsedURL2Str(&Currentbuf->currentURL)); title = form_quote(Strnew_charp(Currentbuf->buffername)); #ifdef __EMX__ tmp = Sprintf("%s/w3mbookmark.exe?mode=panel&bmark=%s&url=%s&title=%s", get_os2_dft("W3M_LIB_DIR", LIB_DIR), BookmarkFile, url->ptr, title->ptr); #else /* not __EMX__ */ tmp = Sprintf("%s/w3mbookmark?mode=panel&bmark=%s&url=%s&title=%s", LIB_DIR, BookmarkFile, url->ptr, title->ptr); #endif /* not __EMX__ */ cmd_loadURL(tmp->ptr, NULL); } /* option setting */ void ldOpt(void) { cmd_loadBuffer(load_option_panel(), BP_NO_URL, LB_NOLINK); } /* error message list */ void msgs(void) { cmd_loadBuffer(message_list_panel(), BP_NO_URL, LB_NOLINK); } /* page info */ void pginfo(void) { 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); #ifdef JP_CHARSET if (buf != NULL) buf->document_code = Currentbuf->document_code; #endif /* JP_CHARSET */ cmd_loadBuffer(buf, BP_NORMAL, LB_INFO); } void follow_map(struct parsed_tagarg *arg) { #ifdef MENU_MAP Anchor *a; char *url; int x; ParsedURL p_url; a = retrieveCurrentImg(Currentbuf); if (a != NULL) x = Currentbuf->cursorX - Currentbuf->pos + a->start.pos; else x = Currentbuf->cursorX; url = follow_map_menu(Currentbuf, arg, x, Currentbuf->cursorY + 2); if (url == NULL || *url == '\0') return; if (*url == '#') { gotoLabel(url + 1); return; } parseURL2(url, &p_url, baseURL(Currentbuf)); pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr); cmd_loadURL(url, baseURL(Currentbuf)); #else Buffer *buf; buf = follow_map_panel(Currentbuf, arg); if (buf != NULL) cmd_loadBuffer(buf, BP_NORMAL, LB_NOLINK); #endif } #ifdef USE_COOKIE /* cookie list */ void cooLst(void) { 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 */ void ldHist(void) { cmd_loadBuffer(historyBuffer(URLHist), BP_NO_URL, LB_NOLINK); } #endif /* USE_HISTORY */ /* download HREF link */ void svA(void) { CurrentKeyData = NULL; /* not allowed in w3m-control: */ do_download = TRUE; followA(); do_download = FALSE; } /* download IMG link */ void svI(void) { CurrentKeyData = NULL; /* not allowed in w3m-control: */ do_download = TRUE; followI(); do_download = FALSE; } /* save buffer */ void svBuf(void) { char *file; FILE *f; int is_pipe; CurrentKeyData = NULL; /* not allowed in w3m-control: */ file = searchKeyData(); if (file == NULL || *file == '\0') { file = inputLineHist("Save buffer to: ", NULL, IN_COMMAND, SaveHist); if (file == NULL || *file == '\0') { displayBuffer(Currentbuf, B_FORCE_REDRAW); return; } } if (*file == '|') { is_pipe = TRUE; f = popen(file + 1, "w"); } else { file = expandName(file); if (checkOverWrite(file) < 0) return; f = fopen(file, "w"); is_pipe = FALSE; } if (f == NULL) { char *emsg = Sprintf("Can't open %s\n", file)->ptr; disp_err_message(emsg, TRUE); return; } saveBuffer(Currentbuf, f); if (is_pipe) pclose(f); else fclose(f); displayBuffer(Currentbuf, B_NORMAL); } /* save source */ void svSrc(void) { if (Currentbuf->sourcefile == NULL) return; CurrentKeyData = NULL; /* not allowed in w3m-control: */ PermitSaveToPipe = TRUE; doFileCopy(Currentbuf->sourcefile, guess_save_name(Currentbuf->currentURL.file)); PermitSaveToPipe = FALSE; displayBuffer(Currentbuf, B_NORMAL); } static void _peekURL(int only_img){ Anchor *a; ParsedURL pu; static Str s = NULL; static int offset = 0; 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; } a = (only_img ? NULL : retrieveCurrentAnchor(Currentbuf)); if (a == NULL) { a = retrieveCurrentImg(Currentbuf); if (a == NULL) { a = retrieveCurrentForm(Currentbuf); if (a == NULL) return; s = Strnew_charp(form2str((FormItemList *) a->url)); goto disp; } } parseURL2(a->url, &pu, baseURL(Currentbuf)); s = parsedURL2Str(&pu); disp: if (PREC_NUM > 1 && s->length > (PREC_NUM - 1) * (COLS - 1)) disp_message_nomouse(&s->ptr[(PREC_NUM - 1) * (COLS - 1)], TRUE); else disp_message_nomouse(&s->ptr[offset], TRUE); } /* peek URL */ void peekURL(void) { _peekURL(0); } /* peek URL of image */ void peekIMG(void) { _peekURL(1); } /* show current URL */ static Str currentURL(void) { if (Currentbuf->bufferprop & BP_INTERNAL) return Strnew_size(0); return parsedURL2Str(&Currentbuf->currentURL); } void curURL(void) { static Str s = NULL; static int offset = 0; 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 (PREC_NUM > 1 && s->length > (PREC_NUM - 1) * (COLS - 1)) disp_message_nomouse(&s->ptr[(PREC_NUM - 1) * (COLS - 1)], TRUE); else disp_message_nomouse(&s->ptr[offset], TRUE); } /* view HTML source */ void vwSrc(void) { char *fn; 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")) { FILE *f; Str tmpf = tmpfname(TMPF_SRC, NULL); f = fopen(tmpf->ptr, "w"); if (f == NULL) return; saveBufferDelNum(Currentbuf, f, showLineNum); fclose(f); fn = tmpf->ptr; } else { return; } } else if (Currentbuf->real_scheme == SCM_LOCAL) { fn = Currentbuf->filename; } else { fn = Currentbuf->sourcefile; } if (!strcasecmp(Currentbuf->type, "text/html")) { #ifdef JP_CHARSET char old_code = DocumentCode; DocumentCode = Currentbuf->document_code; #endif buf = loadFile(fn); #ifdef JP_CHARSET DocumentCode = old_code; #endif if (buf == NULL) return; 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->bufferprop |= BP_SOURCE; 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")) { char *old_type = DefaultType; DefaultType = "text/html"; buf = loadGeneralFile(fn, NULL, NO_REFERER, 0, NULL); DefaultType = old_type; if (buf == NULL || buf == NO_BUFFER) return; if (Currentbuf->real_type && !strcasecmp(Currentbuf->real_type, "text/plain")) buf->real_type = "text/html"; else buf->real_type = Currentbuf->real_type; if (!strcmp(buf->buffername, mybasename(fn))) 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->sourcefile = Currentbuf->sourcefile; buf->clone = Currentbuf->clone; (*buf->clone)++; pushBuffer(buf); displayBuffer(Currentbuf, B_NORMAL); } /* reload */ void reload(void) { Buffer *buf, *fbuf = NULL; char *type = Currentbuf->type; Str url; int top, linenum, cursorY, pos, currentColumn; FormList *request; int multipart; if (Currentbuf->bufferprop & BP_INTERNAL) { disp_err_message("Can't reload...", FALSE); return; } if (Currentbuf->currentURL.scheme == SCM_LOCAL && !strcmp(Currentbuf->currentURL.file, "-")) { /* file is std input */ disp_err_message("Can't reload stdin", TRUE); return; } if (Currentbuf->firstLine == NULL) { top = 1; linenum = 1; } else { top = Currentbuf->topLine->linenumber; linenum = Currentbuf->currentLine->linenumber; } cursorY = Currentbuf->cursorY; pos = Currentbuf->pos; currentColumn = Currentbuf->currentColumn; if (Currentbuf->bufferprop & BP_FRAME && (fbuf = Currentbuf->linkBuffer[LB_N_FRAME])) { if (fmInitialized) { message("Rendering frame", 0, 0); refresh(); } if (!(buf = renderFrame(fbuf, 1))) 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 == NULL) { displayBuffer(Currentbuf, B_FORCE_REDRAW); return; } gotoLine(Currentbuf, linenum); Currentbuf->pos = pos; Currentbuf->currentColumn = currentColumn; arrangeCursor(Currentbuf); 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); message("Reloading...", 0, 0); refresh(); buf = loadGeneralFile(url->ptr, NULL, NO_REFERER, RG_NOCACHE, request); if (multipart) unlink(request->body); if (buf == NULL) { disp_err_message("Can't reload...", FALSE); return; } else if (buf == NO_BUFFER) { return; } buf->form_submit = Currentbuf->form_submit; if (fbuf != NULL) Firstbuf = deleteBuffer(Firstbuf, fbuf); repBuffer(Currentbuf, buf); if ((type != NULL) && (buf->type != NULL) && ((!strcasecmp(buf->type, "text/plain") && !strcasecmp(type, "text/html")) || (!strcasecmp(buf->type, "text/html") && !strcasecmp(type, "text/plain")))) { vwSrc(); if (Currentbuf != buf) Firstbuf = deleteBuffer(Firstbuf, buf); } if (Currentbuf->firstLine == NULL) { displayBuffer(Currentbuf, B_FORCE_REDRAW); return; } Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->firstLine, top - 1, FALSE); gotoLine(Currentbuf, linenum); Currentbuf->pos = pos; Currentbuf->currentColumn = currentColumn; arrangeCursor(Currentbuf); displayBuffer(Currentbuf, B_FORCE_REDRAW); } /* mark URL-like patterns as anchors */ void chkURL(void) { static char *url_like_pat[] = { "http://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$]*", #ifdef USE_SSL "https://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$]*", #endif /* USE_SSL */ #ifdef USE_GOPHER "gopher://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./_]*", #endif /* USE_GOPHER */ "ftp://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./=_+@#,\\$]*", #ifdef USE_NNTP "news:[^<> ][^<> ]*", "nntp://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./_]*", #endif /* USE_NNTP */ NULL, }; int i; for (i = 0; url_like_pat[i]; i++) { reAnchor(Currentbuf, url_like_pat[i]); } Currentbuf->check_url |= CHK_URL; displayBuffer(Currentbuf, B_FORCE_REDRAW); } #ifdef USE_NNTP /* mark Message-ID-like patterns as NEWS anchors */ void chkNMID(void) { static char *url_like_pat[] = { "<[^<> ][^<> ]*@[A-z0-9\\.\\-_][A-z0-9\\.\\-_]*>", NULL, }; int i; for (i = 0; url_like_pat[i]; i++) { reAnchorNews(Currentbuf, url_like_pat[i]); } Currentbuf->check_url |= CHK_NMID; displayBuffer(Currentbuf, B_FORCE_REDRAW); } #endif /* USE_NNTP */ /* render frame */ void rFrame(void) { 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) 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 tmp; char *browser = NULL; int bg = 0; 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 == '\0') return; } } url = quoteShell(url)->ptr; if (strcasestr(browser, "%s")) { tmp = Sprintf(browser, url); Strremovetrailingspaces(tmp); if (Strlastchar(tmp) == '&') { Strshrink(tmp, 1); bg = 1; } } else { tmp = Strnew_charp(browser); Strcat_char(tmp, ' '); Strcat_charp(tmp, url); } fmTerm(); mySystem(tmp->ptr, bg); fmInit(); displayBuffer(Currentbuf, B_FORCE_REDRAW); } void extbrz() { if (Currentbuf->bufferprop & BP_INTERNAL) { disp_err_message("Can't browse...", FALSE); return; } if (Currentbuf->currentURL.scheme == SCM_LOCAL && !strcmp(Currentbuf->currentURL.file, "-")) { /* file is std input */ disp_err_message("Can't browse stdin", TRUE); return; } invoke_browser(parsedURL2Str(&Currentbuf->currentURL)->ptr); } void linkbrz() { 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 */ void curlno() { Str tmp; int cur = 0, all, col, len = 0; if (Currentbuf->currentLine != NULL) { Line *l = Currentbuf->currentLine; cur = l->real_linenumber; if (l->width < 0) l->width = COLPOS(l, l->len); len = l->width; } col = Currentbuf->currentColumn + Currentbuf->cursorX + 1; all = (Currentbuf->lastLine ? Currentbuf->lastLine->real_linenumber : Currentbuf->allLine); if (all == 0 && Currentbuf->lastLine != NULL) all = Currentbuf->currentLine->real_linenumber; if (all == 0) all = 1; 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, cur * 100 / all, col, len); #ifdef JP_CHARSET Strcat_charp(tmp, " "); Strcat_charp(tmp, code_to_str(Currentbuf->document_code)); #endif /* not JP_CHARSET */ disp_message(tmp->ptr, FALSE); } #ifdef MOUSE /* Addition:mouse event */ #define MOUSE_BTN1_DOWN 0 #define MOUSE_BTN2_DOWN 1 #define MOUSE_BTN3_DOWN 2 #define MOUSE_BTN4_DOWN_RXVT 3 #define MOUSE_BTN5_DOWN_RXVT 4 #define MOUSE_BTN4_DOWN_XTERM 64 #define MOUSE_BTN5_DOWN_XTERM 65 #define MOUSE_BTN_UP 3 #define MOUSE_BTN_RESET -1 #define MOUSE_SCROLL_LINE 5 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; if (btn == MOUSE_BTN_UP) { switch (press_btn) { case MOUSE_BTN1_DOWN: if (press_x != x || press_y != y) { 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(); } } else { if (y == LASTLINE) { switch (x) { case 0: case 1: backBf(); break; case 2: case 3: pgBack(); break; case 4: case 5: pgFore(); break; } return; } if (y == Currentbuf->cursorY && (x == Currentbuf->cursorX #ifdef JP_CHARSET || (Currentbuf->currentLine != NULL && (Currentbuf->currentLine->propBuf[Currentbuf->pos] & PC_KANJI1) && x == Currentbuf->cursorX + 1) #endif /* JP_CHARSET */ )) { followA(); return; } cursorXY(Currentbuf, x, y); displayBuffer(Currentbuf, B_NORMAL); } break; case MOUSE_BTN2_DOWN: backBf(); break; case MOUSE_BTN3_DOWN: #ifdef MENU cursorXY(Currentbuf, x, y); onA(); mainMenu(x, y); #endif /* MENU */ 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; } } void msToggle(void) { if (use_mouse) { use_mouse = FALSE; } else { use_mouse = TRUE; } displayBuffer(Currentbuf, B_FORCE_REDRAW); } void mouse() { int btn, x, y; btn = (unsigned char) getch() - 32; 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, 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 */ #endif /* MOUSE */ void wrapToggle(void) { if (WrapSearch) { WrapSearch = FALSE; disp_message("Wrap search off", FALSE); } else { WrapSearch = TRUE; disp_message("Wrap search on", FALSE); } } #ifdef DICT static char * GetWord(Buffer * buf) { Line *l = buf->currentLine; char *lb = l->lineBuf; int i, b, e, pos = buf->pos; i = pos; while (!IS_ALPHA(lb[i]) && i >= 0) i--; pos = i; while (IS_ALPHA(lb[i]) && i >= 0) i--; i++; if (!IS_ALPHA(lb[i])) return NULL; b = i; i = pos; while (IS_ALPHA(lb[i]) && i <= l->len - 1) i++; e = i - 1; return Strnew_charp_n(&lb[b], e - b + 1)->ptr; } static void execdict(char *word) { Buffer *buf; Str cmd, bn; MySignalHandler(*prevtrap) (); if (word == NULL || *word == '\0') { displayBuffer(Currentbuf, B_NORMAL); return; } cmd = Strnew_charp(DICTCMD); Strcat_char(cmd, ' '); Strcat_charp(cmd, word); prevtrap = signal(SIGINT, intTrap); crmode(); buf = getshell(cmd->ptr); bn = Sprintf("%s %s", DICTBUFFERNAME, word); buf->buffername = bn->ptr; buf->filename = word; signal(SIGINT, prevtrap); term_raw(); if (buf == NULL) { disp_message("Execution failed", FALSE); } else if (buf->firstLine == NULL) { /* if the dictionary doesn't describe the word. */ disp_message(Sprintf("Word \"%s\" Not Found", word)->ptr, FALSE); } else { buf->bufferprop |= (BP_INTERNAL | BP_NO_URL); pushBuffer(buf); } displayBuffer(Currentbuf, B_FORCE_REDRAW); } void dictword(void) { execdict(inputStr("(dictionary)!", "")); } void dictwordat(void) { execdict(GetWord(Currentbuf)); } #endif /* DICT */ char * searchKeyData(void) { KeyListItem *item; if (CurrentKeyData != NULL && *CurrentKeyData != '\0') return allocStr(CurrentKeyData, 0); #ifdef MENU if (CurrentMenuData != NULL && *CurrentMenuData != '\0') return allocStr(CurrentMenuData, 0); #endif if (CurrentKey < 0) return NULL; item = searchKeyList(&w3mKeyList, CurrentKey); if (item == NULL || item->data == NULL || *item->data == '\0') return NULL; return allocStr(item->data, 0); } #if 0 static int searchKeyNum(void) { char *d; int n = 1; d = searchKeyData(); if (d != NULL) n = atoi(d); return n * PREC_NUM; } #endif