1
/* $Id: main.c,v 1.270 2010/08/24 10:11:51 htrb Exp $ */
10
#if defined(HAVE_WAITPID) || defined(HAVE_WAIT3)
28
#if defined(USE_GPM) || defined(USE_SYSMOUSE)
29
extern int do_getch();
30
#define getch() do_getch()
31
#endif /* defined(USE_GPM) || defined(USE_SYSMOUSE) */
34
#ifdef __MINGW32_VERSION
48
typedef struct _Event {
53
static Event *CurrentEvent = NULL;
54
static Event *LastEvent = NULL;
57
static AlarmEvent DefaultAlarm = {
58
0, AL_UNSET, FUNCNAME_nulcmd, NULL
60
static AlarmEvent *CurrentAlarm = &DefaultAlarm;
61
static MySignalHandler SigAlarm(SIGNAL_ARG);
65
static int need_resize_screen = FALSE;
66
static MySignalHandler resize_hook(SIGNAL_ARG);
67
static void resize_screen(void);
71
static MySignalHandler SigPipe(SIGNAL_ARG);
75
static char *MarkString = NULL;
77
static char *SearchString = NULL;
78
int (*searchRoutine) (Buffer *, char *);
80
#ifndef __MINGW32_VERSION
83
_JBTYPE IntReturn[_JBLEN];
84
#endif /* __MINGW32_VERSION */
86
static void delBuffer(Buffer *buf);
87
static void cmd_loadfile(char *path);
88
static void cmd_loadURL(char *url, ParsedURL *current, char *referer,
90
static void cmd_loadBuffer(Buffer *buf, int prop, int linkid);
91
static void keyPressEventProc(int c);
92
int show_params_p = 0;
93
void show_params(FILE * fp);
95
static char *getCurWord(Buffer *buf, int *spos, int *epos);
97
static int display_ok = FALSE;
98
static void do_dump(Buffer *);
102
static int add_download_list = FALSE;
104
void set_buffer_environ(Buffer *);
105
static void save_buffer_position(Buffer *buf);
107
static void _followForm(int);
108
static void _goLine(char *);
109
static void _newT(void);
110
static void followTab(TabBuffer * tab);
111
static void moveTab(TabBuffer * t, TabBuffer * t2, int right);
112
static void _nextA(int);
113
static void _prevA(int);
114
static int check_target = TRUE;
115
#define PREC_NUM (prec_num ? prec_num : 1)
116
#define PREC_LIMIT 10000
117
static int searchKeyNum(void);
119
#define help() fusage(stdout, 0)
120
#define usage() fusage(stderr, 1)
125
fprintf(f, "w3m version %s, options %s\n", w3m_version,
139
#ifdef USE_ANSI_COLOR
160
#ifdef USE_SSL_VERIFY
164
#ifdef USE_EXTERNAL_URI_LOADER
165
",external-uri-loader"
192
fusage(FILE * f, int err)
195
/* FIXME: gettextize? */
196
fprintf(f, "usage: w3m [options] [URL or filename]\noptions:\n");
197
fprintf(f, " -t tab set tab width\n");
198
fprintf(f, " -r ignore backspace effect\n");
199
fprintf(f, " -l line # of preserved line (default 10000)\n");
201
fprintf(f, " -I charset document charset\n");
202
fprintf(f, " -O charset display/output charset\n");
203
#if 0 /* use -O{s|j|e} instead */
204
fprintf(f, " -e EUC-JP\n");
205
fprintf(f, " -s Shift_JIS\n");
206
fprintf(f, " -j JIS\n");
209
fprintf(f, " -B load bookmark\n");
210
fprintf(f, " -bookmark file specify bookmark file\n");
211
fprintf(f, " -T type specify content-type\n");
212
fprintf(f, " -m internet message mode\n");
213
fprintf(f, " -v visual startup mode\n");
215
fprintf(f, " -M monochrome display\n");
216
#endif /* USE_COLOR */
218
" -N open URL of command line on each new tab\n");
219
fprintf(f, " -F automatically render frame\n");
221
" -cols width specify column width (used with -dump)\n");
223
" -ppc count specify the number of pixels per character (4.0...32.0)\n");
226
" -ppl count specify the number of pixels per line (4.0...64.0)\n");
228
fprintf(f, " -dump dump formatted page into stdout\n");
230
" -dump_head dump response of HEAD request into stdout\n");
231
fprintf(f, " -dump_source dump page source into stdout\n");
232
fprintf(f, " -dump_both dump HEAD and source into stdout\n");
234
" -dump_extra dump HEAD, source, and extra information into stdout\n");
235
fprintf(f, " -post file use POST method with file content\n");
236
fprintf(f, " -header string insert string as a header\n");
237
fprintf(f, " +<num> goto <num> line\n");
238
fprintf(f, " -num show line number\n");
239
fprintf(f, " -no-proxy don't use proxy\n");
241
fprintf(f, " -4 IPv4 only (-o dns_order=4)\n");
242
fprintf(f, " -6 IPv6 only (-o dns_order=6)\n");
245
fprintf(f, " -no-mouse don't use mouse\n");
246
#endif /* USE_MOUSE */
249
" -cookie use cookie (-no-cookie: don't use cookie)\n");
250
#endif /* USE_COOKIE */
251
fprintf(f, " -graph use DEC special graphics for border of table and menu\n");
252
fprintf(f, " -no-graph use ACII character for border of table and menu\n");
253
#if 1 /* pager requires -s */
254
fprintf(f, " -s squeeze multiple blank lines\n");
256
fprintf(f, " -S squeeze multiple blank lines\n");
258
fprintf(f, " -W toggle wrap search mode\n");
259
fprintf(f, " -X don't use termcap init/deinit\n");
261
" -title[=TERM] set buffer name to terminal title string\n");
262
fprintf(f, " -o opt=value assign value to config option\n");
263
fprintf(f, " -show-option print all config options\n");
264
fprintf(f, " -config file specify config file\n");
265
fprintf(f, " -help print this usage message\n");
266
fprintf(f, " -version print w3m version\n");
267
fprintf(f, " -reqlog write request logfile\n");
268
fprintf(f, " -debug DO NOT USE\n");
276
static char *getCodePage(void);
280
static GC_warn_proc orig_GC_warn_proc = NULL;
281
#define GC_WARN_KEEP_MAX (20)
284
wrap_GC_warn_proc(char *msg, GC_word arg)
291
} msg_ring[GC_WARN_KEEP_MAX];
298
j = (i + n) % (sizeof(msg_ring) / sizeof(msg_ring[0]));
299
msg_ring[j].msg = msg;
300
msg_ring[j].arg = arg;
302
if (n < sizeof(msg_ring) / sizeof(msg_ring[0]))
310
for (; n > 0; --n, ++i) {
311
i %= sizeof(msg_ring) / sizeof(msg_ring[0]);
313
printf(msg_ring[i].msg, (unsigned long)msg_ring[i].arg);
314
sleep_till_anykey(1, 1);
320
#if GC_VERSION_MAJOR >= 7 && GC_VERSION_MINOR >= 2
321
else if (orig_GC_warn_proc = GC_get_warn_proc())
323
else if (orig_GC_warn_proc)
325
orig_GC_warn_proc(msg, arg);
327
fprintf(stderr, msg, (unsigned long)arg);
338
while ((pid = waitpid(-1, &p_stat, WNOHANG)) > 0)
340
while ((pid = wait3(&p_stat, WNOHANG, NULL)) > 0)
342
if ((pid = wait(&p_stat)) > 0)
347
if (WIFEXITED(p_stat)) {
348
for (d = FirstDL; d != NULL; d = d->next) {
350
d->err = WEXITSTATUS(p_stat);
356
mySignal(SIGCHLD, sig_chld);
362
make_optional_header_string(char *s)
367
if (strchr(s, '\n') || strchr(s, '\r'))
369
for (p = s; *p && *p != ':'; p++) ;
370
if (*p != ':' || p == s)
372
hs = Strnew_size(strlen(s) + 3);
373
Strcopy_charp_n(hs, s, p - s);
374
if (!Strcasecmp_charp(hs, "content-type"))
375
override_content_type = TRUE;
376
Strcat_charp(hs, ": ");
377
if (*(++p)) { /* not null header */
378
SKIP_BLANKS(p); /* skip white spaces */
381
Strcat_charp(hs, "\r\n");
386
main(int argc, char **argv, char **envp)
388
Buffer *newbuf = NULL;
392
char *line_str = NULL;
396
int load_bookmark = FALSE;
397
int visual_start = FALSE;
398
int open_new_tab = FALSE;
399
char search_header = FALSE;
400
char *default_type = NULL;
401
char *post_file = NULL;
405
wc_uint8 auto_detect;
411
#if defined(ENABLE_NLS) || (defined(USE_M17N) && defined(HAVE_LANGINFO_CODESET))
412
setlocale(LC_ALL, "");
415
bindtextdomain(PACKAGE, LOCALEDIR);
419
#ifndef HAVE_SYS_ERRLIST
420
prepare_sys_errlist();
421
#endif /* not HAVE_SYS_ERRLIST */
423
NO_proxy_domains = newTextList();
424
fileToDelete = newTextList();
426
load_argv = New_N(char *, argc - 1);
429
CurrentDir = currentdir();
430
CurrentPid = (int)getpid();
434
/* argument search 1 */
435
for (i = 1; i < argc; i++) {
436
if (*argv[i] == '-') {
437
if (!strcmp("-config", argv[i])) {
441
config_file = argv[i];
444
else if (!strcmp("-h", argv[i]) || !strcmp("-help", argv[i]))
446
else if (!strcmp("-V", argv[i]) || !strcmp("-version", argv[i])) {
454
if (non_null(Locale = getenv("LC_ALL")) ||
455
non_null(Locale = getenv("LC_CTYPE")) ||
456
non_null(Locale = getenv("LANG"))) {
457
DisplayCharset = wc_guess_locale_charset(Locale, DisplayCharset);
458
DocumentCharset = wc_guess_locale_charset(Locale, DocumentCharset);
459
SystemCharset = wc_guess_locale_charset(Locale, SystemCharset);
462
CodePage = wc_guess_charset(getCodePage(), 0);
464
DisplayCharset = DocumentCharset = SystemCharset = CodePage;
468
/* initializations */
471
LoadHist = newHist();
472
SaveHist = newHist();
473
ShellHist = newHist();
474
TextHist = newHist();
478
if (FollowLocale && Locale) {
479
DisplayCharset = wc_guess_locale_charset(Locale, DisplayCharset);
480
SystemCharset = wc_guess_locale_charset(Locale, SystemCharset);
482
auto_detect = WcOption.auto_detect;
483
BookmarkCharset = DocumentCharset;
486
if (!non_null(HTTP_proxy) &&
487
((p = getenv("HTTP_PROXY")) ||
488
(p = getenv("http_proxy")) || (p = getenv("HTTP_proxy"))))
491
if (!non_null(HTTPS_proxy) &&
492
((p = getenv("HTTPS_PROXY")) ||
493
(p = getenv("https_proxy")) || (p = getenv("HTTPS_proxy"))))
495
if (HTTPS_proxy == NULL && non_null(HTTP_proxy))
496
HTTPS_proxy = HTTP_proxy;
499
if (!non_null(GOPHER_proxy) &&
500
((p = getenv("GOPHER_PROXY")) ||
501
(p = getenv("gopher_proxy")) || (p = getenv("GOPHER_proxy"))))
503
#endif /* USE_GOPHER */
504
if (!non_null(FTP_proxy) &&
505
((p = getenv("FTP_PROXY")) ||
506
(p = getenv("ftp_proxy")) || (p = getenv("FTP_proxy"))))
508
if (!non_null(NO_proxy) &&
509
((p = getenv("NO_PROXY")) ||
510
(p = getenv("no_proxy")) || (p = getenv("NO_proxy"))))
513
if (!non_null(NNTP_server) && (p = getenv("NNTPSERVER")) != NULL)
515
if (!non_null(NNTP_mode) && (p = getenv("NNTPMODE")) != NULL)
519
if (!non_null(Editor) && (p = getenv("EDITOR")) != NULL)
521
if (!non_null(Mailer) && (p = getenv("MAILER")) != NULL)
524
/* argument search 2 */
527
if (*argv[i] == '-') {
528
if (!strcmp("-t", argv[i])) {
531
if (atoi(argv[i]) > 0)
532
Tabstop = atoi(argv[i]);
534
else if (!strcmp("-r", argv[i]))
536
else if (!strcmp("-l", argv[i])) {
539
if (atoi(argv[i]) > 0)
540
PagerMax = atoi(argv[i]);
543
#if 0 /* use -O{s|j|e} instead */
544
else if (!strcmp("-s", argv[i]))
545
DisplayCharset = WC_CES_SHIFT_JIS;
546
else if (!strcmp("-j", argv[i]))
547
DisplayCharset = WC_CES_ISO_2022_JP;
548
else if (!strcmp("-e", argv[i]))
549
DisplayCharset = WC_CES_EUC_JP;
551
else if (!strncmp("-I", argv[i], 2)) {
552
if (argv[i][2] != '\0')
559
DocumentCharset = wc_guess_charset_short(p, DocumentCharset);
560
WcOption.auto_detect = WC_OPT_DETECT_OFF;
561
UseContentCharset = FALSE;
563
else if (!strncmp("-O", argv[i], 2)) {
564
if (argv[i][2] != '\0')
571
DisplayCharset = wc_guess_charset_short(p, DisplayCharset);
574
else if (!strcmp("-graph", argv[i]))
575
UseGraphicChar = GRAPHIC_CHAR_DEC;
576
else if (!strcmp("-no-graph", argv[i]))
577
UseGraphicChar = GRAPHIC_CHAR_ASCII;
578
else if (!strcmp("-T", argv[i])) {
581
DefaultType = default_type = argv[i];
583
else if (!strcmp("-m", argv[i]))
584
SearchHeader = search_header = TRUE;
585
else if (!strcmp("-v", argv[i]))
587
else if (!strcmp("-N", argv[i]))
590
else if (!strcmp("-M", argv[i]))
592
#endif /* USE_COLOR */
593
else if (!strcmp("-B", argv[i]))
594
load_bookmark = TRUE;
595
else if (!strcmp("-bookmark", argv[i])) {
598
BookmarkFile = argv[i];
599
if (BookmarkFile[0] != '~' && BookmarkFile[0] != '/') {
600
Str tmp = Strnew_charp(CurrentDir);
601
if (Strlastchar(tmp) != '/')
602
Strcat_char(tmp, '/');
603
Strcat_charp(tmp, BookmarkFile);
604
BookmarkFile = cleanupName(tmp->ptr);
607
else if (!strcmp("-F", argv[i]))
609
else if (!strcmp("-W", argv[i])) {
615
else if (!strcmp("-dump", argv[i]))
616
w3m_dump = DUMP_BUFFER;
617
else if (!strcmp("-dump_source", argv[i]))
618
w3m_dump = DUMP_SOURCE;
619
else if (!strcmp("-dump_head", argv[i]))
620
w3m_dump = DUMP_HEAD;
621
else if (!strcmp("-dump_both", argv[i]))
622
w3m_dump = (DUMP_HEAD | DUMP_SOURCE);
623
else if (!strcmp("-dump_extra", argv[i]))
624
w3m_dump = (DUMP_HEAD | DUMP_SOURCE | DUMP_EXTRA);
625
else if (!strcmp("-halfdump", argv[i]))
626
w3m_dump = DUMP_HALFDUMP;
627
else if (!strcmp("-halfload", argv[i])) {
630
DefaultType = default_type = "text/html";
632
else if (!strcmp("-backend", argv[i])) {
635
else if (!strcmp("-backend_batch", argv[i])) {
639
if (!backend_batch_commands)
640
backend_batch_commands = newTextList();
641
pushText(backend_batch_commands, argv[i]);
643
else if (!strcmp("-cols", argv[i])) {
646
COLS = atoi(argv[i]);
647
if (COLS > MAXIMUM_COLS) {
651
else if (!strcmp("-ppc", argv[i])) {
656
if (ppc >= MINIMUM_PIXEL_PER_CHAR &&
657
ppc <= MAXIMUM_PIXEL_PER_CHAR) {
658
pixel_per_char = ppc;
659
set_pixel_per_char = TRUE;
663
else if (!strcmp("-ppl", argv[i])) {
668
if (ppc >= MINIMUM_PIXEL_PER_CHAR &&
669
ppc <= MAXIMUM_PIXEL_PER_CHAR * 2) {
670
pixel_per_line = ppc;
671
set_pixel_per_line = TRUE;
675
else if (!strcmp("-num", argv[i]))
677
else if (!strcmp("-no-proxy", argv[i]))
680
else if (!strcmp("-4", argv[i]) || !strcmp("-6", argv[i]))
681
set_param_option(Sprintf("dns_order=%c", argv[i][1])->ptr);
683
else if (!strcmp("-post", argv[i])) {
688
else if (!strcmp("-header", argv[i])) {
692
if ((hs = make_optional_header_string(argv[i])) != NULL) {
693
if (header_string == NULL)
696
Strcat(header_string, hs);
704
else if (!strcmp("-no-mouse", argv[i])) {
707
#endif /* USE_MOUSE */
709
else if (!strcmp("-no-cookie", argv[i])) {
711
accept_cookie = FALSE;
713
else if (!strcmp("-cookie", argv[i])) {
715
accept_cookie = TRUE;
717
#endif /* USE_COOKIE */
718
#if 1 /* pager requires -s */
719
else if (!strcmp("-s", argv[i]))
721
else if (!strcmp("-S", argv[i]))
723
squeezeBlankLine = TRUE;
724
else if (!strcmp("-X", argv[i]))
725
Do_not_use_ti_te = TRUE;
726
else if (!strcmp("-title", argv[i]))
727
displayTitleTerm = getenv("TERM");
728
else if (!strncmp("-title=", argv[i], 7))
729
displayTitleTerm = argv[i] + 7;
730
else if (!strcmp("-o", argv[i]) ||
731
!strcmp("-show-option", argv[i])) {
732
if (!strcmp("-show-option", argv[i]) || ++i >= argc ||
733
!strcmp(argv[i], "?")) {
737
if (!set_param_option(argv[i])) {
738
/* option set failed */
739
/* FIXME: gettextize? */
740
fprintf(stderr, "%s: bad option\n", argv[i]);
745
else if (!strcmp("-dummy", argv[i])) {
748
else if (!strcmp("-debug", argv[i])) {
751
else if (!strcmp("-reqlog",argv[i])) {
752
w3m_reqlog=rcFile("request.log");
758
else if (*argv[i] == '+') {
759
line_str = argv[i] + 1;
762
load_argv[load_argc++] = argv[i];
773
#ifdef __MINGW32_VERSION
778
wVerReq = MAKEWORD(1, 1);
780
err = WSAStartup(wVerReq, &WSAData);
783
fprintf(stderr, "Can't find winsock\n");
795
if (BookmarkFile == NULL)
796
BookmarkFile = rcFile(BOOKMARK);
798
if (!isatty(1) && !w3m_dump) {
799
/* redirected output */
800
w3m_dump = DUMP_BUFFER;
807
#ifdef USE_BINMODE_STREAM
808
setmode(fileno(stdout), O_BINARY);
810
if (!w3m_dump && !w3m_backend) {
813
mySignal(SIGWINCH, resize_hook);
814
#else /* not SIGWINCH */
817
#endif /* not SIGWINCH */
820
else if (w3m_halfdump && displayImage)
827
#endif /* USE_COOKIE */
830
loadHistory(URLHist);
831
#endif /* not USE_HISTORY */
834
wtf_init(DocumentCharset, DisplayCharset);
836
* WcOption.pre_conv = WC_TRUE;
844
mySignal(SIGINT, SIG_IGN);
846
mySignal(SIGCHLD, sig_chld);
849
mySignal(SIGPIPE, SigPipe);
852
#if GC_VERSION_MAJOR >= 7 && GC_VERSION_MINOR >= 2
853
GC_set_warn_proc(wrap_GC_warn_proc);
855
orig_GC_warn_proc = GC_set_warn_proc(wrap_GC_warn_proc);
858
if (load_argc == 0) {
859
/* no URL specified */
861
redin = newFileStream(fdopen(dup(0), "rb"), (void (*)())pclose);
862
newbuf = openGeneralPagerBuffer(redin);
865
else if (load_bookmark) {
866
newbuf = loadGeneralFile(BookmarkFile, NULL, NO_REFERER, 0, NULL);
868
Strcat_charp(err_msg, "w3m: Can't load bookmark.\n");
870
else if (visual_start) {
871
/* FIXME: gettextize? */
875
("<title>W3M startup page</title><center><b>Welcome to ");
876
Strcat_charp(s_page, "<a href='http://w3m.sourceforge.net/'>");
877
Strcat_m_charp(s_page,
878
"w3m</a>!<p><p>This is w3m version ",
880
"<br>Written by <a href='mailto:aito@fw.ipsj.or.jp'>Akinori Ito</a>",
882
newbuf = loadHTMLString(s_page);
884
Strcat_charp(err_msg, "w3m: Can't load string.\n");
885
else if (newbuf != NO_BUFFER)
886
newbuf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
888
else if ((p = getenv("HTTP_HOME")) != NULL ||
889
(p = getenv("WWW_HOME")) != NULL) {
890
newbuf = loadGeneralFile(p, NULL, NO_REFERER, 0, NULL);
892
Strcat(err_msg, Sprintf("w3m: Can't load %s.\n", p));
893
else if (newbuf != NO_BUFFER)
894
pushHashHist(URLHist, parsedURL2Str(&newbuf->currentURL)->ptr);
901
if (newbuf == NULL) {
905
fprintf(stderr, "%s", err_msg->ptr);
913
for (; i < load_argc; i++) {
915
SearchHeader = search_header;
916
DefaultType = default_type;
920
if (getURLScheme(&url) == SCM_MISSING && !ArgvIsURL)
921
url = file_to_url(load_argv[i]);
923
url = url_encode(conv_from_system(load_argv[i]), NULL, 0);
924
if (w3m_dump == DUMP_HEAD) {
925
request = New(FormList);
926
request->method = FORM_METHOD_HEAD;
927
newbuf = loadGeneralFile(url, NULL, NO_REFERER, 0, request);
930
if (post_file && i == 0) {
933
if (!strcmp(post_file, "-"))
936
fp = fopen(post_file, "r");
938
/* FIXME: gettextize? */
940
Sprintf("w3m: Can't open %s.\n", post_file));
943
body = Strfgetall(fp);
947
newFormList(NULL, "post", NULL, NULL, NULL, NULL,
949
request->body = body->ptr;
950
request->boundary = NULL;
951
request->length = body->length;
956
newbuf = loadGeneralFile(url, NULL, NO_REFERER, 0, request);
958
if (newbuf == NULL) {
959
/* FIXME: gettextize? */
961
Sprintf("w3m: Can't load %s.\n", load_argv[i]));
964
else if (newbuf == NO_BUFFER)
966
switch (newbuf->real_scheme) {
971
unshiftHist(LoadHist, url);
973
pushHashHist(URLHist, parsedURL2Str(&newbuf->currentURL)->ptr);
977
else if (newbuf == NO_BUFFER)
979
if (newbuf->pagerSource ||
980
(newbuf->real_scheme == SCM_LOCAL && newbuf->header_source &&
981
newbuf->currentURL.file && strcmp(newbuf->currentURL.file, "-")))
982
newbuf->search_header = search_header;
983
if (CurrentTab == NULL) {
984
FirstTab = LastTab = CurrentTab = newTab();
986
Firstbuf = Currentbuf = newbuf;
988
else if (open_new_tab) {
990
Currentbuf->nextBuffer = newbuf;
991
delBuffer(Currentbuf);
994
Currentbuf->nextBuffer = newbuf;
997
if (!w3m_dump || w3m_dump == DUMP_BUFFER) {
998
if (Currentbuf->frameset != NULL && RenderFrame)
1002
do_dump(Currentbuf);
1004
Currentbuf = newbuf;
1011
if (err_msg->length)
1012
fprintf(stderr, "%s", err_msg->ptr);
1015
#endif /* USE_COOKIE */
1019
if (add_download_list) {
1020
add_download_list = FALSE;
1021
CurrentTab = LastTab;
1023
FirstTab = LastTab = CurrentTab = newTab();
1026
if (!Firstbuf || Firstbuf == NO_BUFFER) {
1027
Firstbuf = Currentbuf = newBuffer(INIT_BUFFER_WIDTH);
1028
Currentbuf->bufferprop = BP_INTERNAL | BP_NO_URL;
1029
Currentbuf->buffername = DOWNLOAD_LIST_TITLE;
1032
Currentbuf = Firstbuf;
1036
CurrentTab = FirstTab;
1037
if (!FirstTab || !Firstbuf || Firstbuf == NO_BUFFER) {
1038
if (newbuf == NO_BUFFER) {
1040
/* FIXME: gettextize? */
1041
inputChar("Hit any key to quit w3m:");
1045
if (err_msg->length)
1046
fprintf(stderr, "%s", err_msg->ptr);
1047
if (newbuf == NO_BUFFER) {
1050
#endif /* USE_COOKIE */
1051
if (!err_msg->length)
1056
if (err_msg->length)
1057
disp_message_nsec(err_msg->ptr, FALSE, 1, TRUE, FALSE);
1059
SearchHeader = FALSE;
1062
UseContentCharset = TRUE;
1063
WcOption.auto_detect = auto_detect;
1066
Currentbuf = Firstbuf;
1067
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1072
if (add_download_list) {
1073
add_download_list = FALSE;
1076
if (Currentbuf->submit) {
1077
Anchor *a = Currentbuf->submit;
1078
Currentbuf->submit = NULL;
1079
gotoLine(Currentbuf, a->start.line);
1080
Currentbuf->pos = a->start.pos;
1084
/* event processing */
1087
CurrentKeyData = NULL;
1088
CurrentCmdData = (char *)CurrentEvent->data;
1089
w3mFuncList[CurrentEvent->cmd].func();
1090
CurrentCmdData = NULL;
1091
CurrentEvent = CurrentEvent->next;
1094
/* get keypress event */
1096
if (Currentbuf->event) {
1097
if (Currentbuf->event->status != AL_UNSET) {
1098
CurrentAlarm = Currentbuf->event;
1099
if (CurrentAlarm->sec == 0) { /* refresh (0sec) */
1100
Currentbuf->event = NULL;
1102
CurrentKeyData = NULL;
1103
CurrentCmdData = (char *)CurrentAlarm->data;
1104
w3mFuncList[CurrentAlarm->cmd].func();
1105
CurrentCmdData = NULL;
1110
Currentbuf->event = NULL;
1112
if (!Currentbuf->event)
1113
CurrentAlarm = &DefaultAlarm;
1116
mouse_action.in_action = FALSE;
1119
#endif /* USE_MOUSE */
1121
if (CurrentAlarm->sec > 0) {
1122
mySignal(SIGALRM, SigAlarm);
1123
alarm(CurrentAlarm->sec);
1127
mySignal(SIGWINCH, resize_hook);
1130
if (activeImage && displayImage && Currentbuf->img &&
1131
!Currentbuf->image_loaded) {
1134
if (need_resize_screen)
1137
loadImage(Currentbuf, IMG_FLAG_NEXT);
1138
} while (sleep_till_anykey(1, 0) <= 0);
1147
if (need_resize_screen)
1149
} while (sleep_till_anykey(1, 0) <= 0);
1154
if (CurrentAlarm->sec > 0) {
1161
#endif /* USE_MOUSE */
1162
if (IS_ASCII(c)) { /* Ascii */
1163
if (('0' <= c) && (c <= '9') &&
1164
(prec_num || (GlobalKeymap[c] == FUNCNAME_nulcmd))) {
1165
prec_num = prec_num * 10 + (int)(c - '0');
1166
if (prec_num > PREC_LIMIT)
1167
prec_num = PREC_LIMIT;
1170
set_buffer_environ(Currentbuf);
1171
save_buffer_position(Currentbuf);
1172
keyPressEventProc((int)c);
1176
prev_key = CurrentKey;
1178
CurrentKeyData = NULL;
1183
keyPressEventProc(int c)
1186
w3mFuncList[(int)GlobalKeymap[c]].func();
1190
pushEvent(int cmd, void *data)
1199
LastEvent->next = event;
1201
CurrentEvent = event;
1206
dump_source(Buffer *buf)
1210
if (buf->sourcefile == NULL)
1212
f = fopen(buf->sourcefile, "r");
1215
while (c = fgetc(f), !feof(f)) {
1222
dump_head(Buffer *buf)
1226
if (buf->document_header == NULL) {
1227
if (w3m_dump & DUMP_EXTRA)
1231
for (ti = buf->document_header->first; ti; ti = ti->next) {
1234
wc_conv_strict(ti->ptr, InnerCharset,
1235
buf->document_charset)->ptr);
1237
printf("%s", ti->ptr);
1244
dump_extra(Buffer *buf)
1246
printf("W3m-current-url: %s\n", parsedURL2Str(&buf->currentURL)->ptr);
1248
printf("W3m-base-url: %s\n", parsedURL2Str(buf->baseURL)->ptr);
1250
printf("W3m-document-charset: %s\n",
1251
wc_ces_to_charset(buf->document_charset));
1254
if (buf->ssl_certificate) {
1257
for (p = buf->ssl_certificate; *p; p++) {
1258
Strcat_char(tmp, *p);
1260
for (; *(p + 1) == '\n'; p++) ;
1262
Strcat_char(tmp, '\t');
1265
if (Strlastchar(tmp) != '\n')
1266
Strcat_char(tmp, '\n');
1267
printf("W3m-ssl-certificate: %s", tmp->ptr);
1273
cmp_anchor_hseq(const void *a, const void *b)
1275
return (*((const Anchor **) a))->hseq - (*((const Anchor **) b))->hseq;
1279
do_dump(Buffer *buf)
1281
MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
1283
prevtrap = mySignal(SIGINT, intTrap);
1284
if (SETJMP(IntReturn) != 0) {
1285
mySignal(SIGINT, prevtrap);
1288
if (w3m_dump & DUMP_EXTRA)
1290
if (w3m_dump & DUMP_HEAD)
1292
if (w3m_dump & DUMP_SOURCE)
1294
if (w3m_dump == DUMP_BUFFER) {
1296
saveBuffer(buf, stdout, FALSE);
1297
if (displayLinkNumber && buf->href) {
1298
int nanchor = buf->href->nanchor;
1299
printf("\nReferences:\n\n");
1300
Anchor **in_order = New_N(Anchor *, buf->href->nanchor);
1301
for (i = 0; i < nanchor; i++)
1302
in_order[i] = buf->href->anchors + i;
1303
qsort(in_order, nanchor, sizeof(Anchor *), cmp_anchor_hseq);
1304
for (i = 0; i < nanchor; i++) {
1307
if (in_order[i]->slave)
1309
parseURL2(in_order[i]->url, &pu, baseURL(buf));
1310
url = url_decode2(parsedURL2Str(&pu)->ptr, Currentbuf);
1311
printf("[%d] %s\n", in_order[i]->hseq + 1, url);
1315
mySignal(SIGINT, prevtrap);
1318
DEFUN(nulcmd, NOTHING NULL @@@, "Do nothing")
1323
DEFUN(pcmap, PCMAP, "pcmap")
1325
w3mFuncList[(int)PcKeymap[(int)getch()]].func();
1327
#else /* not __EMX__ */
1335
escKeyProc(int c, int esc, unsigned char *map)
1337
if (CurrentKey >= 0 && CurrentKey & K_MULTI) {
1338
unsigned char **mmap;
1339
mmap = (unsigned char **)getKeyData(MULTI_KEY(CurrentKey));
1356
esc |= (CurrentKey & ~0xFFFF);
1358
CurrentKey = esc | c;
1359
w3mFuncList[(int)map[c]].func();
1362
DEFUN(escmap, ESCMAP, "ESC map")
1367
escKeyProc((int)c, K_ESC, EscKeymap);
1370
DEFUN(escbmap, ESCBMAP, "ESC [ map")
1379
escKeyProc((int)c, K_ESCB, EscBKeymap);
1386
d = (int)c - (int)'0';
1389
d = d * 10 + (int)c - (int)'0';
1393
escKeyProc((int)d, K_ESCD, EscDKeymap);
1396
DEFUN(multimap, MULTIMAP, "multimap")
1401
CurrentKey = K_MULTI | (CurrentKey << 16) | c;
1402
escKeyProc((int)c, 0, NULL);
1407
tmpClearBuffer(Buffer *buf)
1409
if (buf->pagerSource == NULL && writeBufferCache(buf) == 0) {
1410
buf->firstLine = NULL;
1411
buf->topLine = NULL;
1412
buf->currentLine = NULL;
1413
buf->lastLine = NULL;
1417
static Str currentURL(void);
1427
if ((fp = fopen(rcFile("bufinfo"), "w")) == NULL) {
1430
fprintf(fp, "%s\n", currentURL()->ptr);
1436
pushBuffer(Buffer *buf)
1441
deleteImage(Currentbuf);
1444
tmpClearBuffer(Currentbuf);
1445
if (Firstbuf == Currentbuf) {
1446
buf->nextBuffer = Firstbuf;
1447
Firstbuf = Currentbuf = buf;
1449
else if ((b = prevBuffer(Firstbuf, Currentbuf)) != NULL) {
1450
b->nextBuffer = buf;
1451
buf->nextBuffer = Currentbuf;
1461
delBuffer(Buffer *buf)
1465
if (Currentbuf == buf)
1466
Currentbuf = buf->nextBuffer;
1467
Firstbuf = deleteBuffer(Firstbuf, buf);
1469
Currentbuf = Firstbuf;
1473
repBuffer(Buffer *oldbuf, Buffer *buf)
1475
Firstbuf = replaceBuffer(Firstbuf, oldbuf, buf);
1482
{ /* Interrupt catcher */
1483
LONGJMP(IntReturn, 0);
1488
static MySignalHandler
1489
resize_hook(SIGNAL_ARG)
1491
need_resize_screen = TRUE;
1492
mySignal(SIGWINCH, resize_hook);
1499
need_resize_screen = FALSE;
1503
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1505
#endif /* SIGWINCH */
1508
static MySignalHandler
1514
mySignal(SIGPIPE, SigPipe);
1520
* Command functions: These functions are called with a keystroke.
1524
nscroll(int n, int mode)
1526
Buffer *buf = Currentbuf;
1527
Line *top = buf->topLine, *cur = buf->currentLine;
1528
int lnum, tlnum, llnum, diff_n;
1530
if (buf->firstLine == NULL)
1532
lnum = cur->linenumber;
1533
buf->topLine = lineSkip(buf, top, n, FALSE);
1534
if (buf->topLine == top) {
1536
if (lnum < buf->topLine->linenumber)
1537
lnum = buf->topLine->linenumber;
1538
else if (lnum > buf->lastLine->linenumber)
1539
lnum = buf->lastLine->linenumber;
1542
tlnum = buf->topLine->linenumber;
1543
llnum = buf->topLine->linenumber + buf->LINES - 1;
1544
if (nextpage_topline)
1547
diff_n = n - (tlnum - top->linenumber);
1549
lnum = tlnum + diff_n;
1551
lnum = llnum + diff_n;
1553
gotoLine(buf, lnum);
1556
if (buf->currentLine->bpos &&
1557
buf->currentLine->bwidth >= buf->currentColumn + buf->visualpos)
1560
while (buf->currentLine->next && buf->currentLine->next->bpos &&
1561
buf->currentLine->bwidth + buf->currentLine->width <
1562
buf->currentColumn + buf->visualpos)
1563
cursorDown0(buf, 1);
1567
if (buf->currentLine->bwidth + buf->currentLine->width <
1568
buf->currentColumn + buf->visualpos)
1571
while (buf->currentLine->prev && buf->currentLine->bpos &&
1572
buf->currentLine->bwidth >=
1573
buf->currentColumn + buf->visualpos)
1577
displayBuffer(buf, mode);
1580
/* Move page forward */
1581
DEFUN(pgFore, NEXT_PAGE, "Move to next page")
1584
nscroll(searchKeyNum() * (Currentbuf->LINES - 1), B_NORMAL);
1586
nscroll(prec_num ? searchKeyNum() : searchKeyNum()
1587
* (Currentbuf->LINES - 1), prec_num ? B_SCROLL : B_NORMAL);
1590
/* Move page backward */
1591
DEFUN(pgBack, PREV_PAGE, "Move to previous page")
1594
nscroll(-searchKeyNum() * (Currentbuf->LINES - 1), B_NORMAL);
1596
nscroll(-(prec_num ? searchKeyNum() : searchKeyNum()
1597
* (Currentbuf->LINES - 1)), prec_num ? B_SCROLL : B_NORMAL);
1600
/* Move half page forward */
1601
DEFUN(hpgFore, NEXT_HALF_PAGE, "Scroll down half page")
1603
nscroll(searchKeyNum() * (Currentbuf->LINES / 2 - 1), B_NORMAL);
1606
/* Move half page backward */
1607
DEFUN(hpgBack, PREV_HALF_PAGE, "Scroll up half page")
1609
nscroll(-searchKeyNum() * (Currentbuf->LINES / 2 - 1), B_NORMAL);
1613
DEFUN(lup1, UP, "Scroll up one line")
1615
nscroll(searchKeyNum(), B_SCROLL);
1619
DEFUN(ldown1, DOWN, "Scroll down one line")
1621
nscroll(-searchKeyNum(), B_SCROLL);
1624
/* move cursor position to the center of screen */
1625
DEFUN(ctrCsrV, CENTER_V, "Move to the center column")
1628
if (Currentbuf->firstLine == NULL)
1630
offsety = Currentbuf->LINES / 2 - Currentbuf->cursorY;
1633
Currentbuf->currentLine = lineSkip(Currentbuf,
1634
Currentbuf->currentLine, offsety,
1637
Currentbuf->topLine =
1638
lineSkip(Currentbuf, Currentbuf->topLine, -offsety, FALSE);
1639
arrangeLine(Currentbuf);
1640
displayBuffer(Currentbuf, B_NORMAL);
1644
DEFUN(ctrCsrH, CENTER_H, "Move to the center line")
1647
if (Currentbuf->firstLine == NULL)
1649
offsetx = Currentbuf->cursorX - Currentbuf->COLS / 2;
1651
columnSkip(Currentbuf, offsetx);
1652
arrangeCursor(Currentbuf);
1653
displayBuffer(Currentbuf, B_NORMAL);
1658
DEFUN(rdrwSc, REDRAW, "Redraw screen")
1661
arrangeCursor(Currentbuf);
1662
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1671
for (pos = 0; pos < l->size; pos++)
1672
l->propBuf[pos] &= ~PE_MARK;
1675
/* search by regular expression */
1677
srchcore(char *volatile str, int (*func) (Buffer *, char *))
1679
MySignalHandler(*prevtrap) ();
1680
volatile int i, result = SR_NOTFOUND;
1682
if (str != NULL && str != SearchString)
1684
if (SearchString == NULL || *SearchString == '\0')
1687
str = conv_search_string(SearchString, DisplayCharset);
1688
prevtrap = mySignal(SIGINT, intTrap);
1690
if (SETJMP(IntReturn) == 0) {
1691
for (i = 0; i < PREC_NUM; i++) {
1692
result = func(Currentbuf, str);
1693
if (i < PREC_NUM - 1 && result & SR_FOUND)
1694
clear_mark(Currentbuf->currentLine);
1697
mySignal(SIGINT, prevtrap);
1703
disp_srchresult(int result, char *prompt, char *str)
1707
if (result & SR_NOTFOUND)
1708
disp_message(Sprintf("Not found: %s", str)->ptr, TRUE);
1709
else if (result & SR_WRAPPED)
1710
disp_message(Sprintf("Search wrapped: %s", str)->ptr, TRUE);
1711
else if (show_srch_str)
1712
disp_message(Sprintf("%s%s", prompt, str)->ptr, TRUE);
1716
dispincsrch(int ch, Str buf, Lineprop *prop)
1719
static Line *currentLine;
1722
int do_next_search = FALSE;
1724
if (ch == 0 && buf == NULL) {
1725
SAVE_BUFPOSITION(&sbuf); /* search starting point */
1726
currentLine = sbuf.currentLine;
1734
searchRoutine = backwardSearch;
1735
do_next_search = TRUE;
1738
searchRoutine = forwardSearch;
1739
do_next_search = TRUE;
1744
migemo_active = -migemo_active;
1750
return ch; /* use InputKeymap */
1753
if (do_next_search) {
1755
if (searchRoutine == forwardSearch)
1756
Currentbuf->pos += 1;
1757
SAVE_BUFPOSITION(&sbuf);
1758
if (srchcore(str, searchRoutine) == SR_NOTFOUND
1759
&& searchRoutine == forwardSearch) {
1760
Currentbuf->pos -= 1;
1761
SAVE_BUFPOSITION(&sbuf);
1763
arrangeCursor(Currentbuf);
1764
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1765
clear_mark(Currentbuf->currentLine);
1769
return 020; /* _prev completion for C-s C-s */
1772
RESTORE_BUFPOSITION(&sbuf);
1773
arrangeCursor(Currentbuf);
1774
srchcore(str, searchRoutine);
1775
arrangeCursor(Currentbuf);
1776
currentLine = Currentbuf->currentLine;
1777
pos = Currentbuf->pos;
1779
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1780
clear_mark(Currentbuf->currentLine);
1783
while (*str++ != '\0') {
1784
if (migemo_active > 0)
1785
*prop++ |= PE_UNDER;
1787
*prop++ &= ~PE_UNDER;
1794
isrch(int (*func) (Buffer *, char *), char *prompt)
1798
SAVE_BUFPOSITION(&sbuf);
1799
dispincsrch(0, NULL, NULL); /* initialize incremental search state */
1801
searchRoutine = func;
1802
str = inputLineHistSearch(prompt, NULL, IN_STRING, TextHist, dispincsrch);
1804
RESTORE_BUFPOSITION(&sbuf);
1806
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1810
srch(int (*func) (Buffer *, char *), char *prompt)
1817
str = searchKeyData();
1818
if (str == NULL || *str == '\0') {
1819
str = inputStrHist(prompt, NULL, TextHist);
1820
if (str != NULL && *str == '\0')
1823
displayBuffer(Currentbuf, B_NORMAL);
1828
pos = Currentbuf->pos;
1829
if (func == forwardSearch)
1830
Currentbuf->pos += 1;
1831
result = srchcore(str, func);
1832
if (result & SR_FOUND)
1833
clear_mark(Currentbuf->currentLine);
1835
Currentbuf->pos = pos;
1836
displayBuffer(Currentbuf, B_NORMAL);
1838
disp_srchresult(result, prompt, str);
1839
searchRoutine = func;
1842
/* Search regular expression forward */
1844
DEFUN(srchfor, SEARCH SEARCH_FORE WHEREIS, "Search forward")
1846
srch(forwardSearch, "Forward: ");
1849
DEFUN(isrchfor, ISEARCH, "Incremental search forward")
1851
isrch(forwardSearch, "I-search: ");
1854
/* Search regular expression backward */
1856
DEFUN(srchbak, SEARCH_BACK, "Search backward")
1858
srch(backwardSearch, "Backward: ");
1861
DEFUN(isrchbak, ISEARCH_BACK, "Incremental search backward")
1863
isrch(backwardSearch, "I-search backward: ");
1867
srch_nxtprv(int reverse)
1871
static int (*routine[2]) (Buffer *, char *) = {
1872
forwardSearch, backwardSearch
1876
if (searchRoutine == NULL) {
1877
/* FIXME: gettextize? */
1878
disp_message("No previous regular expression", TRUE);
1883
if (searchRoutine == backwardSearch)
1886
Currentbuf->pos += 1;
1887
result = srchcore(SearchString, routine[reverse]);
1888
if (result & SR_FOUND)
1889
clear_mark(Currentbuf->currentLine);
1890
displayBuffer(Currentbuf, B_NORMAL);
1891
disp_srchresult(result, (reverse ? "Backward: " : "Forward: "),
1895
/* Search next matching */
1896
DEFUN(srchnxt, SEARCH_NEXT, "Search next regexp")
1901
/* Search previous matching */
1902
DEFUN(srchprv, SEARCH_PREV, "Search previous regexp")
1908
shiftvisualpos(Buffer *buf, int shift)
1910
Line *l = buf->currentLine;
1911
buf->visualpos -= shift;
1912
if (buf->visualpos - l->bwidth >= buf->COLS)
1913
buf->visualpos = l->bwidth + buf->COLS - 1;
1914
else if (buf->visualpos - l->bwidth < 0)
1915
buf->visualpos = l->bwidth;
1917
if (buf->visualpos - l->bwidth == -shift && buf->cursorX == 0)
1918
buf->visualpos = l->bwidth;
1921
/* Shift screen left */
1922
DEFUN(shiftl, SHIFT_LEFT, "Shift screen left")
1926
if (Currentbuf->firstLine == NULL)
1928
column = Currentbuf->currentColumn;
1929
columnSkip(Currentbuf, searchKeyNum() * (-Currentbuf->COLS + 1) + 1);
1930
shiftvisualpos(Currentbuf, Currentbuf->currentColumn - column);
1931
displayBuffer(Currentbuf, B_NORMAL);
1934
/* Shift screen right */
1935
DEFUN(shiftr, SHIFT_RIGHT, "Shift screen right")
1939
if (Currentbuf->firstLine == NULL)
1941
column = Currentbuf->currentColumn;
1942
columnSkip(Currentbuf, searchKeyNum() * (Currentbuf->COLS - 1) - 1);
1943
shiftvisualpos(Currentbuf, Currentbuf->currentColumn - column);
1944
displayBuffer(Currentbuf, B_NORMAL);
1947
DEFUN(col1R, RIGHT, "Shift screen one column right")
1949
Buffer *buf = Currentbuf;
1950
Line *l = buf->currentLine;
1951
int j, column, n = searchKeyNum();
1955
for (j = 0; j < n; j++) {
1956
column = buf->currentColumn;
1957
columnSkip(Currentbuf, 1);
1958
if (column == buf->currentColumn)
1960
shiftvisualpos(Currentbuf, 1);
1962
displayBuffer(Currentbuf, B_NORMAL);
1965
DEFUN(col1L, LEFT, "Shift screen one column")
1967
Buffer *buf = Currentbuf;
1968
Line *l = buf->currentLine;
1969
int j, n = searchKeyNum();
1973
for (j = 0; j < n; j++) {
1974
if (buf->currentColumn == 0)
1976
columnSkip(Currentbuf, -1);
1977
shiftvisualpos(Currentbuf, -1);
1979
displayBuffer(Currentbuf, B_NORMAL);
1982
DEFUN(setEnv, SETENV, "Set environment variable")
1987
CurrentKeyData = NULL; /* not allowed in w3m-control: */
1988
env = searchKeyData();
1989
if (env == NULL || *env == '\0' || strchr(env, '=') == NULL) {
1990
if (env != NULL && *env != '\0')
1991
env = Sprintf("%s=", env)->ptr;
1992
env = inputStrHist("Set environ: ", env, TextHist);
1993
if (env == NULL || *env == '\0') {
1994
displayBuffer(Currentbuf, B_NORMAL);
1998
if ((value = strchr(env, '=')) != NULL && value > env) {
1999
var = allocStr(env, value - env);
2001
set_environ(var, value);
2003
displayBuffer(Currentbuf, B_NORMAL);
2006
DEFUN(pipeBuf, PIPE_BUF, "Send rendered document to pipe")
2012
CurrentKeyData = NULL; /* not allowed in w3m-control: */
2013
cmd = searchKeyData();
2014
if (cmd == NULL || *cmd == '\0') {
2015
/* FIXME: gettextize? */
2016
cmd = inputLineHist("Pipe buffer to: ", "", IN_COMMAND, ShellHist);
2019
cmd = conv_to_system(cmd);
2020
if (cmd == NULL || *cmd == '\0') {
2021
displayBuffer(Currentbuf, B_NORMAL);
2024
tmpf = tmpfname(TMPF_DFL, NULL)->ptr;
2025
f = fopen(tmpf, "w");
2027
/* FIXME: gettextize? */
2028
disp_message(Sprintf("Can't save buffer to %s", cmd)->ptr, TRUE);
2031
saveBuffer(Currentbuf, f, TRUE);
2033
buf = getpipe(myExtCommand(cmd, shell_quote(tmpf), TRUE)->ptr);
2035
disp_message("Execution failed", TRUE);
2039
buf->filename = cmd;
2040
buf->buffername = Sprintf("%s %s", PIPEBUFFERNAME,
2041
conv_from_system(cmd))->ptr;
2042
buf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
2043
if (buf->type == NULL)
2044
buf->type = "text/plain";
2045
buf->currentURL.file = "-";
2048
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2051
/* Execute shell command and read output ac pipe. */
2052
DEFUN(pipesh, PIPE_SHELL, "Execute shell command and browse")
2057
CurrentKeyData = NULL; /* not allowed in w3m-control: */
2058
cmd = searchKeyData();
2059
if (cmd == NULL || *cmd == '\0') {
2060
cmd = inputLineHist("(read shell[pipe])!", "", IN_COMMAND, ShellHist);
2063
cmd = conv_to_system(cmd);
2064
if (cmd == NULL || *cmd == '\0') {
2065
displayBuffer(Currentbuf, B_NORMAL);
2070
disp_message("Execution failed", TRUE);
2074
buf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
2075
if (buf->type == NULL)
2076
buf->type = "text/plain";
2079
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2082
/* Execute shell command and load entire output to buffer */
2083
DEFUN(readsh, READ_SHELL, "Execute shell command and load")
2086
MySignalHandler(*prevtrap) ();
2089
CurrentKeyData = NULL; /* not allowed in w3m-control: */
2090
cmd = searchKeyData();
2091
if (cmd == NULL || *cmd == '\0') {
2092
cmd = inputLineHist("(read shell)!", "", IN_COMMAND, ShellHist);
2095
cmd = conv_to_system(cmd);
2096
if (cmd == NULL || *cmd == '\0') {
2097
displayBuffer(Currentbuf, B_NORMAL);
2100
prevtrap = mySignal(SIGINT, intTrap);
2102
buf = getshell(cmd);
2103
mySignal(SIGINT, prevtrap);
2106
/* FIXME: gettextize? */
2107
disp_message("Execution failed", TRUE);
2111
buf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
2112
if (buf->type == NULL)
2113
buf->type = "text/plain";
2116
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2119
/* Execute shell command */
2120
DEFUN(execsh, EXEC_SHELL SHELL, "Execute shell command")
2124
CurrentKeyData = NULL; /* not allowed in w3m-control: */
2125
cmd = searchKeyData();
2126
if (cmd == NULL || *cmd == '\0') {
2127
cmd = inputLineHist("(exec shell)!", "", IN_COMMAND, ShellHist);
2130
cmd = conv_to_system(cmd);
2131
if (cmd != NULL && *cmd != '\0') {
2135
/* FIXME: gettextize? */
2136
printf("\n[Hit any key]");
2141
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2145
DEFUN(ldfile, LOAD, "Load local file")
2149
fn = searchKeyData();
2150
if (fn == NULL || *fn == '\0') {
2151
/* FIXME: gettextize? */
2152
fn = inputFilenameHist("(Load)Filename? ", NULL, LoadHist);
2155
fn = conv_to_system(fn);
2156
if (fn == NULL || *fn == '\0') {
2157
displayBuffer(Currentbuf, B_NORMAL);
2163
/* Load help file */
2164
DEFUN(ldhelp, HELP, "View help")
2172
n = strcspn(lang, ";, \t");
2173
tmp = Sprintf("file:///$LIB/" HELP_CGI CGI_EXTENSION "?version=%s&lang=%s",
2174
Str_form_quote(Strnew_charp(w3m_version))->ptr,
2175
Str_form_quote(Strnew_charp_n(lang, n))->ptr);
2176
cmd_loadURL(tmp->ptr, NULL, NO_REFERER, NULL);
2178
cmd_loadURL(helpFile(HELP_FILE), NULL, NO_REFERER, NULL);
2183
cmd_loadfile(char *fn)
2187
buf = loadGeneralFile(file_to_url(fn), NULL, NO_REFERER, 0, NULL);
2189
/* FIXME: gettextize? */
2190
char *emsg = Sprintf("%s not found", conv_from_system(fn))->ptr;
2191
disp_err_message(emsg, FALSE);
2193
else if (buf != NO_BUFFER) {
2195
if (RenderFrame && Currentbuf->frameset != NULL)
2198
displayBuffer(Currentbuf, B_NORMAL);
2201
/* Move cursor left */
2205
int i, m = searchKeyNum();
2206
if (Currentbuf->firstLine == NULL)
2208
for (i = 0; i < m; i++)
2209
cursorLeft(Currentbuf, n);
2210
displayBuffer(Currentbuf, B_NORMAL);
2213
DEFUN(movL, MOVE_LEFT,
2214
"Move cursor left (a half screen shift at the left edge)")
2216
_movL(Currentbuf->COLS / 2);
2219
DEFUN(movL1, MOVE_LEFT1, "Move cursor left (1 columns shift at the left edge)")
2224
/* Move cursor downward */
2228
int i, m = searchKeyNum();
2229
if (Currentbuf->firstLine == NULL)
2231
for (i = 0; i < m; i++)
2232
cursorDown(Currentbuf, n);
2233
displayBuffer(Currentbuf, B_NORMAL);
2236
DEFUN(movD, MOVE_DOWN,
2237
"Move cursor down (a half screen scroll at the end of screen)")
2239
_movD((Currentbuf->LINES + 1) / 2);
2242
DEFUN(movD1, MOVE_DOWN1,
2243
"Move cursor down (1 line scroll at the end of screen)")
2248
/* move cursor upward */
2252
int i, m = searchKeyNum();
2253
if (Currentbuf->firstLine == NULL)
2255
for (i = 0; i < m; i++)
2256
cursorUp(Currentbuf, n);
2257
displayBuffer(Currentbuf, B_NORMAL);
2260
DEFUN(movU, MOVE_UP,
2261
"Move cursor up (a half screen scroll at the top of screen)")
2263
_movU((Currentbuf->LINES + 1) / 2);
2266
DEFUN(movU1, MOVE_UP1, "Move cursor up (1 line scrol at the top of screen)")
2271
/* Move cursor right */
2275
int i, m = searchKeyNum();
2276
if (Currentbuf->firstLine == NULL)
2278
for (i = 0; i < m; i++)
2279
cursorRight(Currentbuf, n);
2280
displayBuffer(Currentbuf, B_NORMAL);
2283
DEFUN(movR, MOVE_RIGHT,
2284
"Move cursor right (a half screen shift at the right edge)")
2286
_movR(Currentbuf->COLS / 2);
2289
DEFUN(movR1, MOVE_RIGHT1,
2290
"Move cursor right (1 columns shift at the right edge)")
2297
* From: Takashi Nishimoto <g96p0935@mse.waseda.ac.jp> Date: Mon, 14 Jun
2298
* 1999 09:29:56 +0900
2300
#if defined(USE_M17N) && defined(USE_UNICODE)
2301
#define nextChar(s, l) do { (s)++; } while ((s) < (l)->len && (l)->propBuf[s] & PC_WCHAR2)
2302
#define prevChar(s, l) do { (s)--; } while ((s) > 0 && (l)->propBuf[s] & PC_WCHAR2)
2307
return wc_any_to_ucs(wtf_parse1((wc_uchar **)&p));
2311
is_wordchar(wc_uint32 c)
2313
return wc_is_ucs_alnum(c);
2316
#define nextChar(s, l) (s)++
2317
#define prevChar(s, l) (s)--
2318
#define getChar(p) ((int)*(p))
2328
prev_nonnull_line(Line *line)
2332
for (l = line; l != NULL && l->len == 0; l = l->prev) ;
2333
if (l == NULL || l->len == 0)
2336
Currentbuf->currentLine = l;
2338
Currentbuf->pos = Currentbuf->currentLine->len;
2342
DEFUN(movLW, PREV_WORD, "Move to previous word")
2347
int i, n = searchKeyNum();
2349
if (Currentbuf->firstLine == NULL)
2352
for (i = 0; i < n; i++) {
2353
pline = Currentbuf->currentLine;
2354
ppos = Currentbuf->pos;
2356
if (prev_nonnull_line(Currentbuf->currentLine) < 0)
2360
l = Currentbuf->currentLine;
2362
while (Currentbuf->pos > 0) {
2363
int tmp = Currentbuf->pos;
2365
if (is_wordchar(getChar(&lb[tmp])))
2367
Currentbuf->pos = tmp;
2369
if (Currentbuf->pos > 0)
2371
if (prev_nonnull_line(Currentbuf->currentLine->prev) < 0) {
2372
Currentbuf->currentLine = pline;
2373
Currentbuf->pos = ppos;
2376
Currentbuf->pos = Currentbuf->currentLine->len;
2379
l = Currentbuf->currentLine;
2381
while (Currentbuf->pos > 0) {
2382
int tmp = Currentbuf->pos;
2384
if (!is_wordchar(getChar(&lb[tmp])))
2386
Currentbuf->pos = tmp;
2390
arrangeCursor(Currentbuf);
2391
displayBuffer(Currentbuf, B_NORMAL);
2395
next_nonnull_line(Line *line)
2399
for (l = line; l != NULL && l->len == 0; l = l->next) ;
2401
if (l == NULL || l->len == 0)
2404
Currentbuf->currentLine = l;
2406
Currentbuf->pos = 0;
2410
DEFUN(movRW, NEXT_WORD, "Move to next word")
2415
int i, n = searchKeyNum();
2417
if (Currentbuf->firstLine == NULL)
2420
for (i = 0; i < n; i++) {
2421
pline = Currentbuf->currentLine;
2422
ppos = Currentbuf->pos;
2424
if (next_nonnull_line(Currentbuf->currentLine) < 0)
2427
l = Currentbuf->currentLine;
2429
while (Currentbuf->pos < l->len &&
2430
is_wordchar(getChar(&lb[Currentbuf->pos])))
2431
nextChar(Currentbuf->pos, l);
2434
while (Currentbuf->pos < l->len &&
2435
!is_wordchar(getChar(&lb[Currentbuf->pos])))
2436
nextChar(Currentbuf->pos, l);
2437
if (Currentbuf->pos < l->len)
2439
if (next_nonnull_line(Currentbuf->currentLine->next) < 0) {
2440
Currentbuf->currentLine = pline;
2441
Currentbuf->pos = ppos;
2444
Currentbuf->pos = 0;
2445
l = Currentbuf->currentLine;
2450
arrangeCursor(Currentbuf);
2451
displayBuffer(Currentbuf, B_NORMAL);
2455
_quitfm(int confirm)
2459
if (checkDownloadList())
2460
/* FIXME: gettextize? */
2461
ans = inputChar("Download process retains. "
2462
"Do you want to exit w3m? (y/n)");
2464
/* FIXME: gettextize? */
2465
ans = inputChar("Do you want to exit w3m? (y/n)");
2466
if (!(ans && TOLOWER(*ans) == 'y')) {
2467
displayBuffer(Currentbuf, B_NORMAL);
2471
term_title(""); /* XXX */
2479
#endif /* USE_COOKIE */
2481
if (UseHistory && SaveURLHist)
2482
saveHistory(URLHist, URLHistSize);
2483
#endif /* USE_HISTORY */
2488
DEFUN(quitfm, ABORT EXIT, "Quit w3m without confirmation")
2493
/* Question and Quit */
2494
DEFUN(qquitfm, QUIT, "Quit w3m")
2496
_quitfm(confirm_on_quit);
2500
DEFUN(selBuf, SELECT, "Go to buffer selection panel")
2508
buf = selectBuffer(Firstbuf, Currentbuf, &cmd);
2520
if (Firstbuf == NULL) {
2521
/* No more buffer */
2522
Firstbuf = nullBuffer();
2523
Currentbuf = Firstbuf;
2535
for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer) {
2536
if (buf == Currentbuf)
2542
tmpClearBuffer(buf);
2544
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2547
/* Suspend (on BSD), or run interactive shell (on SysV) */
2548
DEFUN(susp, INTERRUPT SUSPEND, "Stop loading document")
2552
#endif /* not SIGSTOP */
2558
shell = getenv("SHELL");
2563
kill((pid_t) 0, SIGSTOP);
2564
#endif /* SIGSTOP */
2566
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2569
/* Go to specified line */
2573
if (l == NULL || *l == '\0' || Currentbuf->currentLine == NULL) {
2574
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2577
Currentbuf->pos = 0;
2578
if (((*l == '^') || (*l == '$')) && prec_num) {
2579
gotoRealLine(Currentbuf, prec_num);
2581
else if (*l == '^') {
2582
Currentbuf->topLine = Currentbuf->currentLine = Currentbuf->firstLine;
2584
else if (*l == '$') {
2585
Currentbuf->topLine =
2586
lineSkip(Currentbuf, Currentbuf->lastLine,
2587
-(Currentbuf->LINES + 1) / 2, TRUE);
2588
Currentbuf->currentLine = Currentbuf->lastLine;
2591
gotoRealLine(Currentbuf, atoi(l));
2592
arrangeCursor(Currentbuf);
2593
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2596
DEFUN(goLine, GOTO_LINE, "Go to specified line")
2599
char *str = searchKeyData();
2605
/* FIXME: gettextize? */
2606
_goLine(inputStr("Goto line: ", ""));
2610
DEFUN(goLineF, BEGIN, "Go to the first line")
2615
DEFUN(goLineL, END, "Go to the last line")
2620
/* Go to the beginning of the line */
2621
DEFUN(linbeg, LINE_BEGIN, "Go to the beginning of line")
2623
if (Currentbuf->firstLine == NULL)
2625
while (Currentbuf->currentLine->prev && Currentbuf->currentLine->bpos)
2626
cursorUp0(Currentbuf, 1);
2627
Currentbuf->pos = 0;
2628
arrangeCursor(Currentbuf);
2629
displayBuffer(Currentbuf, B_NORMAL);
2632
/* Go to the bottom of the line */
2633
DEFUN(linend, LINE_END, "Go to the end of line")
2635
if (Currentbuf->firstLine == NULL)
2637
while (Currentbuf->currentLine->next
2638
&& Currentbuf->currentLine->next->bpos)
2639
cursorDown0(Currentbuf, 1);
2640
Currentbuf->pos = Currentbuf->currentLine->len - 1;
2641
arrangeCursor(Currentbuf);
2642
displayBuffer(Currentbuf, B_NORMAL);
2646
cur_real_linenumber(Buffer *buf)
2648
Line *l, *cur = buf->currentLine;
2653
n = cur->real_linenumber ? cur->real_linenumber : 1;
2654
for (l = buf->firstLine; l && l != cur && l->real_linenumber == 0; l = l->next) { /* header */
2661
/* Run editor on the current buffer */
2662
DEFUN(editBf, EDIT, "Edit current document")
2664
char *fn = Currentbuf->filename;
2667
if (fn == NULL || Currentbuf->pagerSource != NULL || /* Behaving as a pager */
2668
(Currentbuf->type == NULL && Currentbuf->edit == NULL) || /* Reading shell */
2669
Currentbuf->real_scheme != SCM_LOCAL || !strcmp(Currentbuf->currentURL.file, "-") || /* file is std input */
2670
Currentbuf->bufferprop & BP_FRAME) { /* Frame */
2671
disp_err_message("Can't edit other than local file", TRUE);
2674
if (Currentbuf->edit)
2675
cmd = unquote_mailcap(Currentbuf->edit, Currentbuf->real_type, fn,
2676
checkHeader(Currentbuf, "Content-Type:"), NULL);
2678
cmd = myEditor(Editor, shell_quote(fn),
2679
cur_real_linenumber(Currentbuf));
2684
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2688
/* Run editor on the current screen */
2689
DEFUN(editScr, EDIT_SCREEN, "Edit currently rendered document")
2694
tmpf = tmpfname(TMPF_DFL, NULL)->ptr;
2695
f = fopen(tmpf, "w");
2697
/* FIXME: gettextize? */
2698
disp_err_message(Sprintf("Can't open %s", tmpf)->ptr, TRUE);
2701
saveBuffer(Currentbuf, f, TRUE);
2704
system(myEditor(Editor, shell_quote(tmpf),
2705
cur_real_linenumber(Currentbuf))->ptr);
2708
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2713
/* Set / unset mark */
2714
DEFUN(_mark, MARK, "Set/unset mark")
2719
if (Currentbuf->firstLine == NULL)
2721
l = Currentbuf->currentLine;
2722
l->propBuf[Currentbuf->pos] ^= PE_MARK;
2723
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2726
/* Go to next mark */
2727
DEFUN(nextMk, NEXT_MARK, "Move to next word")
2734
if (Currentbuf->firstLine == NULL)
2736
i = Currentbuf->pos + 1;
2737
l = Currentbuf->currentLine;
2743
for (; i < l->len; i++) {
2744
if (l->propBuf[i] & PE_MARK) {
2745
Currentbuf->currentLine = l;
2746
Currentbuf->pos = i;
2747
arrangeCursor(Currentbuf);
2748
displayBuffer(Currentbuf, B_NORMAL);
2755
/* FIXME: gettextize? */
2756
disp_message("No mark exist after here", TRUE);
2759
/* Go to previous mark */
2760
DEFUN(prevMk, PREV_MARK, "Move to previous mark")
2767
if (Currentbuf->firstLine == NULL)
2769
i = Currentbuf->pos - 1;
2770
l = Currentbuf->currentLine;
2777
for (; i >= 0; i--) {
2778
if (l->propBuf[i] & PE_MARK) {
2779
Currentbuf->currentLine = l;
2780
Currentbuf->pos = i;
2781
arrangeCursor(Currentbuf);
2782
displayBuffer(Currentbuf, B_NORMAL);
2790
/* FIXME: gettextize? */
2791
disp_message("No mark exist before here", TRUE);
2794
/* Mark place to which the regular expression matches */
2795
DEFUN(reMark, REG_MARK, "Set mark using regexp")
2803
str = searchKeyData();
2804
if (str == NULL || *str == '\0') {
2805
str = inputStrHist("(Mark)Regexp: ", MarkString, TextHist);
2806
if (str == NULL || *str == '\0') {
2807
displayBuffer(Currentbuf, B_NORMAL);
2811
str = conv_search_string(str, DisplayCharset);
2812
if ((str = regexCompile(str, 1)) != NULL) {
2813
disp_message(str, TRUE);
2817
for (l = Currentbuf->firstLine; l != NULL; l = l->next) {
2820
if (regexMatch(p, &l->lineBuf[l->len] - p, p == l->lineBuf) == 1) {
2821
matchedPosition(&p1, &p2);
2822
l->propBuf[p1 - l->lineBuf] |= PE_MARK;
2830
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2832
#endif /* USE_MARK */
2835
loadNormalBuf(Buffer *buf, int renderframe)
2838
if (renderframe && RenderFrame && Currentbuf->frameset != NULL)
2844
loadLink(char *url, char *target, char *referer, FormList *request)
2846
Buffer *buf, *nfbuf;
2847
union frameset_element *f_element = NULL;
2849
ParsedURL *base, pu;
2850
const int *no_referer_ptr;
2852
message(Sprintf("loading %s", url)->ptr, 0, 0);
2855
no_referer_ptr = query_SCONF_NO_REFERER_FROM(&Currentbuf->currentURL);
2856
base = baseURL(Currentbuf);
2857
if ((no_referer_ptr && *no_referer_ptr) ||
2859
base->scheme == SCM_LOCAL || base->scheme == SCM_LOCAL_CGI)
2860
referer = NO_REFERER;
2861
if (referer == NULL)
2862
referer = parsedURL2Str(&Currentbuf->currentURL)->ptr;
2863
buf = loadGeneralFile(url, baseURL(Currentbuf), referer, flag, request);
2865
char *emsg = Sprintf("Can't load %s", url)->ptr;
2866
disp_err_message(emsg, FALSE);
2870
parseURL2(url, &pu, base);
2871
pushHashHist(URLHist, parsedURL2Str(&pu)->ptr);
2873
if (buf == NO_BUFFER) {
2876
if (!on_target) /* open link as an indivisual page */
2877
return loadNormalBuf(buf, TRUE);
2879
if (do_download) /* download (thus no need to render frame) */
2880
return loadNormalBuf(buf, FALSE);
2882
if (target == NULL || /* no target specified (that means this page is not a frame page) */
2883
!strcmp(target, "_top") || /* this link is specified to be opened as an indivisual * page */
2884
!(Currentbuf->bufferprop & BP_FRAME) /* This page is not a frame page */
2886
return loadNormalBuf(buf, TRUE);
2888
nfbuf = Currentbuf->linkBuffer[LB_N_FRAME];
2889
if (nfbuf == NULL) {
2890
/* original page (that contains <frameset> tag) doesn't exist */
2891
return loadNormalBuf(buf, TRUE);
2894
f_element = search_frame(nfbuf->frameset, target);
2895
if (f_element == NULL) {
2896
/* specified target doesn't exist in this frameset */
2897
return loadNormalBuf(buf, TRUE);
2902
/* stack current frameset */
2903
pushFrameTree(&(nfbuf->frameQ), copyFrameSet(nfbuf->frameset), Currentbuf);
2904
/* delete frame view buffer */
2905
delBuffer(Currentbuf);
2907
/* nfbuf->frameset = copyFrameSet(nfbuf->frameset); */
2908
resetFrameElement(f_element, buf, referer, request);
2913
char *label = pu.label;
2915
if (label && f_element->element->attr == F_BODY) {
2916
al = searchAnchor(f_element->body->nameList, label);
2919
label = Strnew_m_charp("_", target, NULL)->ptr;
2920
al = searchURLLabel(Currentbuf, label);
2923
gotoLine(Currentbuf, al->start.line);
2925
Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->topLine,
2926
Currentbuf->currentLine->
2928
Currentbuf->topLine->linenumber,
2930
Currentbuf->pos = al->start.pos;
2931
arrangeCursor(Currentbuf);
2934
displayBuffer(Currentbuf, B_NORMAL);
2939
gotoLabel(char *label)
2945
al = searchURLLabel(Currentbuf, label);
2947
/* FIXME: gettextize? */
2948
disp_message(Sprintf("%s is not found", label)->ptr, TRUE);
2951
buf = newBuffer(Currentbuf->width);
2952
copyBuffer(buf, Currentbuf);
2953
for (i = 0; i < MAX_LB; i++)
2954
buf->linkBuffer[i] = NULL;
2955
buf->currentURL.label = allocStr(label, -1);
2956
pushHashHist(URLHist, parsedURL2Str(&buf->currentURL)->ptr);
2959
gotoLine(Currentbuf, al->start.line);
2961
Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->topLine,
2962
Currentbuf->currentLine->linenumber
2963
- Currentbuf->topLine->linenumber,
2965
Currentbuf->pos = al->start.pos;
2966
arrangeCursor(Currentbuf);
2967
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2972
handleMailto(char *url)
2977
if (strncasecmp(url, "mailto:", 7))
2979
#ifdef USE_W3MMAILER
2980
if (! non_null(Mailer) || MailtoOptions == MAILTO_OPTIONS_USE_W3MMAILER)
2983
if (!non_null(Mailer)) {
2984
/* FIXME: gettextize? */
2985
disp_err_message("no mailer is specified", TRUE);
2990
/* invoke external mailer */
2991
if (MailtoOptions == MAILTO_OPTIONS_USE_MAILTO_URL) {
2992
to = Strnew_charp(html_unquote(url));
2994
to = Strnew_charp(url + 7);
2995
if ((pos = strchr(to->ptr, '?')) != NULL)
2996
Strtruncate(to, pos - to->ptr);
2999
system(myExtCommand(Mailer, shell_quote(file_unquote(to->ptr)),
3002
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3003
pushHashHist(URLHist, url);
3007
/* follow HREF link */
3008
DEFUN(followA, GOTO_LINK, "Go to current link")
3014
int x = 0, y = 0, map = 0;
3018
if (Currentbuf->firstLine == NULL)
3020
l = Currentbuf->currentLine;
3023
a = retrieveCurrentImg(Currentbuf);
3024
if (a && a->image && a->image->map) {
3028
if (a && a->image && a->image->ismap) {
3029
getMapXY(Currentbuf, a, &x, &y);
3033
a = retrieveCurrentMap(Currentbuf);
3039
a = retrieveCurrentAnchor(Currentbuf);
3044
if (*a->url == '#') { /* index within this buffer */
3045
gotoLabel(a->url + 1);
3048
parseURL2(a->url, &u, baseURL(Currentbuf));
3049
if (Strcmp(parsedURL2Str(&u), parsedURL2Str(&Currentbuf->currentURL)) == 0) {
3050
/* index within this buffer */
3056
if (handleMailto(a->url))
3059
else if (!strncasecmp(a->url, "news:", 5) && strchr(a->url, '@') == NULL) {
3060
/* news:newsgroup is not supported */
3061
/* FIXME: gettextize? */
3062
disp_err_message("news:newsgroup_name is not supported", TRUE);
3065
#endif /* USE_NNTP */
3069
url = Sprintf("%s?%d,%d", a->url, x, y)->ptr;
3072
if (check_target && open_tab_blank && a->target &&
3073
(!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) {
3078
loadLink(url, a->target, a->referer, NULL);
3079
if (buf != Currentbuf)
3082
deleteTab(CurrentTab);
3083
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3086
loadLink(url, a->target, a->referer, NULL);
3087
displayBuffer(Currentbuf, B_NORMAL);
3090
/* follow HREF link in the buffer */
3099
/* view inline image */
3100
DEFUN(followI, VIEW_IMAGE, "View image")
3106
if (Currentbuf->firstLine == NULL)
3108
l = Currentbuf->currentLine;
3110
a = retrieveCurrentImg(Currentbuf);
3113
/* FIXME: gettextize? */
3114
message(Sprintf("loading %s", a->url)->ptr, 0, 0);
3116
buf = loadGeneralFile(a->url, baseURL(Currentbuf), NULL, 0, NULL);
3118
/* FIXME: gettextize? */
3119
char *emsg = Sprintf("Can't load %s", a->url)->ptr;
3120
disp_err_message(emsg, FALSE);
3122
else if (buf != NO_BUFFER) {
3125
displayBuffer(Currentbuf, B_NORMAL);
3128
static FormItemList *
3129
save_submit_formlist(FormItemList *src)
3133
FormItemList *srcitem;
3135
FormItemList *ret = NULL;
3137
FormSelectOptionItem *opt;
3138
FormSelectOptionItem *curopt;
3139
FormSelectOptionItem *srcopt;
3140
#endif /* MENU_SELECT */
3144
srclist = src->parent;
3145
list = New(FormList);
3146
list->method = srclist->method;
3147
list->action = Strdup(srclist->action);
3149
list->charset = srclist->charset;
3151
list->enctype = srclist->enctype;
3152
list->nitems = srclist->nitems;
3153
list->body = srclist->body;
3154
list->boundary = srclist->boundary;
3155
list->length = srclist->length;
3157
for (srcitem = srclist->item; srcitem; srcitem = srcitem->next) {
3158
item = New(FormItemList);
3159
item->type = srcitem->type;
3160
item->name = Strdup(srcitem->name);
3161
item->value = Strdup(srcitem->value);
3162
item->checked = srcitem->checked;
3163
item->accept = srcitem->accept;
3164
item->size = srcitem->size;
3165
item->rows = srcitem->rows;
3166
item->maxlength = srcitem->maxlength;
3167
item->readonly = srcitem->readonly;
3169
opt = curopt = NULL;
3170
for (srcopt = srcitem->select_option; srcopt; srcopt = srcopt->next) {
3171
if (!srcopt->checked)
3173
opt = New(FormSelectOptionItem);
3174
opt->value = Strdup(srcopt->value);
3175
opt->label = Strdup(srcopt->label);
3176
opt->checked = srcopt->checked;
3177
if (item->select_option == NULL) {
3178
item->select_option = curopt = opt;
3182
curopt = curopt->next;
3185
item->select_option = opt;
3187
item->label = Strdup(srcitem->label);
3188
#endif /* MENU_SELECT */
3189
item->parent = list;
3192
if (list->lastitem == NULL) {
3193
list->item = list->lastitem = item;
3196
list->lastitem->next = item;
3197
list->lastitem = item;
3209
conv_form_encoding(Str val, FormItemList *fi, Buffer *buf)
3211
wc_ces charset = SystemCharset;
3213
if (fi->parent->charset)
3214
charset = fi->parent->charset;
3215
else if (buf->document_charset && buf->document_charset != WC_CES_US_ASCII)
3216
charset = buf->document_charset;
3217
return wc_Str_conv_strict(val, InnerCharset, charset);
3220
#define conv_form_encoding(val, fi, buf) (val)
3224
query_from_followform(Str *query, FormItemList *fi, int multipart)
3230
*query = tmpfname(TMPF_DFL, NULL);
3231
body = fopen((*query)->ptr, "w");
3235
fi->parent->body = (*query)->ptr;
3236
fi->parent->boundary =
3237
Sprintf("------------------------------%d%ld%ld%ld", CurrentPid,
3238
fi->parent, fi->parent->body, fi->parent->boundary)->ptr;
3241
for (f2 = fi->parent->item; f2; f2 = f2->next) {
3242
if (f2->name == NULL)
3244
/* <ISINDEX> is translated into single text form */
3245
if (f2->name->length == 0 &&
3246
(multipart || f2->type != FORM_INPUT_TEXT))
3249
case FORM_INPUT_RESET:
3252
case FORM_INPUT_SUBMIT:
3253
case FORM_INPUT_IMAGE:
3254
if (f2 != fi || f2->value == NULL)
3257
case FORM_INPUT_RADIO:
3258
case FORM_INPUT_CHECKBOX:
3263
if (f2->type == FORM_INPUT_IMAGE) {
3266
getMapXY(Currentbuf, retrieveCurrentImg(Currentbuf), &x, &y);
3268
*query = Strdup(conv_form_encoding(f2->name, fi, Currentbuf));
3269
Strcat_charp(*query, ".x");
3270
form_write_data(body, fi->parent->boundary, (*query)->ptr,
3271
Sprintf("%d", x)->ptr);
3272
*query = Strdup(conv_form_encoding(f2->name, fi, Currentbuf));
3273
Strcat_charp(*query, ".y");
3274
form_write_data(body, fi->parent->boundary, (*query)->ptr,
3275
Sprintf("%d", y)->ptr);
3277
else if (f2->name && f2->name->length > 0 && f2->value != NULL) {
3279
*query = conv_form_encoding(f2->value, fi, Currentbuf);
3280
if (f2->type == FORM_INPUT_FILE)
3281
form_write_from_file(body, fi->parent->boundary,
3282
conv_form_encoding(f2->name, fi,
3285
Str_conv_to_system(f2->value)->ptr);
3287
form_write_data(body, fi->parent->boundary,
3288
conv_form_encoding(f2->name, fi,
3295
if (f2->type == FORM_INPUT_IMAGE) {
3298
getMapXY(Currentbuf, retrieveCurrentImg(Currentbuf), &x, &y);
3301
Str_form_quote(conv_form_encoding
3302
(f2->name, fi, Currentbuf)));
3303
Strcat(*query, Sprintf(".x=%d&", x));
3305
Str_form_quote(conv_form_encoding
3306
(f2->name, fi, Currentbuf)));
3307
Strcat(*query, Sprintf(".y=%d", y));
3311
if (f2->name && f2->name->length > 0) {
3313
Str_form_quote(conv_form_encoding
3314
(f2->name, fi, Currentbuf)));
3315
Strcat_char(*query, '=');
3317
if (f2->value != NULL) {
3318
if (fi->parent->method == FORM_METHOD_INTERNAL)
3319
Strcat(*query, Str_form_quote(f2->value));
3322
Str_form_quote(conv_form_encoding
3323
(f2->value, fi, Currentbuf)));
3328
Strcat_char(*query, '&');
3332
fprintf(body, "--%s--\r\n", fi->parent->boundary);
3336
/* remove trailing & */
3337
while (Strlastchar(*query) == '&')
3338
Strshrink(*query, 1);
3343
DEFUN(submitForm, SUBMIT, "Submit form")
3356
_followForm(int submit)
3361
FormItemList *fi, *f2;
3363
int multipart = 0, i;
3365
if (Currentbuf->firstLine == NULL)
3367
l = Currentbuf->currentLine;
3369
a = retrieveCurrentForm(Currentbuf);
3372
fi = (FormItemList *)a->url;
3374
case FORM_INPUT_TEXT:
3378
/* FIXME: gettextize? */
3379
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3380
/* FIXME: gettextize? */
3381
p = inputStrHist("TEXT:", fi->value ? fi->value->ptr : NULL, TextHist);
3382
if (p == NULL || fi->readonly)
3384
fi->value = Strnew_charp(p);
3385
formUpdateBuffer(a, Currentbuf, fi);
3386
if (fi->accept || fi->parent->nitems == 1)
3389
case FORM_INPUT_FILE:
3393
/* FIXME: gettextize? */
3394
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3395
/* FIXME: gettextize? */
3396
p = inputFilenameHist("Filename:", fi->value ? fi->value->ptr : NULL,
3398
if (p == NULL || fi->readonly)
3400
fi->value = Strnew_charp(p);
3401
formUpdateBuffer(a, Currentbuf, fi);
3402
if (fi->accept || fi->parent->nitems == 1)
3405
case FORM_INPUT_PASSWORD:
3409
/* FIXME: gettextize? */
3410
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3413
/* FIXME: gettextize? */
3414
p = inputLine("Password:", fi->value ? fi->value->ptr : NULL,
3418
fi->value = Strnew_charp(p);
3419
formUpdateBuffer(a, Currentbuf, fi);
3427
/* FIXME: gettextize? */
3428
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3430
formUpdateBuffer(a, Currentbuf, fi);
3432
case FORM_INPUT_RADIO:
3436
/* FIXME: gettextize? */
3437
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3440
formRecheckRadio(a, Currentbuf, fi);
3442
case FORM_INPUT_CHECKBOX:
3446
/* FIXME: gettextize? */
3447
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3450
fi->checked = !fi->checked;
3451
formUpdateBuffer(a, Currentbuf, fi);
3457
if (!formChooseOptionByMenu(fi,
3458
Currentbuf->cursorX - Currentbuf->pos +
3459
a->start.pos + Currentbuf->rootX,
3460
Currentbuf->cursorY + Currentbuf->rootY))
3462
formUpdateBuffer(a, Currentbuf, fi);
3463
if (fi->parent->nitems == 1)
3466
#endif /* MENU_SELECT */
3467
case FORM_INPUT_IMAGE:
3468
case FORM_INPUT_SUBMIT:
3469
case FORM_INPUT_BUTTON:
3473
multipart = (fi->parent->method == FORM_METHOD_POST &&
3474
fi->parent->enctype == FORM_ENCTYPE_MULTIPART);
3475
query_from_followform(&tmp, fi, multipart);
3477
tmp2 = Strdup(fi->parent->action);
3478
if (!Strcmp_charp(tmp2, "!CURRENT_URL!")) {
3479
/* It means "current URL" */
3480
tmp2 = parsedURL2Str(&Currentbuf->currentURL);
3481
if ((p = strchr(tmp2->ptr, '?')) != NULL)
3482
Strshrink(tmp2, (tmp2->ptr + tmp2->length) - p);
3485
if (fi->parent->method == FORM_METHOD_GET) {
3486
if ((p = strchr(tmp2->ptr, '?')) != NULL)
3487
Strshrink(tmp2, (tmp2->ptr + tmp2->length) - p);
3488
Strcat_charp(tmp2, "?");
3490
loadLink(tmp2->ptr, a->target, NULL, NULL);
3492
else if (fi->parent->method == FORM_METHOD_POST) {
3496
stat(fi->parent->body, &st);
3497
fi->parent->length = st.st_size;
3500
fi->parent->body = tmp->ptr;
3501
fi->parent->length = tmp->length;
3503
buf = loadLink(tmp2->ptr, a->target, NULL, fi->parent);
3505
unlink(fi->parent->body);
3507
if (buf && !(buf->bufferprop & BP_REDIRECTED)) { /* buf must be Currentbuf */
3508
/* BP_REDIRECTED means that the buffer is obtained through
3509
* Location: header. In this case, buf->form_submit must not be set
3510
* because the page is not loaded by POST method but GET method.
3512
buf->form_submit = save_submit_formlist(fi);
3515
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 */
3516
do_internal(tmp2->ptr, tmp->ptr);
3519
disp_err_message("Can't send form because of illegal method.",
3523
case FORM_INPUT_RESET:
3524
for (i = 0; i < Currentbuf->formitem->nanchor; i++) {
3525
a2 = &Currentbuf->formitem->anchors[i];
3526
f2 = (FormItemList *)a2->url;
3527
if (f2->parent == fi->parent &&
3528
f2->name && f2->value &&
3529
f2->type != FORM_INPUT_SUBMIT &&
3530
f2->type != FORM_INPUT_HIDDEN &&
3531
f2->type != FORM_INPUT_RESET) {
3532
f2->value = f2->init_value;
3533
f2->checked = f2->init_checked;
3535
f2->label = f2->init_label;
3536
f2->selected = f2->init_selected;
3537
#endif /* MENU_SELECT */
3538
formUpdateBuffer(a2, Currentbuf, f2);
3542
case FORM_INPUT_HIDDEN:
3546
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3549
/* go to the top anchor */
3550
DEFUN(topA, LINK_BEGIN, "Go to the first link")
3552
HmarkerList *hl = Currentbuf->hmarklist;
3557
if (Currentbuf->firstLine == NULL)
3559
if (!hl || hl->nmark == 0)
3562
if (prec_num > hl->nmark)
3563
hseq = hl->nmark - 1;
3564
else if (prec_num > 0)
3565
hseq = prec_num - 1;
3567
if (hseq >= hl->nmark)
3569
po = hl->marks + hseq;
3570
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3572
an = retrieveAnchor(Currentbuf->formitem, po->line, po->pos);
3574
} while (an == NULL);
3576
gotoLine(Currentbuf, po->line);
3577
Currentbuf->pos = po->pos;
3578
arrangeCursor(Currentbuf);
3579
displayBuffer(Currentbuf, B_NORMAL);
3582
/* go to the last anchor */
3583
DEFUN(lastA, LINK_END, "Go to the last link")
3585
HmarkerList *hl = Currentbuf->hmarklist;
3590
if (Currentbuf->firstLine == NULL)
3592
if (!hl || hl->nmark == 0)
3595
if (prec_num >= hl->nmark)
3597
else if (prec_num > 0)
3598
hseq = hl->nmark - prec_num;
3600
hseq = hl->nmark - 1;
3604
po = hl->marks + hseq;
3605
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3607
an = retrieveAnchor(Currentbuf->formitem, po->line, po->pos);
3609
} while (an == NULL);
3611
gotoLine(Currentbuf, po->line);
3612
Currentbuf->pos = po->pos;
3613
arrangeCursor(Currentbuf);
3614
displayBuffer(Currentbuf, B_NORMAL);
3617
/* go to the nth anchor */
3618
DEFUN(nthA, LINK_N, "Go to the nth link")
3620
HmarkerList *hl = Currentbuf->hmarklist;
3624
int n = searchKeyNum();
3625
if (n < 0 || n > hl->nmark) return;
3627
if (Currentbuf->firstLine == NULL)
3629
if (!hl || hl->nmark == 0)
3632
po = hl->marks + n-1;
3633
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3635
an = retrieveAnchor(Currentbuf->formitem, po->line, po->pos);
3636
if (an == NULL) return;
3638
gotoLine(Currentbuf, po->line);
3639
Currentbuf->pos = po->pos;
3640
arrangeCursor(Currentbuf);
3641
displayBuffer(Currentbuf, B_NORMAL);
3644
/* go to the next anchor */
3645
DEFUN(nextA, NEXT_LINK, "Move to next link")
3650
/* go to the previous anchor */
3651
DEFUN(prevA, PREV_LINK, "Move to previous link")
3656
/* go to the next visited anchor */
3657
DEFUN(nextVA, NEXT_VISITED, "Move to next visited link")
3662
/* go to the previous visited anchor */
3663
DEFUN(prevVA, PREV_VISITED, "Move to previous visited link")
3668
/* go to the next [visited] anchor */
3672
HmarkerList *hl = Currentbuf->hmarklist;
3675
int i, x, y, n = searchKeyNum();
3678
if (Currentbuf->firstLine == NULL)
3680
if (!hl || hl->nmark == 0)
3683
an = retrieveCurrentAnchor(Currentbuf);
3684
if (visited != TRUE && an == NULL)
3685
an = retrieveCurrentForm(Currentbuf);
3687
y = Currentbuf->currentLine->linenumber;
3688
x = Currentbuf->pos;
3690
if (visited == TRUE) {
3694
for (i = 0; i < n; i++) {
3696
if (an && an->hseq >= 0) {
3697
int hseq = an->hseq + 1;
3699
if (hseq >= hl->nmark) {
3700
if (visited == TRUE)
3705
po = &hl->marks[hseq];
3706
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3707
if (visited != TRUE && an == NULL)
3708
an = retrieveAnchor(Currentbuf->formitem, po->line,
3711
if (visited == TRUE && an) {
3712
parseURL2(an->url, &url, baseURL(Currentbuf));
3713
if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
3717
} while (an == NULL || an == pan);
3720
an = closest_next_anchor(Currentbuf->href, NULL, x, y);
3721
if (visited != TRUE)
3722
an = closest_next_anchor(Currentbuf->formitem, an, x, y);
3724
if (visited == TRUE)
3731
if (visited == TRUE) {
3732
parseURL2(an->url, &url, baseURL(Currentbuf));
3733
if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
3739
if (visited == TRUE)
3743
if (an == NULL || an->hseq < 0)
3745
po = &hl->marks[an->hseq];
3746
gotoLine(Currentbuf, po->line);
3747
Currentbuf->pos = po->pos;
3748
arrangeCursor(Currentbuf);
3749
displayBuffer(Currentbuf, B_NORMAL);
3752
/* go to the previous anchor */
3756
HmarkerList *hl = Currentbuf->hmarklist;
3759
int i, x, y, n = searchKeyNum();
3762
if (Currentbuf->firstLine == NULL)
3764
if (!hl || hl->nmark == 0)
3767
an = retrieveCurrentAnchor(Currentbuf);
3768
if (visited != TRUE && an == NULL)
3769
an = retrieveCurrentForm(Currentbuf);
3771
y = Currentbuf->currentLine->linenumber;
3772
x = Currentbuf->pos;
3774
if (visited == TRUE) {
3778
for (i = 0; i < n; i++) {
3780
if (an && an->hseq >= 0) {
3781
int hseq = an->hseq - 1;
3784
if (visited == TRUE)
3789
po = hl->marks + hseq;
3790
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3791
if (visited != TRUE && an == NULL)
3792
an = retrieveAnchor(Currentbuf->formitem, po->line,
3795
if (visited == TRUE && an) {
3796
parseURL2(an->url, &url, baseURL(Currentbuf));
3797
if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
3801
} while (an == NULL || an == pan);
3804
an = closest_prev_anchor(Currentbuf->href, NULL, x, y);
3805
if (visited != TRUE)
3806
an = closest_prev_anchor(Currentbuf->formitem, an, x, y);
3808
if (visited == TRUE)
3815
if (visited == TRUE && an) {
3816
parseURL2(an->url, &url, baseURL(Currentbuf));
3817
if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
3823
if (visited == TRUE)
3827
if (an == NULL || an->hseq < 0)
3829
po = hl->marks + an->hseq;
3830
gotoLine(Currentbuf, po->line);
3831
Currentbuf->pos = po->pos;
3832
arrangeCursor(Currentbuf);
3833
displayBuffer(Currentbuf, B_NORMAL);
3836
/* go to the next left/right anchor */
3838
nextX(int d, int dy)
3840
HmarkerList *hl = Currentbuf->hmarklist;
3843
int i, x, y, n = searchKeyNum();
3845
if (Currentbuf->firstLine == NULL)
3847
if (!hl || hl->nmark == 0)
3850
an = retrieveCurrentAnchor(Currentbuf);
3852
an = retrieveCurrentForm(Currentbuf);
3854
l = Currentbuf->currentLine;
3855
x = Currentbuf->pos;
3858
for (i = 0; i < n; i++) {
3860
x = (d > 0) ? an->end.pos : an->start.pos - 1;
3863
for (; x >= 0 && x < l->len; x += d) {
3864
an = retrieveAnchor(Currentbuf->href, y, x);
3866
an = retrieveAnchor(Currentbuf->formitem, y, x);
3874
l = (dy > 0) ? l->next : l->prev;
3877
x = (d > 0) ? 0 : l->len - 1;
3886
gotoLine(Currentbuf, y);
3887
Currentbuf->pos = pan->start.pos;
3888
arrangeCursor(Currentbuf);
3889
displayBuffer(Currentbuf, B_NORMAL);
3892
/* go to the next downward/upward anchor */
3896
HmarkerList *hl = Currentbuf->hmarklist;
3898
int i, x, y, n = searchKeyNum();
3901
if (Currentbuf->firstLine == NULL)
3903
if (!hl || hl->nmark == 0)
3906
an = retrieveCurrentAnchor(Currentbuf);
3908
an = retrieveCurrentForm(Currentbuf);
3910
x = Currentbuf->pos;
3911
y = Currentbuf->currentLine->linenumber + d;
3914
for (i = 0; i < n; i++) {
3916
hseq = abs(an->hseq);
3918
for (; y >= 0 && y <= Currentbuf->lastLine->linenumber; y += d) {
3919
an = retrieveAnchor(Currentbuf->href, y, x);
3921
an = retrieveAnchor(Currentbuf->formitem, y, x);
3922
if (an && hseq != abs(an->hseq)) {
3933
gotoLine(Currentbuf, pan->start.line);
3934
arrangeLine(Currentbuf);
3935
displayBuffer(Currentbuf, B_NORMAL);
3938
/* go to the next left anchor */
3939
DEFUN(nextL, NEXT_LEFT, "Move to next left link")
3944
/* go to the next left-up anchor */
3945
DEFUN(nextLU, NEXT_LEFT_UP, "Move to next left (or upward) link")
3950
/* go to the next right anchor */
3951
DEFUN(nextR, NEXT_RIGHT, "Move to next right link")
3956
/* go to the next right-down anchor */
3957
DEFUN(nextRD, NEXT_RIGHT_DOWN, "Move to next right (or downward) link")
3962
/* go to the next downward anchor */
3963
DEFUN(nextD, NEXT_DOWN, "Move to next downward link")
3968
/* go to the next upward anchor */
3969
DEFUN(nextU, NEXT_UP, "Move to next upward link")
3974
/* go to the next bufferr */
3975
DEFUN(nextBf, NEXT, "Move to next buffer")
3980
for (i = 0; i < PREC_NUM; i++) {
3981
buf = prevBuffer(Firstbuf, Currentbuf);
3989
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3992
/* go to the previous bufferr */
3993
DEFUN(prevBf, PREV, "Move to previous buffer")
3998
for (i = 0; i < PREC_NUM; i++) {
3999
buf = Currentbuf->nextBuffer;
4007
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4011
checkBackBuffer(Buffer *buf)
4013
Buffer *fbuf = buf->linkBuffer[LB_N_FRAME];
4017
return TRUE; /* Currentbuf has stacked frames */
4018
/* when no frames stacked and next is frame source, try next's
4020
if (RenderFrame && fbuf == buf->nextBuffer) {
4021
if (fbuf->nextBuffer != NULL)
4028
if (buf->nextBuffer)
4034
/* delete current buffer and back to the previous buffer */
4035
DEFUN(backBf, BACK, "Back to previous buffer")
4037
Buffer *buf = Currentbuf->linkBuffer[LB_N_FRAME];
4039
if (!checkBackBuffer(Currentbuf)) {
4040
if (close_tab_back && nTab >= 1) {
4041
deleteTab(CurrentTab);
4042
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4045
/* FIXME: gettextize? */
4046
disp_message("Can't back...", TRUE);
4050
delBuffer(Currentbuf);
4054
struct frameset *fs;
4055
long linenumber = buf->frameQ->linenumber;
4056
long top = buf->frameQ->top_linenumber;
4057
int pos = buf->frameQ->pos;
4058
int currentColumn = buf->frameQ->currentColumn;
4059
AnchorList *formitem = buf->frameQ->formitem;
4061
fs = popFrameTree(&(buf->frameQ));
4062
deleteFrameSet(buf->frameset);
4065
if (buf == Currentbuf) {
4067
Currentbuf->topLine = lineSkip(Currentbuf,
4068
Currentbuf->firstLine, top - 1,
4070
gotoLine(Currentbuf, linenumber);
4071
Currentbuf->pos = pos;
4072
Currentbuf->currentColumn = currentColumn;
4073
arrangeCursor(Currentbuf);
4074
formResetBuffer(Currentbuf, formitem);
4077
else if (RenderFrame && buf == Currentbuf) {
4078
delBuffer(Currentbuf);
4081
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4084
DEFUN(deletePrevBuf, DELETE_PREVBUF,
4085
"Delete previous buffer (mainly for local-CGI)")
4087
Buffer *buf = Currentbuf->nextBuffer;
4093
cmd_loadURL(char *url, ParsedURL *current, char *referer, FormList *request)
4097
if (handleMailto(url))
4100
if (!strncasecmp(url, "news:", 5) && strchr(url, '@') == NULL) {
4101
/* news:newsgroup is not supported */
4102
/* FIXME: gettextize? */
4103
disp_err_message("news:newsgroup_name is not supported", TRUE);
4106
#endif /* USE_NNTP */
4109
buf = loadGeneralFile(url, current, referer, 0, request);
4111
/* FIXME: gettextize? */
4112
char *emsg = Sprintf("Can't load %s", conv_from_system(url))->ptr;
4113
disp_err_message(emsg, FALSE);
4115
else if (buf != NO_BUFFER) {
4117
if (RenderFrame && Currentbuf->frameset != NULL)
4120
displayBuffer(Currentbuf, B_NORMAL);
4124
/* go to specified URL */
4126
goURL0(char *prompt, int relative)
4128
char *url, *referer;
4129
ParsedURL p_url, *current;
4130
Buffer *cur_buf = Currentbuf;
4131
const int *no_referer_ptr;
4133
url = searchKeyData();
4135
Hist *hist = copyHist(URLHist);
4138
current = baseURL(Currentbuf);
4140
char *c_url = parsedURL2Str(current)->ptr;
4141
if (DefaultURLString == DEFAULT_URL_CURRENT)
4142
url = url_decode2(c_url, NULL);
4144
pushHist(hist, c_url);
4146
a = retrieveCurrentAnchor(Currentbuf);
4149
parseURL2(a->url, &p_url, current);
4150
a_url = parsedURL2Str(&p_url)->ptr;
4151
if (DefaultURLString == DEFAULT_URL_LINK)
4152
url = url_decode2(a_url, Currentbuf);
4154
pushHist(hist, a_url);
4156
url = inputLineHist(prompt, url, IN_URL, hist);
4161
no_referer_ptr = query_SCONF_NO_REFERER_FROM(&Currentbuf->currentURL);
4162
current = baseURL(Currentbuf);
4163
if ((no_referer_ptr && *no_referer_ptr) ||
4165
current->scheme == SCM_LOCAL || current->scheme == SCM_LOCAL_CGI)
4166
referer = NO_REFERER;
4168
referer = parsedURL2Str(&Currentbuf->currentURL)->ptr;
4169
url = url_encode(url, current, Currentbuf->document_charset);
4174
url = url_encode(url, NULL, 0);
4176
if (url == NULL || *url == '\0') {
4177
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4184
parseURL2(url, &p_url, current);
4185
pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);
4186
cmd_loadURL(url, current, referer, NULL);
4187
if (Currentbuf != cur_buf) /* success */
4188
pushHashHist(URLHist, parsedURL2Str(&Currentbuf->currentURL)->ptr);
4191
DEFUN(goURL, GOTO, "Go to URL")
4193
goURL0("Goto URL: ", FALSE);
4196
DEFUN(gorURL, GOTO_RELATIVE, "Go to relative URL")
4198
goURL0("Goto relative URL: ", TRUE);
4202
cmd_loadBuffer(Buffer *buf, int prop, int linkid)
4205
disp_err_message("Can't load string", FALSE);
4207
else if (buf != NO_BUFFER) {
4208
buf->bufferprop |= (BP_INTERNAL | prop);
4209
if (!(buf->bufferprop & BP_NO_URL))
4210
copyParsedURL(&buf->currentURL, &Currentbuf->currentURL);
4211
if (linkid != LB_NOLINK) {
4212
buf->linkBuffer[REV_LB[linkid]] = Currentbuf;
4213
Currentbuf->linkBuffer[linkid] = buf;
4217
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4221
DEFUN(ldBmark, BOOKMARK VIEW_BOOKMARK, "Read bookmark")
4223
cmd_loadURL(BookmarkFile, NULL, NO_REFERER, NULL);
4227
/* Add current to bookmark */
4228
DEFUN(adBmark, ADD_BOOKMARK, "Add current page to bookmark")
4233
tmp = Sprintf("mode=panel&cookie=%s&bmark=%s&url=%s&title=%s"
4238
(Str_form_quote(localCookie()))->ptr,
4239
(Str_form_quote(Strnew_charp(BookmarkFile)))->ptr,
4240
(Str_form_quote(parsedURL2Str(&Currentbuf->currentURL)))->
4243
(Str_form_quote(wc_conv_strict(Currentbuf->buffername,
4245
BookmarkCharset)))->ptr,
4246
wc_ces_to_charset(BookmarkCharset));
4248
(Str_form_quote(Strnew_charp(Currentbuf->buffername)))->ptr);
4250
request = newFormList(NULL, "post", NULL, NULL, NULL, NULL, NULL);
4251
request->body = tmp->ptr;
4252
request->length = tmp->length;
4253
cmd_loadURL("file:///$LIB/" W3MBOOKMARK_CMDNAME, NULL, NO_REFERER,
4257
/* option setting */
4258
DEFUN(ldOpt, OPTIONS, "Option setting panel")
4260
cmd_loadBuffer(load_option_panel(), BP_NO_URL, LB_NOLINK);
4264
DEFUN(setOpt, SET_OPTION, "Set option")
4268
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4269
opt = searchKeyData();
4270
if (opt == NULL || *opt == '\0' || strchr(opt, '=') == NULL) {
4271
if (opt != NULL && *opt != '\0') {
4272
char *v = get_param_option(opt);
4273
opt = Sprintf("%s=%s", opt, v ? v : "")->ptr;
4275
opt = inputStrHist("Set option: ", opt, TextHist);
4276
if (opt == NULL || *opt == '\0') {
4277
displayBuffer(Currentbuf, B_NORMAL);
4281
if (set_param_option(opt))
4283
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
4286
/* error message list */
4287
DEFUN(msgs, MSGS, "Display error messages")
4289
cmd_loadBuffer(message_list_panel(), BP_NO_URL, LB_NOLINK);
4293
DEFUN(pginfo, INFO, "View info of current document")
4297
if ((buf = Currentbuf->linkBuffer[LB_N_INFO]) != NULL) {
4299
displayBuffer(Currentbuf, B_NORMAL);
4302
if ((buf = Currentbuf->linkBuffer[LB_INFO]) != NULL)
4304
buf = page_info_panel(Currentbuf);
4305
cmd_loadBuffer(buf, BP_NORMAL, LB_INFO);
4309
follow_map(struct parsed_tagarg *arg)
4311
char *name = tag_get_value(arg, "link");
4312
#if defined(MENU_MAP) || defined(USE_IMAGE)
4318
an = retrieveCurrentImg(Currentbuf);
4319
x = Currentbuf->cursorX + Currentbuf->rootX;
4320
y = Currentbuf->cursorY + Currentbuf->rootY;
4321
a = follow_map_menu(Currentbuf, name, an, x, y);
4322
if (a == NULL || a->url == NULL || *(a->url) == '\0') {
4325
Buffer *buf = follow_map_panel(Currentbuf, name);
4328
cmd_loadBuffer(buf, BP_NORMAL, LB_NOLINK);
4330
#if defined(MENU_MAP) || defined(USE_IMAGE)
4333
if (*(a->url) == '#') {
4334
gotoLabel(a->url + 1);
4337
parseURL2(a->url, &p_url, baseURL(Currentbuf));
4338
pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);
4339
if (check_target && open_tab_blank && a->target &&
4340
(!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) {
4345
cmd_loadURL(a->url, baseURL(Currentbuf),
4346
parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL);
4347
if (buf != Currentbuf)
4350
deleteTab(CurrentTab);
4351
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4354
cmd_loadURL(a->url, baseURL(Currentbuf),
4355
parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL);
4361
DEFUN(linkMn, LINK_MENU, "Popup link element menu")
4363
LinkList *l = link_menu(Currentbuf);
4368
if (*(l->url) == '#') {
4369
gotoLabel(l->url + 1);
4372
parseURL2(l->url, &p_url, baseURL(Currentbuf));
4373
pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);
4374
cmd_loadURL(l->url, baseURL(Currentbuf),
4375
parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL);
4379
anchorMn(Anchor *(*menu_func) (Buffer *), int go)
4384
if (!Currentbuf->href || !Currentbuf->hmarklist)
4386
a = menu_func(Currentbuf);
4387
if (!a || a->hseq < 0)
4389
po = &Currentbuf->hmarklist->marks[a->hseq];
4390
gotoLine(Currentbuf, po->line);
4391
Currentbuf->pos = po->pos;
4392
arrangeCursor(Currentbuf);
4393
displayBuffer(Currentbuf, B_NORMAL);
4399
DEFUN(accessKey, ACCESSKEY, "Popup acceskey menu")
4401
anchorMn(accesskey_menu, TRUE);
4405
DEFUN(listMn, LIST_MENU, "Popup link list menu and go to selected link")
4407
anchorMn(list_menu, TRUE);
4410
DEFUN(movlistMn, MOVE_LIST_MENU,
4411
"Popup link list menu and move cursor to selected link")
4413
anchorMn(list_menu, FALSE);
4417
/* link,anchor,image list */
4418
DEFUN(linkLst, LIST, "Show all links and images")
4422
buf = link_list_panel(Currentbuf);
4425
buf->document_charset = Currentbuf->document_charset;
4427
cmd_loadBuffer(buf, BP_NORMAL, LB_NOLINK);
4433
DEFUN(cooLst, COOKIE, "View cookie list")
4437
buf = cookie_list_panel();
4439
cmd_loadBuffer(buf, BP_NO_URL, LB_NOLINK);
4441
#endif /* USE_COOKIE */
4445
DEFUN(ldHist, HISTORY, "View history of URL")
4447
cmd_loadBuffer(historyBuffer(URLHist), BP_NO_URL, LB_NOLINK);
4449
#endif /* USE_HISTORY */
4451
/* download HREF link */
4452
DEFUN(svA, SAVE_LINK, "Save link to file")
4454
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4457
do_download = FALSE;
4460
/* download IMG link */
4461
DEFUN(svI, SAVE_IMAGE, "Save image to file")
4463
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4466
do_download = FALSE;
4470
DEFUN(svBuf, PRINT SAVE_SCREEN, "Save rendered document to file")
4472
char *qfile = NULL, *file;
4476
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4477
file = searchKeyData();
4478
if (file == NULL || *file == '\0') {
4479
/* FIXME: gettextize? */
4480
qfile = inputLineHist("Save buffer to: ", NULL, IN_COMMAND, SaveHist);
4481
if (qfile == NULL || *qfile == '\0') {
4482
displayBuffer(Currentbuf, B_NORMAL);
4486
file = conv_to_system(qfile ? qfile : file);
4489
f = popen(file + 1, "w");
4493
file = unescape_spaces(Strnew_charp(qfile))->ptr;
4494
file = conv_to_system(file);
4496
file = expandPath(file);
4497
if (checkOverWrite(file) < 0) {
4498
displayBuffer(Currentbuf, B_NORMAL);
4501
f = fopen(file, "w");
4505
/* FIXME: gettextize? */
4506
char *emsg = Sprintf("Can't open %s", conv_from_system(file))->ptr;
4507
disp_err_message(emsg, TRUE);
4510
saveBuffer(Currentbuf, f, TRUE);
4515
displayBuffer(Currentbuf, B_NORMAL);
4519
DEFUN(svSrc, DOWNLOAD SAVE, "Save document source to file")
4523
if (Currentbuf->sourcefile == NULL)
4525
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4526
PermitSaveToPipe = TRUE;
4527
if (Currentbuf->real_scheme == SCM_LOCAL)
4528
file = conv_from_system(guess_save_name(NULL,
4529
Currentbuf->currentURL.
4532
file = guess_save_name(Currentbuf, Currentbuf->currentURL.file);
4533
doFileCopy(Currentbuf->sourcefile, file);
4534
PermitSaveToPipe = FALSE;
4535
displayBuffer(Currentbuf, B_NORMAL);
4539
_peekURL(int only_img)
4544
static Str s = NULL;
4546
static Lineprop *p = NULL;
4549
static int offset = 0, n;
4551
if (Currentbuf->firstLine == NULL)
4553
if (CurrentKey == prev_key && s != NULL) {
4554
if (s->length - offset >= COLS)
4556
else if (s->length <= offset) /* bug ? */
4564
a = (only_img ? NULL : retrieveCurrentAnchor(Currentbuf));
4566
a = (only_img ? NULL : retrieveCurrentForm(Currentbuf));
4568
a = retrieveCurrentImg(Currentbuf);
4573
s = Strnew_charp(form2str((FormItemList *)a->url));
4576
parseURL2(a->url, &pu, baseURL(Currentbuf));
4577
s = parsedURL2Str(&pu);
4580
s = Strnew_charp(url_decode2(s->ptr, Currentbuf));
4582
s = checkType(s, &pp, NULL);
4583
p = NewAtom_N(Lineprop, s->length);
4584
bcopy((void *)pp, (void *)p, s->length * sizeof(Lineprop));
4588
if (n > 1 && s->length > (n - 1) * (COLS - 1))
4589
offset = (n - 1) * (COLS - 1);
4591
while (offset < s->length && p[offset] & PC_WCHAR2)
4594
disp_message_nomouse(&s->ptr[offset], TRUE);
4598
DEFUN(peekURL, PEEK_LINK, "Peek link URL")
4603
/* peek URL of image */
4604
DEFUN(peekIMG, PEEK_IMG, "Peek image URL")
4609
/* show current URL */
4613
if (Currentbuf->bufferprop & BP_INTERNAL)
4614
return Strnew_size(0);
4615
return parsedURL2Str(&Currentbuf->currentURL);
4618
DEFUN(curURL, PEEK, "Peek current URL")
4620
static Str s = NULL;
4622
static Lineprop *p = NULL;
4625
static int offset = 0, n;
4627
if (Currentbuf->bufferprop & BP_INTERNAL)
4629
if (CurrentKey == prev_key && s != NULL) {
4630
if (s->length - offset >= COLS)
4632
else if (s->length <= offset) /* bug ? */
4639
s = Strnew_charp(url_decode2(s->ptr, NULL));
4641
s = checkType(s, &pp, NULL);
4642
p = NewAtom_N(Lineprop, s->length);
4643
bcopy((void *)pp, (void *)p, s->length * sizeof(Lineprop));
4647
if (n > 1 && s->length > (n - 1) * (COLS - 1))
4648
offset = (n - 1) * (COLS - 1);
4650
while (offset < s->length && p[offset] & PC_WCHAR2)
4653
disp_message_nomouse(&s->ptr[offset], TRUE);
4655
/* view HTML source */
4657
DEFUN(vwSrc, SOURCE VIEW, "View HTML source")
4661
if (Currentbuf->type == NULL || Currentbuf->bufferprop & BP_FRAME)
4663
if ((buf = Currentbuf->linkBuffer[LB_SOURCE]) != NULL ||
4664
(buf = Currentbuf->linkBuffer[LB_N_SOURCE]) != NULL) {
4666
displayBuffer(Currentbuf, B_NORMAL);
4669
if (Currentbuf->sourcefile == NULL) {
4670
if (Currentbuf->pagerSource &&
4671
!strcasecmp(Currentbuf->type, "text/plain")) {
4674
wc_bool old_fix_width_conv;
4677
Str tmpf = tmpfname(TMPF_SRC, NULL);
4678
f = fopen(tmpf->ptr, "w");
4682
old_charset = DisplayCharset;
4683
old_fix_width_conv = WcOption.fix_width_conv;
4684
DisplayCharset = (Currentbuf->document_charset != WC_CES_US_ASCII)
4685
? Currentbuf->document_charset : 0;
4686
WcOption.fix_width_conv = WC_FALSE;
4688
saveBufferBody(Currentbuf, f, TRUE);
4690
DisplayCharset = old_charset;
4691
WcOption.fix_width_conv = old_fix_width_conv;
4694
Currentbuf->sourcefile = tmpf->ptr;
4701
buf = newBuffer(INIT_BUFFER_WIDTH);
4703
if (is_html_type(Currentbuf->type)) {
4704
buf->type = "text/plain";
4705
if (Currentbuf->real_type &&
4706
is_html_type(Currentbuf->real_type))
4707
buf->real_type = "text/plain";
4709
buf->real_type = Currentbuf->real_type;
4710
buf->buffername = Sprintf("source of %s", Currentbuf->buffername)->ptr;
4711
buf->linkBuffer[LB_N_SOURCE] = Currentbuf;
4712
Currentbuf->linkBuffer[LB_SOURCE] = buf;
4714
else if (!strcasecmp(Currentbuf->type, "text/plain")) {
4715
buf->type = "text/html";
4716
if (Currentbuf->real_type &&
4717
!strcasecmp(Currentbuf->real_type, "text/plain"))
4718
buf->real_type = "text/html";
4720
buf->real_type = Currentbuf->real_type;
4721
buf->buffername = Sprintf("HTML view of %s",
4722
Currentbuf->buffername)->ptr;
4723
buf->linkBuffer[LB_SOURCE] = Currentbuf;
4724
Currentbuf->linkBuffer[LB_N_SOURCE] = buf;
4729
buf->currentURL = Currentbuf->currentURL;
4730
buf->real_scheme = Currentbuf->real_scheme;
4731
buf->filename = Currentbuf->filename;
4732
buf->sourcefile = Currentbuf->sourcefile;
4733
buf->header_source = Currentbuf->header_source;
4734
buf->search_header = Currentbuf->search_header;
4736
buf->document_charset = Currentbuf->document_charset;
4738
buf->clone = Currentbuf->clone;
4741
buf->need_reshape = TRUE;
4744
displayBuffer(Currentbuf, B_NORMAL);
4748
DEFUN(reload, RELOAD, "Reload buffer")
4750
Buffer *buf, *fbuf = NULL, sbuf;
4758
if (Currentbuf->bufferprop & BP_INTERNAL) {
4759
if (!strcmp(Currentbuf->buffername, DOWNLOAD_LIST_TITLE)) {
4763
/* FIXME: gettextize? */
4764
disp_err_message("Can't reload...", TRUE);
4767
if (Currentbuf->currentURL.scheme == SCM_LOCAL &&
4768
!strcmp(Currentbuf->currentURL.file, "-")) {
4769
/* file is std input */
4770
/* FIXME: gettextize? */
4771
disp_err_message("Can't reload stdin", TRUE);
4774
copyBuffer(&sbuf, Currentbuf);
4775
if (Currentbuf->bufferprop & BP_FRAME &&
4776
(fbuf = Currentbuf->linkBuffer[LB_N_FRAME])) {
4777
if (fmInitialized) {
4778
message("Rendering frame", 0, 0);
4781
if (!(buf = renderFrame(fbuf, 1))) {
4782
displayBuffer(Currentbuf, B_NORMAL);
4785
if (fbuf->linkBuffer[LB_FRAME]) {
4786
if (buf->sourcefile &&
4787
fbuf->linkBuffer[LB_FRAME]->sourcefile &&
4788
!strcmp(buf->sourcefile,
4789
fbuf->linkBuffer[LB_FRAME]->sourcefile))
4790
fbuf->linkBuffer[LB_FRAME]->sourcefile = NULL;
4791
delBuffer(fbuf->linkBuffer[LB_FRAME]);
4793
fbuf->linkBuffer[LB_FRAME] = buf;
4794
buf->linkBuffer[LB_N_FRAME] = fbuf;
4797
if (Currentbuf->firstLine) {
4798
COPY_BUFROOT(Currentbuf, &sbuf);
4799
restorePosition(Currentbuf, &sbuf);
4801
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4804
else if (Currentbuf->frameset != NULL)
4805
fbuf = Currentbuf->linkBuffer[LB_FRAME];
4807
if (Currentbuf->form_submit) {
4808
request = Currentbuf->form_submit->parent;
4809
if (request->method == FORM_METHOD_POST
4810
&& request->enctype == FORM_ENCTYPE_MULTIPART) {
4814
query_from_followform(&query, Currentbuf->form_submit, multipart);
4815
stat(request->body, &st);
4816
request->length = st.st_size;
4822
url = parsedURL2Str(&Currentbuf->currentURL);
4823
/* FIXME: gettextize? */
4824
message("Reloading...", 0, 0);
4827
old_charset = DocumentCharset;
4828
if (Currentbuf->document_charset != WC_CES_US_ASCII)
4829
DocumentCharset = Currentbuf->document_charset;
4831
SearchHeader = Currentbuf->search_header;
4832
DefaultType = Currentbuf->real_type;
4833
buf = loadGeneralFile(url->ptr, NULL, NO_REFERER, RG_NOCACHE, request);
4835
DocumentCharset = old_charset;
4837
SearchHeader = FALSE;
4841
unlink(request->body);
4843
/* FIXME: gettextize? */
4844
disp_err_message("Can't reload...", TRUE);
4847
else if (buf == NO_BUFFER) {
4848
displayBuffer(Currentbuf, B_NORMAL);
4852
Firstbuf = deleteBuffer(Firstbuf, fbuf);
4853
repBuffer(Currentbuf, buf);
4854
if ((buf->type != NULL) && (sbuf.type != NULL) &&
4855
((!strcasecmp(buf->type, "text/plain") &&
4856
is_html_type(sbuf.type)) ||
4857
(is_html_type(buf->type) &&
4858
!strcasecmp(sbuf.type, "text/plain")))) {
4860
if (Currentbuf != buf)
4861
Firstbuf = deleteBuffer(Firstbuf, buf);
4863
Currentbuf->search_header = sbuf.search_header;
4864
Currentbuf->form_submit = sbuf.form_submit;
4865
if (Currentbuf->firstLine) {
4866
COPY_BUFROOT(Currentbuf, &sbuf);
4867
restorePosition(Currentbuf, &sbuf);
4869
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4873
DEFUN(reshape, RESHAPE, "Re-render buffer")
4875
Currentbuf->need_reshape = TRUE;
4876
reshapeBuffer(Currentbuf);
4877
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4882
_docCSet(wc_ces charset)
4884
if (Currentbuf->bufferprop & BP_INTERNAL)
4886
if (Currentbuf->sourcefile == NULL) {
4887
disp_message("Can't reload...", FALSE);
4890
Currentbuf->document_charset = charset;
4891
Currentbuf->need_reshape = TRUE;
4892
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4896
change_charset(struct parsed_tagarg *arg)
4898
Buffer *buf = Currentbuf->linkBuffer[LB_N_INFO];
4903
delBuffer(Currentbuf);
4905
if (Currentbuf->bufferprop & BP_INTERNAL)
4907
charset = Currentbuf->document_charset;
4908
for (; arg; arg = arg->next) {
4909
if (!strcmp(arg->arg, "charset"))
4910
charset = atoi(arg->value);
4915
DEFUN(docCSet, CHARSET, "Change the current document charset")
4920
cs = searchKeyData();
4921
if (cs == NULL || *cs == '\0')
4922
/* FIXME: gettextize? */
4923
cs = inputStr("Document charset: ",
4924
wc_ces_to_charset(Currentbuf->document_charset));
4925
charset = wc_guess_charset_short(cs, 0);
4927
displayBuffer(Currentbuf, B_NORMAL);
4933
DEFUN(defCSet, DEFAULT_CHARSET, "Change the default document charset")
4938
cs = searchKeyData();
4939
if (cs == NULL || *cs == '\0')
4940
/* FIXME: gettextize? */
4941
cs = inputStr("Default document charset: ",
4942
wc_ces_to_charset(DocumentCharset));
4943
charset = wc_guess_charset_short(cs, 0);
4945
DocumentCharset = charset;
4946
displayBuffer(Currentbuf, B_NORMAL);
4950
/* mark URL-like patterns as anchors */
4952
chkURLBuffer(Buffer *buf)
4954
static char *url_like_pat[] = {
4955
"https?://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$;]*[a-zA-Z0-9_/=\\-]",
4956
"file:/[a-zA-Z0-9:%\\-\\./=_\\+@#,\\$;]*",
4958
"gopher://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./_]*",
4959
#endif /* USE_GOPHER */
4960
"ftp://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./=_+@#,\\$]*[a-zA-Z0-9_/]",
4962
"news:[^<> ][^<> ]*",
4963
"nntp://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./_]*",
4964
#endif /* USE_NNTP */
4965
#ifndef USE_W3MMAILER /* see also chkExternalURIBuffer() */
4966
"mailto:[^<> ][^<> ]*@[a-zA-Z0-9][a-zA-Z0-9\\-\\._]*[a-zA-Z0-9]",
4969
"https?://[a-zA-Z0-9:%\\-\\./_@]*\\[[a-fA-F0-9:][a-fA-F0-9:\\.]*\\][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$;]*",
4970
"ftp://[a-zA-Z0-9:%\\-\\./_@]*\\[[a-fA-F0-9:][a-fA-F0-9:\\.]*\\][a-zA-Z0-9:%\\-\\./=_+@#,\\$]*",
4975
for (i = 0; url_like_pat[i]; i++) {
4976
reAnchor(buf, url_like_pat[i]);
4978
#ifdef USE_EXTERNAL_URI_LOADER
4979
chkExternalURIBuffer(buf);
4981
buf->check_url |= CHK_URL;
4984
DEFUN(chkURL, MARK_URL, "Mark URL-like strings as anchors")
4986
chkURLBuffer(Currentbuf);
4987
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4990
DEFUN(chkWORD, MARK_WORD, "Mark current word as anchor")
4994
p = getCurWord(Currentbuf, &spos, &epos);
4997
reAnchorWord(Currentbuf, Currentbuf->currentLine, spos, epos);
4998
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5002
/* mark Message-ID-like patterns as NEWS anchors */
5004
chkNMIDBuffer(Buffer *buf)
5006
static char *url_like_pat[] = {
5007
"<[!-;=?-~]+@[a-zA-Z0-9\\.\\-_]+>",
5011
for (i = 0; url_like_pat[i]; i++) {
5012
reAnchorNews(buf, url_like_pat[i]);
5014
buf->check_url |= CHK_NMID;
5017
DEFUN(chkNMID, MARK_MID, "Mark Message-ID-like strings as anchors")
5019
chkNMIDBuffer(Currentbuf);
5020
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5022
#endif /* USE_NNTP */
5025
DEFUN(rFrame, FRAME, "Render frame")
5029
if ((buf = Currentbuf->linkBuffer[LB_FRAME]) != NULL) {
5031
displayBuffer(Currentbuf, B_NORMAL);
5034
if (Currentbuf->frameset == NULL) {
5035
if ((buf = Currentbuf->linkBuffer[LB_N_FRAME]) != NULL) {
5037
displayBuffer(Currentbuf, B_NORMAL);
5041
if (fmInitialized) {
5042
message("Rendering frame", 0, 0);
5045
buf = renderFrame(Currentbuf, 0);
5047
displayBuffer(Currentbuf, B_NORMAL);
5050
buf->linkBuffer[LB_N_FRAME] = Currentbuf;
5051
Currentbuf->linkBuffer[LB_FRAME] = buf;
5053
if (fmInitialized && display_ok)
5054
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5057
/* spawn external browser */
5059
invoke_browser(char *url)
5062
char *browser = NULL;
5065
CurrentKeyData = NULL; /* not allowed in w3m-control: */
5066
browser = searchKeyData();
5067
if (browser == NULL || *browser == '\0') {
5071
browser = ExtBrowser;
5074
browser = ExtBrowser2;
5077
browser = ExtBrowser3;
5080
if (browser == NULL || *browser == '\0') {
5081
browser = inputStr("Browse command: ", NULL);
5082
if (browser != NULL)
5083
browser = conv_to_system(browser);
5087
browser = conv_to_system(browser);
5089
if (browser == NULL || *browser == '\0') {
5090
displayBuffer(Currentbuf, B_NORMAL);
5094
if ((len = strlen(browser)) >= 2 && browser[len - 1] == '&' &&
5095
browser[len - 2] != '\\') {
5096
browser = allocStr(browser, len - 2);
5099
cmd = myExtCommand(browser, shell_quote(url), FALSE);
5100
Strremovetrailingspaces(cmd);
5102
mySystem(cmd->ptr, bg);
5104
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5107
DEFUN(extbrz, EXTERN, "Execute external browser")
5109
if (Currentbuf->bufferprop & BP_INTERNAL) {
5110
/* FIXME: gettextize? */
5111
disp_err_message("Can't browse...", TRUE);
5114
if (Currentbuf->currentURL.scheme == SCM_LOCAL &&
5115
!strcmp(Currentbuf->currentURL.file, "-")) {
5116
/* file is std input */
5117
/* FIXME: gettextize? */
5118
disp_err_message("Can't browse stdin", TRUE);
5121
invoke_browser(parsedURL2Str(&Currentbuf->currentURL)->ptr);
5124
DEFUN(linkbrz, EXTERN_LINK, "View current link using external browser")
5129
if (Currentbuf->firstLine == NULL)
5131
a = retrieveCurrentAnchor(Currentbuf);
5134
parseURL2(a->url, &pu, baseURL(Currentbuf));
5135
invoke_browser(parsedURL2Str(&pu)->ptr);
5138
/* show current line number and number of lines in the entire document */
5139
DEFUN(curlno, LINE_INFO, "Show current line number")
5141
Line *l = Currentbuf->currentLine;
5143
int cur = 0, all = 0, col = 0, len = 0;
5146
cur = l->real_linenumber;
5147
col = l->bwidth + Currentbuf->currentColumn + Currentbuf->cursorX + 1;
5148
while (l->next && l->next->bpos)
5151
l->width = COLPOS(l, l->len);
5152
len = l->bwidth + l->width;
5154
if (Currentbuf->lastLine)
5155
all = Currentbuf->lastLine->real_linenumber;
5156
if (Currentbuf->pagerSource && !(Currentbuf->bufferprop & BP_CLOSE))
5157
tmp = Sprintf("line %d col %d/%d", cur, col, len);
5159
tmp = Sprintf("line %d/%d (%d%%) col %d/%d", cur, all,
5160
(int)((double)cur * 100.0 / (double)(all ? all : 1)
5163
Strcat_charp(tmp, " ");
5164
Strcat_charp(tmp, wc_ces_to_charset_desc(Currentbuf->document_charset));
5167
disp_message(tmp->ptr, FALSE);
5171
DEFUN(dispI, DISPLAY_IMAGE, "Restart loading and drawing of images")
5177
displayImage = TRUE;
5179
* if (!(Currentbuf->type && is_html_type(Currentbuf->type)))
5182
Currentbuf->image_flag = IMG_FLAG_AUTO;
5183
Currentbuf->need_reshape = TRUE;
5184
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
5187
DEFUN(stopI, STOP_IMAGE, "Stop loading and drawing of images")
5192
* if (!(Currentbuf->type && is_html_type(Currentbuf->type)))
5195
Currentbuf->image_flag = IMG_FLAG_SKIP;
5196
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
5203
mouse_scroll_line(void)
5205
if (relative_wheel_scroll)
5206
return (relative_wheel_scroll_ratio * LASTLINE + 99) / 100;
5208
return fixed_wheel_scroll_count;
5212
posTab(int x, int y)
5216
if (mouse_action.menu_str && x < mouse_action.menu_width && y == 0)
5217
return NO_TABBUFFER;
5220
for (tab = FirstTab; tab; tab = tab->nextTab) {
5221
if (tab->x1 <= x && x <= tab->x2 && tab->y == y)
5228
do_mouse_action(int btn, int x, int y)
5230
MouseActionMap *map = NULL;
5233
if (nTab > 1 || mouse_action.menu_str)
5234
ny = LastTab->y + 1;
5237
case MOUSE_BTN1_DOWN:
5240
case MOUSE_BTN2_DOWN:
5243
case MOUSE_BTN3_DOWN:
5250
if (mouse_action.menu_str && x >= 0 && x < mouse_action.menu_width) {
5251
if (mouse_action.menu_map[btn])
5252
map = &mouse_action.menu_map[btn][x];
5255
map = &mouse_action.tab_map[btn];
5257
else if (y == LASTLINE) {
5258
if (mouse_action.lastline_str && x >= 0 &&
5259
x < mouse_action.lastline_width) {
5260
if (mouse_action.lastline_map[btn])
5261
map = &mouse_action.lastline_map[btn][x];
5265
if (y == Currentbuf->cursorY + Currentbuf->rootY &&
5266
(x == Currentbuf->cursorX + Currentbuf->rootX
5268
|| (WcOption.use_wide && Currentbuf->currentLine != NULL &&
5269
(CharType(Currentbuf->currentLine->propBuf[Currentbuf->pos])
5271
&& x == Currentbuf->cursorX + Currentbuf->rootX + 1)
5274
if (retrieveCurrentAnchor(Currentbuf) ||
5275
retrieveCurrentForm(Currentbuf)) {
5276
map = &mouse_action.active_map[btn];
5277
if (!(map && map->func))
5278
map = &mouse_action.anchor_map[btn];
5282
int cx = Currentbuf->cursorX, cy = Currentbuf->cursorY;
5283
cursorXY(Currentbuf, x - Currentbuf->rootX, y - Currentbuf->rootY);
5284
if (y == Currentbuf->cursorY + Currentbuf->rootY &&
5285
(x == Currentbuf->cursorX + Currentbuf->rootX
5287
|| (WcOption.use_wide && Currentbuf->currentLine != NULL &&
5288
(CharType(Currentbuf->currentLine->
5289
propBuf[Currentbuf->pos]) == PC_KANJI1)
5290
&& x == Currentbuf->cursorX + Currentbuf->rootX + 1)
5293
(retrieveCurrentAnchor(Currentbuf) ||
5294
retrieveCurrentForm(Currentbuf)))
5295
map = &mouse_action.anchor_map[btn];
5296
cursorXY(Currentbuf, cx, cy);
5302
if (!(map && map->func))
5303
map = &mouse_action.default_map[btn];
5304
if (map && map->func) {
5305
mouse_action.in_action = TRUE;
5306
mouse_action.cursorX = x;
5307
mouse_action.cursorY = y;
5309
CurrentKeyData = NULL;
5310
CurrentCmdData = map->data;
5312
CurrentCmdData = NULL;
5317
process_mouse(int btn, int x, int y)
5319
int delta_x, delta_y, i;
5320
static int press_btn = MOUSE_BTN_RESET, press_x, press_y;
5324
if (nTab > 1 || mouse_action.menu_str)
5325
ny = LastTab->y + 1;
5326
if (btn == MOUSE_BTN_UP) {
5327
switch (press_btn) {
5328
case MOUSE_BTN1_DOWN:
5329
if (press_y == y && press_x == x)
5330
do_mouse_action(press_btn, x, y);
5331
else if (ny > 0 && y < ny) {
5333
moveTab(posTab(press_x, press_y), posTab(x, y),
5334
(press_y == y) ? (press_x < x) : (press_y < y));
5337
else if (press_x >= Currentbuf->rootX) {
5338
Buffer *buf = Currentbuf;
5339
int cx = Currentbuf->cursorX, cy = Currentbuf->cursorY;
5344
if (t == NO_TABBUFFER)
5345
t = NULL; /* open new tab */
5346
cursorXY(Currentbuf, press_x - Currentbuf->rootX,
5347
press_y - Currentbuf->rootY);
5348
if (Currentbuf->cursorY == press_y - Currentbuf->rootY &&
5349
(Currentbuf->cursorX == press_x - Currentbuf->rootX
5351
|| (WcOption.use_wide &&
5352
Currentbuf->currentLine != NULL &&
5353
(CharType(Currentbuf->currentLine->
5354
propBuf[Currentbuf->pos]) == PC_KANJI1)
5355
&& Currentbuf->cursorX == press_x
5356
- Currentbuf->rootX - 1)
5359
displayBuffer(Currentbuf, B_NORMAL);
5362
if (buf == Currentbuf)
5363
cursorXY(Currentbuf, cx, cy);
5368
delta_x = x - press_x;
5369
delta_y = y - press_y;
5371
if (abs(delta_x) < abs(delta_y) / 3)
5373
if (abs(delta_y) < abs(delta_x) / 3)
5375
if (reverse_mouse) {
5383
else if (delta_y < 0) {
5384
prec_num = -delta_y;
5391
else if (delta_x < 0) {
5392
prec_num = -delta_x;
5397
case MOUSE_BTN2_DOWN:
5398
case MOUSE_BTN3_DOWN:
5399
if (press_y == y && press_x == x)
5400
do_mouse_action(press_btn, x, y);
5402
case MOUSE_BTN4_DOWN_RXVT:
5403
for (i = 0; i < mouse_scroll_line(); i++)
5406
case MOUSE_BTN5_DOWN_RXVT:
5407
for (i = 0; i < mouse_scroll_line(); i++)
5412
else if (btn == MOUSE_BTN4_DOWN_XTERM) {
5413
for (i = 0; i < mouse_scroll_line(); i++)
5416
else if (btn == MOUSE_BTN5_DOWN_XTERM) {
5417
for (i = 0; i < mouse_scroll_line(); i++)
5421
if (btn != MOUSE_BTN4_DOWN_RXVT || press_btn == MOUSE_BTN_RESET) {
5427
press_btn = MOUSE_BTN_RESET;
5431
DEFUN(msToggle, MOUSE_TOGGLE, "Toggle activity of mouse")
5439
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5442
DEFUN(mouse, MOUSE, "mouse operation")
5446
btn = (unsigned char)getch() - 32;
5447
#if defined(__CYGWIN__) && CYGWIN_VERSION_DLL_MAJOR < 1005
5448
if (cygwin_mouse_btn_swapped) {
5449
if (btn == MOUSE_BTN2_DOWN)
5450
btn = MOUSE_BTN3_DOWN;
5451
else if (btn == MOUSE_BTN3_DOWN)
5452
btn = MOUSE_BTN2_DOWN;
5455
x = (unsigned char)getch() - 33;
5458
y = (unsigned char)getch() - 33;
5462
if (x < 0 || x >= COLS || y < 0 || y > LASTLINE)
5464
process_mouse(btn, x, y);
5467
DEFUN(sgrmouse, SGRMOUSE, "SGR 1006 mouse operation")
5469
int btn = 0, x = 0, y = 0;
5475
btn = btn * 10 + c - '0';
5482
#if defined(__CYGWIN__) && CYGWIN_VERSION_DLL_MAJOR < 1005
5483
if (cygwin_mouse_btn_swapped) {
5484
if (btn == MOUSE_BTN2_DOWN)
5485
btn = MOUSE_BTN3_DOWN;
5486
else if (btn == MOUSE_BTN3_DOWN)
5487
btn = MOUSE_BTN2_DOWN;
5494
x = x * 10 + c - '0';
5504
y = y * 10 + c - '0';
5507
else if (c == 'm') {
5514
if (x < 0 || x >= COLS || y < 0 || y > LASTLINE)
5516
process_mouse(btn, x, y);
5521
gpm_process_mouse(Gpm_Event * event, void *data)
5523
int btn = MOUSE_BTN_RESET, x, y;
5524
if (event->type & GPM_UP)
5526
else if (event->type & GPM_DOWN) {
5527
switch (event->buttons) {
5529
btn = MOUSE_BTN1_DOWN;
5532
btn = MOUSE_BTN2_DOWN;
5535
btn = MOUSE_BTN3_DOWN;
5540
GPM_DRAWPOINTER(event);
5545
process_mouse(btn, x - 1, y - 1);
5548
#endif /* USE_GPM */
5552
sysm_process_mouse(int x, int y, int nbs, int obs)
5559
else if (nbs & ~obs) {
5561
btn = bits & 0x1 ? MOUSE_BTN1_DOWN :
5562
(bits & 0x2 ? MOUSE_BTN2_DOWN :
5563
(bits & 0x4 ? MOUSE_BTN3_DOWN : 0));
5565
else /* nbs == obs */
5567
process_mouse(btn, x, y);
5570
#endif /* USE_SYSMOUSE */
5572
DEFUN(movMs, MOVE_MOUSE, "Move cursor to mouse cursor (for mouse action)")
5574
if (!mouse_action.in_action)
5576
if ((nTab > 1 || mouse_action.menu_str) &&
5577
mouse_action.cursorY < LastTab->y + 1)
5579
else if (mouse_action.cursorX >= Currentbuf->rootX &&
5580
mouse_action.cursorY < LASTLINE) {
5581
cursorXY(Currentbuf, mouse_action.cursorX - Currentbuf->rootX,
5582
mouse_action.cursorY - Currentbuf->rootY);
5584
displayBuffer(Currentbuf, B_NORMAL);
5588
#ifdef KANJI_SYMBOLS
5589
#define FRAME_WIDTH 2
5591
#define FRAME_WIDTH 1
5594
DEFUN(menuMs, MENU_MOUSE, "Popup menu at mouse cursor (for mouse action)")
5596
if (!mouse_action.in_action)
5598
if ((nTab > 1 || mouse_action.menu_str) &&
5599
mouse_action.cursorY < LastTab->y + 1)
5600
mouse_action.cursorX -= FRAME_WIDTH + 1;
5601
else if (mouse_action.cursorX >= Currentbuf->rootX &&
5602
mouse_action.cursorY < LASTLINE) {
5603
cursorXY(Currentbuf, mouse_action.cursorX - Currentbuf->rootX,
5604
mouse_action.cursorY - Currentbuf->rootY);
5605
displayBuffer(Currentbuf, B_NORMAL);
5611
DEFUN(tabMs, TAB_MOUSE, "Move to tab on mouse cursor (for mouse action)")
5615
if (!mouse_action.in_action)
5617
tab = posTab(mouse_action.cursorX, mouse_action.cursorY);
5618
if (!tab || tab == NO_TABBUFFER)
5621
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5624
DEFUN(closeTMs, CLOSE_TAB_MOUSE,
5625
"Close tab on mouse cursor (for mouse action)")
5629
if (!mouse_action.in_action)
5631
tab = posTab(mouse_action.cursorX, mouse_action.cursorY);
5632
if (!tab || tab == NO_TABBUFFER)
5635
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5637
#endif /* USE_MOUSE */
5639
DEFUN(dispVer, VERSION, "Display version of w3m")
5641
disp_message(Sprintf("w3m version %s", w3m_version)->ptr, TRUE);
5644
DEFUN(wrapToggle, WRAP_TOGGLE, "Toggle wrap search mode")
5648
/* FIXME: gettextize? */
5649
disp_message("Wrap search off", TRUE);
5653
/* FIXME: gettextize? */
5654
disp_message("Wrap search on", TRUE);
5659
getCurWord(Buffer *buf, int *spos, int *epos)
5662
Line *l = buf->currentLine;
5671
while (e > 0 && !is_wordchar(getChar(&p[e])))
5673
if (!is_wordchar(getChar(&p[e])))
5679
if (!is_wordchar(getChar(&p[tmp])))
5683
while (e < l->len && is_wordchar(getChar(&p[e])))
5691
GetWord(Buffer *buf)
5696
if ((p = getCurWord(buf, &b, &e)) != NULL) {
5697
return Strnew_charp_n(p, e - b)->ptr;
5704
execdict(char *word)
5709
if (!UseDictCommand || word == NULL || *word == '\0') {
5710
displayBuffer(Currentbuf, B_NORMAL);
5713
w = conv_to_system(word);
5715
displayBuffer(Currentbuf, B_NORMAL);
5718
dictcmd = Sprintf("%s?%s", DictCommand,
5719
Str_form_quote(Strnew_charp(w))->ptr)->ptr;
5720
buf = loadGeneralFile(dictcmd, NULL, NO_REFERER, 0, NULL);
5722
disp_message("Execution failed", TRUE);
5725
else if (buf != NO_BUFFER) {
5727
buf->buffername = Sprintf("%s %s", DICTBUFFERNAME, word)->ptr;
5728
if (buf->type == NULL)
5729
buf->type = "text/plain";
5732
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5735
DEFUN(dictword, DICT_WORD, "Execute dictionary command (see README.dict)")
5737
execdict(inputStr("(dictionary)!", ""));
5740
DEFUN(dictwordat, DICT_WORD_AT,
5741
"Execute dictionary command for word at cursor")
5743
execdict(GetWord(Currentbuf));
5745
#endif /* USE_DICT */
5748
set_buffer_environ(Buffer *buf)
5750
static Buffer *prev_buf = NULL;
5751
static Line *prev_line = NULL;
5752
static int prev_pos = -1;
5757
if (buf != prev_buf) {
5758
set_environ("W3M_SOURCEFILE", buf->sourcefile);
5759
set_environ("W3M_FILENAME", buf->filename);
5760
set_environ("W3M_TITLE", buf->buffername);
5761
set_environ("W3M_URL", parsedURL2Str(&buf->currentURL)->ptr);
5762
set_environ("W3M_TYPE", buf->real_type ? buf->real_type : "unknown");
5764
set_environ("W3M_CHARSET", wc_ces_to_charset(buf->document_charset));
5767
l = buf->currentLine;
5768
if (l && (buf != prev_buf || l != prev_line || buf->pos != prev_pos)) {
5771
char *s = GetWord(buf);
5772
set_environ("W3M_CURRENT_WORD", s ? s : "");
5773
a = retrieveCurrentAnchor(buf);
5775
parseURL2(a->url, &pu, baseURL(buf));
5776
set_environ("W3M_CURRENT_LINK", parsedURL2Str(&pu)->ptr);
5779
set_environ("W3M_CURRENT_LINK", "");
5780
a = retrieveCurrentImg(buf);
5782
parseURL2(a->url, &pu, baseURL(buf));
5783
set_environ("W3M_CURRENT_IMG", parsedURL2Str(&pu)->ptr);
5786
set_environ("W3M_CURRENT_IMG", "");
5787
a = retrieveCurrentForm(buf);
5789
set_environ("W3M_CURRENT_FORM", form2str((FormItemList *)a->url));
5791
set_environ("W3M_CURRENT_FORM", "");
5792
set_environ("W3M_CURRENT_LINE", Sprintf("%d",
5793
l->real_linenumber)->ptr);
5794
set_environ("W3M_CURRENT_COLUMN", Sprintf("%d",
5795
buf->currentColumn +
5796
buf->cursorX + 1)->ptr);
5799
set_environ("W3M_CURRENT_WORD", "");
5800
set_environ("W3M_CURRENT_LINK", "");
5801
set_environ("W3M_CURRENT_IMG", "");
5802
set_environ("W3M_CURRENT_FORM", "");
5803
set_environ("W3M_CURRENT_LINE", "0");
5804
set_environ("W3M_CURRENT_COLUMN", "0");
5808
prev_pos = buf->pos;
5816
if (CurrentKeyData != NULL && *CurrentKeyData != '\0')
5817
data = CurrentKeyData;
5818
else if (CurrentCmdData != NULL && *CurrentCmdData != '\0')
5819
data = CurrentCmdData;
5820
else if (CurrentKey >= 0)
5821
data = getKeyData(CurrentKey);
5822
CurrentKeyData = NULL;
5823
CurrentCmdData = NULL;
5824
if (data == NULL || *data == '\0')
5826
return allocStr(data, -1);
5835
d = searchKeyData();
5838
return n * PREC_NUM;
5846
unsigned long CpList[8], CpSize;
5848
if (!getenv("WINDOWID") && !DosQueryCp(sizeof(CpList), CpList, &CpSize))
5849
return Sprintf("CP%d", *CpList)->ptr;
5861
for (CurrentTab = FirstTab; CurrentTab; CurrentTab = CurrentTab->nextTab) {
5862
while (Firstbuf && Firstbuf != NO_BUFFER) {
5863
buf = Firstbuf->nextBuffer;
5864
discardBuffer(Firstbuf);
5868
while ((f = popText(fileToDelete)) != NULL)
5876
init_migemo(); /* close pipe to migemo */
5887
#ifdef __MINGW32_VERSION
5893
DEFUN(execCmd, COMMAND, "Execute w3m command(s)")
5898
CurrentKeyData = NULL; /* not allowed in w3m-control: */
5899
data = searchKeyData();
5900
if (data == NULL || *data == '\0') {
5901
data = inputStrHist("command [; ...]: ", "", TextHist);
5903
displayBuffer(Currentbuf, B_NORMAL);
5907
/* data: FUNC [DATA] [; FUNC [DATA] ...] */
5915
cmd = getFuncList(p);
5918
p = getQWord(&data);
5920
CurrentKeyData = NULL;
5921
CurrentCmdData = *p ? p : NULL;
5926
w3mFuncList[cmd].func();
5931
CurrentCmdData = NULL;
5933
displayBuffer(Currentbuf, B_NORMAL);
5937
static MySignalHandler
5938
SigAlarm(SIGNAL_ARG)
5942
if (CurrentAlarm->sec > 0) {
5944
CurrentKeyData = NULL;
5945
CurrentCmdData = data = (char *)CurrentAlarm->data;
5950
w3mFuncList[CurrentAlarm->cmd].func();
5955
CurrentCmdData = NULL;
5956
if (CurrentAlarm->status == AL_IMPLICIT_ONCE) {
5957
CurrentAlarm->sec = 0;
5958
CurrentAlarm->status = AL_UNSET;
5960
if (Currentbuf->event) {
5961
if (Currentbuf->event->status != AL_UNSET)
5962
CurrentAlarm = Currentbuf->event;
5964
Currentbuf->event = NULL;
5966
if (!Currentbuf->event)
5967
CurrentAlarm = &DefaultAlarm;
5968
if (CurrentAlarm->sec > 0) {
5969
mySignal(SIGALRM, SigAlarm);
5970
alarm(CurrentAlarm->sec);
5977
DEFUN(setAlarm, ALARM, "Set alarm")
5980
int sec = 0, cmd = -1;
5982
CurrentKeyData = NULL; /* not allowed in w3m-control: */
5983
data = searchKeyData();
5984
if (data == NULL || *data == '\0') {
5985
data = inputStrHist("(Alarm)sec command: ", "", TextHist);
5987
displayBuffer(Currentbuf, B_NORMAL);
5991
if (*data != '\0') {
5992
sec = atoi(getWord(&data));
5994
cmd = getFuncList(getWord(&data));
5997
data = getQWord(&data);
5998
setAlarmEvent(&DefaultAlarm, sec, AL_EXPLICIT, cmd, data);
5999
disp_message_nsec(Sprintf("%dsec %s %s", sec, w3mFuncList[cmd].id,
6000
data)->ptr, FALSE, 1, FALSE, TRUE);
6003
setAlarmEvent(&DefaultAlarm, 0, AL_UNSET, FUNCNAME_nulcmd, NULL);
6005
displayBuffer(Currentbuf, B_NORMAL);
6009
setAlarmEvent(AlarmEvent * event, int sec, short status, int cmd, void *data)
6012
event = New(AlarmEvent);
6014
event->status = status;
6021
DEFUN(reinit, REINIT, "Reload configuration files")
6023
char *resource = searchKeyData();
6025
if (resource == NULL) {
6031
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6035
if (!strcasecmp(resource, "CONFIG") || !strcasecmp(resource, "RC")) {
6038
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6043
if (!strcasecmp(resource, "COOKIE")) {
6049
if (!strcasecmp(resource, "KEYMAP")) {
6054
if (!strcasecmp(resource, "MAILCAP")) {
6060
if (!strcasecmp(resource, "MOUSE")) {
6062
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6068
if (!strcasecmp(resource, "MENU")) {
6074
if (!strcasecmp(resource, "MIMETYPES")) {
6079
#ifdef USE_EXTERNAL_URI_LOADER
6080
if (!strcasecmp(resource, "URIMETHODS")) {
6086
disp_err_message(Sprintf("Don't know how to reinitialize '%s'", resource)->
6090
DEFUN(defKey, DEFINE_KEY,
6091
"Define a binding between a key stroke and a user command")
6095
CurrentKeyData = NULL; /* not allowed in w3m-control: */
6096
data = searchKeyData();
6097
if (data == NULL || *data == '\0') {
6098
data = inputStrHist("Key definition: ", "", TextHist);
6099
if (data == NULL || *data == '\0') {
6100
displayBuffer(Currentbuf, B_NORMAL);
6104
setKeymap(allocStr(data, -1), -1, TRUE);
6105
displayBuffer(Currentbuf, B_NORMAL);
6117
n->currentBuffer = NULL;
6118
n->firstBuffer = NULL;
6133
buf = newBuffer(Currentbuf->width);
6134
copyBuffer(buf, Currentbuf);
6135
buf->nextBuffer = NULL;
6136
for (i = 0; i < MAX_LB; i++)
6137
buf->linkBuffer[i] = NULL;
6139
tag->firstBuffer = tag->currentBuffer = buf;
6141
tag->nextTab = CurrentTab->nextTab;
6142
tag->prevTab = CurrentTab;
6143
if (CurrentTab->nextTab)
6144
CurrentTab->nextTab->prevTab = tag;
6147
CurrentTab->nextTab = tag;
6152
DEFUN(newT, NEW_TAB, "Open new tab")
6155
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6170
for (tab = FirstTab, i = 1; tab && i < n; tab = tab->nextTab, i++) ;
6179
int lcol = 0, rcol = 2, col;
6181
int lcol = 0, rcol = 0, col;
6183
int n1, n2, na, nx, ny, ix, iy;
6186
lcol = mouse_action.menu_str ? mouse_action.menu_width : 0;
6191
n1 = (COLS - rcol - lcol) / TabCols;
6199
n2 = COLS / TabCols;
6202
ny = (nTab - n1 - 1) / n2 + 2;
6204
na = n1 + n2 * (ny - 1);
6205
n1 -= (na - nTab) / ny;
6208
na = n1 + n2 * (ny - 1);
6210
for (iy = 0; iy < ny && tab; iy++) {
6213
col = COLS - rcol - lcol;
6216
nx = n2 - (na - nTab + (iy - 1)) / (ny - 1);
6219
for (ix = 0; ix < nx && tab; ix++, tab = tab->nextTab) {
6220
tab->x1 = col * ix / nx;
6221
tab->x2 = col * (ix + 1) / nx - 1;
6232
deleteTab(TabBuffer * tab)
6240
tab->nextTab->prevTab = tab->prevTab;
6242
LastTab = tab->prevTab;
6243
tab->prevTab->nextTab = tab->nextTab;
6244
if (tab == CurrentTab)
6245
CurrentTab = tab->prevTab;
6247
else { /* tab == FirstTab */
6248
tab->nextTab->prevTab = NULL;
6249
FirstTab = tab->nextTab;
6250
if (tab == CurrentTab)
6251
CurrentTab = tab->nextTab;
6254
buf = tab->firstBuffer;
6255
while (buf && buf != NO_BUFFER) {
6256
next = buf->nextBuffer;
6263
DEFUN(closeT, CLOSE_TAB, "Close current tab")
6270
tab = numTab(PREC_NUM);
6275
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6278
DEFUN(nextT, NEXT_TAB, "Move to next tab")
6284
for (i = 0; i < PREC_NUM; i++) {
6285
if (CurrentTab->nextTab)
6286
CurrentTab = CurrentTab->nextTab;
6288
CurrentTab = FirstTab;
6290
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6293
DEFUN(prevT, PREV_TAB, "Move to previous tab")
6299
for (i = 0; i < PREC_NUM; i++) {
6300
if (CurrentTab->prevTab)
6301
CurrentTab = CurrentTab->prevTab;
6303
CurrentTab = LastTab;
6305
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6309
followTab(TabBuffer * tab)
6315
a = retrieveCurrentImg(Currentbuf);
6316
if (!(a && a->image && a->image->map))
6318
a = retrieveCurrentAnchor(Currentbuf);
6322
if (tab == CurrentTab) {
6323
check_target = FALSE;
6325
check_target = TRUE;
6330
check_target = FALSE;
6332
check_target = TRUE;
6334
if (buf != Currentbuf)
6337
deleteTab(CurrentTab);
6339
else if (buf != Currentbuf) {
6340
/* buf <- p <- ... <- Currentbuf = c */
6344
p = prevBuffer(c, buf);
6345
p->nextBuffer = NULL;
6347
deleteTab(CurrentTab);
6349
for (buf = p; buf; buf = p) {
6350
p = prevBuffer(c, buf);
6354
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6357
DEFUN(tabA, TAB_LINK, "Open current link on new tab")
6359
followTab(prec_num ? numTab(PREC_NUM) : NULL);
6363
tabURL0(TabBuffer * tab, char *prompt, int relative)
6367
if (tab == CurrentTab) {
6368
goURL0(prompt, relative);
6373
goURL0(prompt, relative);
6375
if (buf != Currentbuf)
6378
deleteTab(CurrentTab);
6380
else if (buf != Currentbuf) {
6381
/* buf <- p <- ... <- Currentbuf = c */
6385
p = prevBuffer(c, buf);
6386
p->nextBuffer = NULL;
6388
deleteTab(CurrentTab);
6390
for (buf = p; buf; buf = p) {
6391
p = prevBuffer(c, buf);
6395
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6398
DEFUN(tabURL, TAB_GOTO, "Open URL on new tab")
6400
tabURL0(prec_num ? numTab(PREC_NUM) : NULL,
6401
"Goto URL on new tab: ", FALSE);
6404
DEFUN(tabrURL, TAB_GOTO_RELATIVE, "Open relative URL on new tab")
6406
tabURL0(prec_num ? numTab(PREC_NUM) : NULL,
6407
"Goto relative URL on new tab: ", TRUE);
6411
moveTab(TabBuffer * t, TabBuffer * t2, int right)
6413
if (t2 == NO_TABBUFFER)
6415
if (!t || !t2 || t == t2 || t == NO_TABBUFFER)
6419
t->nextTab->prevTab = t->prevTab;
6421
LastTab = t->prevTab;
6422
t->prevTab->nextTab = t->nextTab;
6425
t->nextTab->prevTab = NULL;
6426
FirstTab = t->nextTab;
6429
t->nextTab = t2->nextTab;
6432
t2->nextTab->prevTab = t;
6438
t->prevTab = t2->prevTab;
6441
t2->prevTab->nextTab = t;
6446
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6449
DEFUN(tabR, TAB_RIGHT, "Move current tab right")
6454
for (tab = CurrentTab, i = 0; tab && i < PREC_NUM;
6455
tab = tab->nextTab, i++) ;
6456
moveTab(CurrentTab, tab ? tab : LastTab, TRUE);
6459
DEFUN(tabL, TAB_LEFT, "Move current tab left")
6464
for (tab = CurrentTab, i = 0; tab && i < PREC_NUM;
6465
tab = tab->prevTab, i++) ;
6466
moveTab(CurrentTab, tab ? tab : FirstTab, FALSE);
6470
addDownloadList(pid_t pid, char *url, char *save, char *lock, clen_t size)
6474
d = New(DownloadList);
6477
if (save[0] != '/' && save[0] != '~')
6478
save = Strnew_m_charp(CurrentDir, "/", save, NULL)->ptr;
6479
d->save = expandPath(save);
6492
add_download_list = TRUE;
6496
checkDownloadList(void)
6503
for (d = FirstDL; d != NULL; d = d->next) {
6504
if (d->running && !lstat(d->lock, &st))
6511
convert_size3(clen_t size)
6519
tmp = Sprintf(size ? ",%.3d%s" : "%d%s", n, tmp->ptr);
6525
DownloadListBuffer(void)
6531
int duration, rate, eta;
6537
/* FIXME: gettextize? */
6538
src = Strnew_charp("<html><head><title>" DOWNLOAD_LIST_TITLE
6539
"</title></head>\n<body><h1 align=center>"
6540
DOWNLOAD_LIST_TITLE "</h1>\n"
6541
"<form method=internal action=download><hr>\n");
6542
for (d = LastDL; d != NULL; d = d->prev) {
6543
if (lstat(d->lock, &st))
6545
Strcat_charp(src, "<pre>\n");
6546
Strcat(src, Sprintf("%s\n --> %s\n ", html_quote(d->url),
6547
html_quote(conv_from_system(d->save))));
6548
duration = cur_time - d->time;
6549
if (!stat(d->save, &st)) {
6554
duration = st.st_mtime - d->time;
6560
int i, l = COLS - 6;
6562
i = 1.0 * l * size / d->size;
6567
Strcat_char(src, '#');
6569
Strcat_char(src, '_');
6570
Strcat_char(src, '\n');
6572
if ((d->running || d->err) && size < d->size)
6573
Strcat(src, Sprintf(" %s / %s bytes (%d%%)",
6574
convert_size3(size), convert_size3(d->size),
6575
(int)(100.0 * size / d->size)));
6577
Strcat(src, Sprintf(" %s bytes loaded", convert_size3(size)));
6579
rate = size / duration;
6580
Strcat(src, Sprintf(" %02d:%02d:%02d rate %s/sec",
6581
duration / (60 * 60), (duration / 60) % 60,
6582
duration % 60, convert_size(rate, 1)));
6583
if (d->running && size < d->size && rate) {
6584
eta = (d->size - size) / rate;
6585
Strcat(src, Sprintf(" eta %02d:%02d:%02d", eta / (60 * 60),
6586
(eta / 60) % 60, eta % 60));
6589
Strcat_char(src, '\n');
6591
Strcat(src, Sprintf("<input type=submit name=ok%d value=OK>",
6594
case 0: if (size < d->size)
6595
Strcat_charp(src, " Download ended but probably not complete");
6597
Strcat_charp(src, " Download complete");
6599
case 1: Strcat_charp(src, " Error: could not open destination file");
6601
case 2: Strcat_charp(src, " Error: could not write to file (disk full)");
6603
default: Strcat_charp(src, " Error: unknown reason");
6607
Strcat(src, Sprintf("<input type=submit name=stop%d value=STOP>",
6609
Strcat_charp(src, "\n</pre><hr>\n");
6611
Strcat_charp(src, "</form></body></html>");
6612
return loadHTMLString(src);
6616
download_action(struct parsed_tagarg *arg)
6621
for (; arg; arg = arg->next) {
6622
if (!strncmp(arg->arg, "stop", 4)) {
6623
pid = (pid_t) atoi(&arg->arg[4]);
6624
#ifndef __MINGW32_VERSION
6628
else if (!strncmp(arg->arg, "ok", 2))
6629
pid = (pid_t) atoi(&arg->arg[2]);
6632
for (d = FirstDL; d; d = d->next) {
6633
if (d->pid == pid) {
6636
d->prev->next = d->next;
6640
d->next->prev = d->prev;
6657
for (d = FirstDL; d != NULL; d = d->next) {
6660
#ifndef __MINGW32_VERSION
6661
kill(d->pid, SIGKILL);
6667
/* download panel */
6668
DEFUN(ldDL, DOWNLOAD_LIST, "Display download list panel")
6671
int replace = FALSE, new_tab = FALSE;
6676
if (Currentbuf->bufferprop & BP_INTERNAL &&
6677
!strcmp(Currentbuf->buffername, DOWNLOAD_LIST_TITLE))
6681
if (Currentbuf == Firstbuf && Currentbuf->nextBuffer == NULL) {
6683
deleteTab(CurrentTab);
6686
delBuffer(Currentbuf);
6687
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6692
reload = checkDownloadList();
6694
buf = DownloadListBuffer();
6696
displayBuffer(Currentbuf, B_NORMAL);
6699
buf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
6701
COPY_BUFROOT(buf, Currentbuf);
6702
restorePosition(buf, Currentbuf);
6704
if (!replace && open_tab_dl_list) {
6709
if (replace || new_tab)
6713
Currentbuf->event = setAlarmEvent(Currentbuf->event, 1, AL_IMPLICIT,
6714
FUNCNAME_reload, NULL);
6716
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6720
save_buffer_position(Buffer *buf)
6722
BufferPos *b = buf->undo;
6724
if (!buf->firstLine)
6726
if (b && b->top_linenumber == TOP_LINENUMBER(buf) &&
6727
b->cur_linenumber == CUR_LINENUMBER(buf) &&
6728
b->currentColumn == buf->currentColumn && b->pos == buf->pos)
6731
b->top_linenumber = TOP_LINENUMBER(buf);
6732
b->cur_linenumber = CUR_LINENUMBER(buf);
6733
b->currentColumn = buf->currentColumn;
6735
b->bpos = buf->currentLine ? buf->currentLine->bpos : 0;
6737
b->prev = buf->undo;
6739
buf->undo->next = b;
6744
resetPos(BufferPos * b)
6749
top.linenumber = b->top_linenumber;
6750
cur.linenumber = b->cur_linenumber;
6753
buf.currentLine = &cur;
6755
buf.currentColumn = b->currentColumn;
6756
restorePosition(Currentbuf, &buf);
6757
Currentbuf->undo = b;
6758
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6761
DEFUN(undoPos, UNDO, "Cancel the last cursor movement")
6763
BufferPos *b = Currentbuf->undo;
6766
if (!Currentbuf->firstLine)
6770
for (i = 0; i < PREC_NUM && b->prev; i++, b = b->prev) ;
6774
DEFUN(redoPos, REDO, "Cancel the last undo")
6776
BufferPos *b = Currentbuf->undo;
6779
if (!Currentbuf->firstLine)
6783
for (i = 0; i < PREC_NUM && b->next; i++, b = b->next) ;