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
fprintf(f, " -e EUC-JP\n");
204
fprintf(f, " -s Shift_JIS\n");
205
fprintf(f, " -j JIS\n");
207
fprintf(f, " -B load bookmark\n");
208
fprintf(f, " -bookmark file specify bookmark file\n");
209
fprintf(f, " -T type specify content-type\n");
210
fprintf(f, " -m internet message mode\n");
211
fprintf(f, " -v visual startup mode\n");
213
fprintf(f, " -M monochrome display\n");
214
#endif /* USE_COLOR */
216
" -N open URL of command line on each new tab\n");
217
fprintf(f, " -F automatically render frame\n");
219
" -cols width specify column width (used with -dump)\n");
221
" -ppc count specify the number of pixels per character (4.0...32.0)\n");
224
" -ppl count specify the number of pixels per line (4.0...64.0)\n");
226
fprintf(f, " -dump dump formatted page into stdout\n");
228
" -dump_head dump response of HEAD request into stdout\n");
229
fprintf(f, " -dump_source dump page source into stdout\n");
230
fprintf(f, " -dump_both dump HEAD and source into stdout\n");
232
" -dump_extra dump HEAD, source, and extra information into stdout\n");
233
fprintf(f, " -post file use POST method with file content\n");
234
fprintf(f, " -header string insert string as a header\n");
235
fprintf(f, " +<num> goto <num> line\n");
236
fprintf(f, " -num show line number\n");
237
fprintf(f, " -no-proxy don't use proxy\n");
239
fprintf(f, " -4 IPv4 only (-o dns_order=4)\n");
240
fprintf(f, " -6 IPv6 only (-o dns_order=6)\n");
243
fprintf(f, " -no-mouse don't use mouse\n");
244
#endif /* USE_MOUSE */
247
" -cookie use cookie (-no-cookie: don't use cookie)\n");
248
#endif /* USE_COOKIE */
249
fprintf(f, " -graph use DEC special graphics for border of table and menu\n");
250
fprintf(f, " -no-graph use ACII character for border of table and menu\n");
251
fprintf(f, " -S squeeze multiple blank lines\n");
252
fprintf(f, " -W toggle wrap search mode\n");
253
fprintf(f, " -X don't use termcap init/deinit\n");
255
" -title[=TERM] set buffer name to terminal title string\n");
256
fprintf(f, " -o opt=value assign value to config option\n");
257
fprintf(f, " -show-option print all config options\n");
258
fprintf(f, " -config file specify config file\n");
259
fprintf(f, " -help print this usage message\n");
260
fprintf(f, " -version print w3m version\n");
261
fprintf(f, " -reqlog write request logfile\n");
262
fprintf(f, " -debug DO NOT USE\n");
270
static char *getCodePage(void);
274
static GC_warn_proc orig_GC_warn_proc = NULL;
275
#define GC_WARN_KEEP_MAX (20)
278
wrap_GC_warn_proc(char *msg, GC_word arg)
285
} msg_ring[GC_WARN_KEEP_MAX];
292
j = (i + n) % (sizeof(msg_ring) / sizeof(msg_ring[0]));
293
msg_ring[j].msg = msg;
294
msg_ring[j].arg = arg;
296
if (n < sizeof(msg_ring) / sizeof(msg_ring[0]))
304
for (; n > 0; --n, ++i) {
305
i %= sizeof(msg_ring) / sizeof(msg_ring[0]);
307
printf(msg_ring[i].msg, (unsigned long)msg_ring[i].arg);
308
sleep_till_anykey(1, 1);
314
else if (orig_GC_warn_proc)
315
orig_GC_warn_proc(msg, arg);
317
fprintf(stderr, msg, (unsigned long)arg);
328
while ((pid = waitpid(-1, &p_stat, WNOHANG)) > 0)
330
while ((pid = wait3(&p_stat, WNOHANG, NULL)) > 0)
332
if ((pid = wait(&p_stat)) > 0)
337
if (WIFEXITED(p_stat)) {
338
for (d = FirstDL; d != NULL; d = d->next) {
340
d->err = WEXITSTATUS(p_stat);
346
mySignal(SIGCHLD, sig_chld);
352
make_optional_header_string(char *s)
357
if (strchr(s, '\n') || strchr(s, '\r'))
359
for (p = s; *p && *p != ':'; p++) ;
360
if (*p != ':' || p == s)
362
hs = Strnew_size(strlen(s) + 3);
363
Strcopy_charp_n(hs, s, p - s);
364
if (!Strcasecmp_charp(hs, "content-type"))
365
override_content_type = TRUE;
366
Strcat_charp(hs, ": ");
367
if (*(++p)) { /* not null header */
368
SKIP_BLANKS(p); /* skip white spaces */
371
Strcat_charp(hs, "\r\n");
376
main(int argc, char **argv, char **envp)
378
Buffer *newbuf = NULL;
382
char *line_str = NULL;
386
int load_bookmark = FALSE;
387
int visual_start = FALSE;
388
int open_new_tab = FALSE;
389
char search_header = FALSE;
390
char *default_type = NULL;
391
char *post_file = NULL;
395
wc_uint8 auto_detect;
401
#if defined(ENABLE_NLS) || (defined(USE_M17N) && defined(HAVE_LANGINFO_CODESET))
402
setlocale(LC_ALL, "");
405
bindtextdomain(PACKAGE, LOCALEDIR);
409
#ifndef HAVE_SYS_ERRLIST
410
prepare_sys_errlist();
411
#endif /* not HAVE_SYS_ERRLIST */
413
NO_proxy_domains = newTextList();
414
fileToDelete = newTextList();
416
load_argv = New_N(char *, argc - 1);
419
CurrentDir = currentdir();
420
CurrentPid = (int)getpid();
424
/* argument search 1 */
425
for (i = 1; i < argc; i++) {
426
if (*argv[i] == '-') {
427
if (!strcmp("-config", argv[i])) {
431
config_file = argv[i];
434
else if (!strcmp("-h", argv[i]) || !strcmp("-help", argv[i]))
436
else if (!strcmp("-V", argv[i]) || !strcmp("-version", argv[i])) {
444
if (non_null(Locale = getenv("LC_ALL")) ||
445
non_null(Locale = getenv("LC_CTYPE")) ||
446
non_null(Locale = getenv("LANG"))) {
447
DisplayCharset = wc_guess_locale_charset(Locale, DisplayCharset);
448
DocumentCharset = wc_guess_locale_charset(Locale, DocumentCharset);
449
SystemCharset = wc_guess_locale_charset(Locale, SystemCharset);
452
CodePage = wc_guess_charset(getCodePage(), 0);
454
DisplayCharset = DocumentCharset = SystemCharset = CodePage;
458
/* initializations */
461
LoadHist = newHist();
462
SaveHist = newHist();
463
ShellHist = newHist();
464
TextHist = newHist();
468
if (FollowLocale && Locale) {
469
DisplayCharset = wc_guess_locale_charset(Locale, DisplayCharset);
470
SystemCharset = wc_guess_locale_charset(Locale, SystemCharset);
472
auto_detect = WcOption.auto_detect;
473
BookmarkCharset = DocumentCharset;
476
if (!non_null(HTTP_proxy) &&
477
((p = getenv("HTTP_PROXY")) ||
478
(p = getenv("http_proxy")) || (p = getenv("HTTP_proxy"))))
481
if (!non_null(HTTPS_proxy) &&
482
((p = getenv("HTTPS_PROXY")) ||
483
(p = getenv("https_proxy")) || (p = getenv("HTTPS_proxy"))))
485
if (HTTPS_proxy == NULL && non_null(HTTP_proxy))
486
HTTPS_proxy = HTTP_proxy;
489
if (!non_null(GOPHER_proxy) &&
490
((p = getenv("GOPHER_PROXY")) ||
491
(p = getenv("gopher_proxy")) || (p = getenv("GOPHER_proxy"))))
493
#endif /* USE_GOPHER */
494
if (!non_null(FTP_proxy) &&
495
((p = getenv("FTP_PROXY")) ||
496
(p = getenv("ftp_proxy")) || (p = getenv("FTP_proxy"))))
498
if (!non_null(NO_proxy) &&
499
((p = getenv("NO_PROXY")) ||
500
(p = getenv("no_proxy")) || (p = getenv("NO_proxy"))))
503
if (!non_null(NNTP_server) && (p = getenv("NNTPSERVER")) != NULL)
505
if (!non_null(NNTP_mode) && (p = getenv("NNTPMODE")) != NULL)
509
if (!non_null(Editor) && (p = getenv("EDITOR")) != NULL)
511
if (!non_null(Mailer) && (p = getenv("MAILER")) != NULL)
514
/* argument search 2 */
517
if (*argv[i] == '-') {
518
if (!strcmp("-t", argv[i])) {
521
if (atoi(argv[i]) > 0)
522
Tabstop = atoi(argv[i]);
524
else if (!strcmp("-r", argv[i]))
526
else if (!strcmp("-l", argv[i])) {
529
if (atoi(argv[i]) > 0)
530
PagerMax = atoi(argv[i]);
533
else if (!strcmp("-s", argv[i]))
534
DisplayCharset = WC_CES_SHIFT_JIS;
535
else if (!strcmp("-j", argv[i]))
536
DisplayCharset = WC_CES_ISO_2022_JP;
537
else if (!strcmp("-e", argv[i]))
538
DisplayCharset = WC_CES_EUC_JP;
539
else if (!strncmp("-I", argv[i], 2)) {
540
if (argv[i][2] != '\0')
547
DocumentCharset = wc_guess_charset_short(p, DocumentCharset);
548
WcOption.auto_detect = WC_OPT_DETECT_OFF;
549
UseContentCharset = FALSE;
551
else if (!strncmp("-O", argv[i], 2)) {
552
if (argv[i][2] != '\0')
559
DisplayCharset = wc_guess_charset_short(p, DisplayCharset);
562
else if (!strcmp("-graph", argv[i]))
563
UseGraphicChar = GRAPHIC_CHAR_DEC;
564
else if (!strcmp("-no-graph", argv[i]))
565
UseGraphicChar = GRAPHIC_CHAR_ASCII;
566
else if (!strcmp("-T", argv[i])) {
569
DefaultType = default_type = argv[i];
571
else if (!strcmp("-m", argv[i]))
572
SearchHeader = search_header = TRUE;
573
else if (!strcmp("-v", argv[i]))
575
else if (!strcmp("-N", argv[i]))
578
else if (!strcmp("-M", argv[i]))
580
#endif /* USE_COLOR */
581
else if (!strcmp("-B", argv[i]))
582
load_bookmark = TRUE;
583
else if (!strcmp("-bookmark", argv[i])) {
586
BookmarkFile = argv[i];
587
if (BookmarkFile[0] != '~' && BookmarkFile[0] != '/') {
588
Str tmp = Strnew_charp(CurrentDir);
589
if (Strlastchar(tmp) != '/')
590
Strcat_char(tmp, '/');
591
Strcat_charp(tmp, BookmarkFile);
592
BookmarkFile = cleanupName(tmp->ptr);
595
else if (!strcmp("-F", argv[i]))
597
else if (!strcmp("-W", argv[i])) {
603
else if (!strcmp("-dump", argv[i]))
604
w3m_dump = DUMP_BUFFER;
605
else if (!strcmp("-dump_source", argv[i]))
606
w3m_dump = DUMP_SOURCE;
607
else if (!strcmp("-dump_head", argv[i]))
608
w3m_dump = DUMP_HEAD;
609
else if (!strcmp("-dump_both", argv[i]))
610
w3m_dump = (DUMP_HEAD | DUMP_SOURCE);
611
else if (!strcmp("-dump_extra", argv[i]))
612
w3m_dump = (DUMP_HEAD | DUMP_SOURCE | DUMP_EXTRA);
613
else if (!strcmp("-halfdump", argv[i]))
614
w3m_dump = DUMP_HALFDUMP;
615
else if (!strcmp("-halfload", argv[i])) {
618
DefaultType = default_type = "text/html";
620
else if (!strcmp("-backend", argv[i])) {
623
else if (!strcmp("-backend_batch", argv[i])) {
627
if (!backend_batch_commands)
628
backend_batch_commands = newTextList();
629
pushText(backend_batch_commands, argv[i]);
631
else if (!strcmp("-cols", argv[i])) {
634
COLS = atoi(argv[i]);
635
if (COLS > MAXIMUM_COLS) {
639
else if (!strcmp("-ppc", argv[i])) {
644
if (ppc >= MINIMUM_PIXEL_PER_CHAR &&
645
ppc <= MAXIMUM_PIXEL_PER_CHAR) {
646
pixel_per_char = ppc;
647
set_pixel_per_char = TRUE;
651
else if (!strcmp("-ppl", argv[i])) {
656
if (ppc >= MINIMUM_PIXEL_PER_CHAR &&
657
ppc <= MAXIMUM_PIXEL_PER_CHAR * 2) {
658
pixel_per_line = ppc;
659
set_pixel_per_line = TRUE;
663
else if (!strcmp("-num", argv[i]))
665
else if (!strcmp("-no-proxy", argv[i]))
668
else if (!strcmp("-4", argv[i]) || !strcmp("-6", argv[i]))
669
set_param_option(Sprintf("dns_order=%c", argv[i][1])->ptr);
671
else if (!strcmp("-post", argv[i])) {
676
else if (!strcmp("-header", argv[i])) {
680
if ((hs = make_optional_header_string(argv[i])) != NULL) {
681
if (header_string == NULL)
684
Strcat(header_string, hs);
692
else if (!strcmp("-no-mouse", argv[i])) {
695
#endif /* USE_MOUSE */
697
else if (!strcmp("-no-cookie", argv[i])) {
699
accept_cookie = FALSE;
701
else if (!strcmp("-cookie", argv[i])) {
703
accept_cookie = TRUE;
705
#endif /* USE_COOKIE */
706
else if (!strcmp("-S", argv[i]))
707
squeezeBlankLine = TRUE;
708
else if (!strcmp("-X", argv[i]))
709
Do_not_use_ti_te = TRUE;
710
else if (!strcmp("-title", argv[i]))
711
displayTitleTerm = getenv("TERM");
712
else if (!strncmp("-title=", argv[i], 7))
713
displayTitleTerm = argv[i] + 7;
714
else if (!strcmp("-o", argv[i]) ||
715
!strcmp("-show-option", argv[i])) {
716
if (!strcmp("-show-option", argv[i]) || ++i >= argc ||
717
!strcmp(argv[i], "?")) {
721
if (!set_param_option(argv[i])) {
722
/* option set failed */
723
/* FIXME: gettextize? */
724
fprintf(stderr, "%s: bad option\n", argv[i]);
729
else if (!strcmp("-dummy", argv[i])) {
732
else if (!strcmp("-debug", argv[i])) {
735
else if (!strcmp("-reqlog",argv[i])) {
736
w3m_reqlog=rcFile("request.log");
742
else if (*argv[i] == '+') {
743
line_str = argv[i] + 1;
746
load_argv[load_argc++] = argv[i];
757
#ifdef __MINGW32_VERSION
762
wVerReq = MAKEWORD(1, 1);
764
err = WSAStartup(wVerReq, &WSAData);
767
fprintf(stderr, "Can't find winsock\n");
779
if (BookmarkFile == NULL)
780
BookmarkFile = rcFile(BOOKMARK);
782
if (!isatty(1) && !w3m_dump) {
783
/* redirected output */
784
w3m_dump = DUMP_BUFFER;
791
#ifdef USE_BINMODE_STREAM
792
setmode(fileno(stdout), O_BINARY);
794
if (!w3m_dump && !w3m_backend) {
797
mySignal(SIGWINCH, resize_hook);
798
#else /* not SIGWINCH */
801
#endif /* not SIGWINCH */
804
else if (w3m_halfdump && displayImage)
811
#endif /* USE_COOKIE */
814
loadHistory(URLHist);
815
#endif /* not USE_HISTORY */
818
wtf_init(DocumentCharset, DisplayCharset);
820
* WcOption.pre_conv = WC_TRUE;
828
mySignal(SIGINT, SIG_IGN);
830
mySignal(SIGCHLD, sig_chld);
833
mySignal(SIGPIPE, SigPipe);
836
orig_GC_warn_proc = GC_set_warn_proc(wrap_GC_warn_proc);
838
if (load_argc == 0) {
839
/* no URL specified */
841
redin = newFileStream(fdopen(dup(0), "rb"), (void (*)())pclose);
842
newbuf = openGeneralPagerBuffer(redin);
845
else if (load_bookmark) {
846
newbuf = loadGeneralFile(BookmarkFile, NULL, NO_REFERER, 0, NULL);
848
Strcat_charp(err_msg, "w3m: Can't load bookmark.\n");
850
else if (visual_start) {
851
/* FIXME: gettextize? */
855
("<title>W3M startup page</title><center><b>Welcome to ");
856
Strcat_charp(s_page, "<a href='http://w3m.sourceforge.net/'>");
857
Strcat_m_charp(s_page,
858
"w3m</a>!<p><p>This is w3m version ",
860
"<br>Written by <a href='mailto:aito@fw.ipsj.or.jp'>Akinori Ito</a>",
862
newbuf = loadHTMLString(s_page);
864
Strcat_charp(err_msg, "w3m: Can't load string.\n");
865
else if (newbuf != NO_BUFFER)
866
newbuf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
868
else if ((p = getenv("HTTP_HOME")) != NULL ||
869
(p = getenv("WWW_HOME")) != NULL) {
870
newbuf = loadGeneralFile(p, NULL, NO_REFERER, 0, NULL);
872
Strcat(err_msg, Sprintf("w3m: Can't load %s.\n", p));
873
else if (newbuf != NO_BUFFER)
874
pushHashHist(URLHist, parsedURL2Str(&newbuf->currentURL)->ptr);
881
if (newbuf == NULL) {
885
fprintf(stderr, "%s", err_msg->ptr);
893
for (; i < load_argc; i++) {
895
SearchHeader = search_header;
896
DefaultType = default_type;
897
if (w3m_dump == DUMP_HEAD) {
898
request = New(FormList);
899
request->method = FORM_METHOD_HEAD;
901
loadGeneralFile(load_argv[i], NULL, NO_REFERER, 0,
905
if (post_file && i == 0) {
908
if (!strcmp(post_file, "-"))
911
fp = fopen(post_file, "r");
913
/* FIXME: gettextize? */
915
Sprintf("w3m: Can't open %s.\n", post_file));
918
body = Strfgetall(fp);
922
newFormList(NULL, "post", NULL, NULL, NULL, NULL,
924
request->body = body->ptr;
925
request->boundary = NULL;
926
request->length = body->length;
932
loadGeneralFile(load_argv[i], NULL, NO_REFERER, 0,
935
if (newbuf == NULL) {
936
/* FIXME: gettextize? */
938
Sprintf("w3m: Can't load %s.\n", load_argv[i]));
941
else if (newbuf == NO_BUFFER)
943
switch (newbuf->real_scheme) {
948
unshiftHist(LoadHist, conv_from_system(load_argv[i]));
950
pushHashHist(URLHist, parsedURL2Str(&newbuf->currentURL)->ptr);
954
else if (newbuf == NO_BUFFER)
956
if (newbuf->pagerSource ||
957
(newbuf->real_scheme == SCM_LOCAL && newbuf->header_source &&
958
newbuf->currentURL.file && strcmp(newbuf->currentURL.file, "-")))
959
newbuf->search_header = search_header;
960
if (CurrentTab == NULL) {
961
FirstTab = LastTab = CurrentTab = newTab();
963
Firstbuf = Currentbuf = newbuf;
965
else if (open_new_tab) {
967
Currentbuf->nextBuffer = newbuf;
968
delBuffer(Currentbuf);
971
Currentbuf->nextBuffer = newbuf;
974
if (!w3m_dump || w3m_dump == DUMP_BUFFER) {
975
if (Currentbuf->frameset != NULL && RenderFrame)
989
fprintf(stderr, "%s", err_msg->ptr);
992
#endif /* USE_COOKIE */
996
if (add_download_list) {
997
add_download_list = FALSE;
998
CurrentTab = LastTab;
1000
FirstTab = LastTab = CurrentTab = newTab();
1003
if (!Firstbuf || Firstbuf == NO_BUFFER) {
1004
Firstbuf = Currentbuf = newBuffer(INIT_BUFFER_WIDTH);
1005
Currentbuf->bufferprop = BP_INTERNAL | BP_NO_URL;
1006
Currentbuf->buffername = DOWNLOAD_LIST_TITLE;
1009
Currentbuf = Firstbuf;
1013
CurrentTab = FirstTab;
1014
if (!FirstTab || !Firstbuf || Firstbuf == NO_BUFFER) {
1015
if (newbuf == NO_BUFFER) {
1017
/* FIXME: gettextize? */
1018
inputChar("Hit any key to quit w3m:");
1022
if (err_msg->length)
1023
fprintf(stderr, "%s", err_msg->ptr);
1024
if (newbuf == NO_BUFFER) {
1027
#endif /* USE_COOKIE */
1028
if (!err_msg->length)
1033
if (err_msg->length)
1034
disp_message_nsec(err_msg->ptr, FALSE, 1, TRUE, FALSE);
1036
SearchHeader = FALSE;
1039
UseContentCharset = TRUE;
1040
WcOption.auto_detect = auto_detect;
1043
Currentbuf = Firstbuf;
1044
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1049
if (add_download_list) {
1050
add_download_list = FALSE;
1053
if (Currentbuf->submit) {
1054
Anchor *a = Currentbuf->submit;
1055
Currentbuf->submit = NULL;
1056
gotoLine(Currentbuf, a->start.line);
1057
Currentbuf->pos = a->start.pos;
1061
/* event processing */
1064
CurrentKeyData = NULL;
1065
CurrentCmdData = (char *)CurrentEvent->data;
1066
w3mFuncList[CurrentEvent->cmd].func();
1067
CurrentCmdData = NULL;
1068
CurrentEvent = CurrentEvent->next;
1071
/* get keypress event */
1073
if (Currentbuf->event) {
1074
if (Currentbuf->event->status != AL_UNSET) {
1075
CurrentAlarm = Currentbuf->event;
1076
if (CurrentAlarm->sec == 0) { /* refresh (0sec) */
1077
Currentbuf->event = NULL;
1079
CurrentKeyData = NULL;
1080
CurrentCmdData = (char *)CurrentAlarm->data;
1081
w3mFuncList[CurrentAlarm->cmd].func();
1082
CurrentCmdData = NULL;
1087
Currentbuf->event = NULL;
1089
if (!Currentbuf->event)
1090
CurrentAlarm = &DefaultAlarm;
1093
mouse_action.in_action = FALSE;
1096
#endif /* USE_MOUSE */
1098
if (CurrentAlarm->sec > 0) {
1099
mySignal(SIGALRM, SigAlarm);
1100
alarm(CurrentAlarm->sec);
1104
mySignal(SIGWINCH, resize_hook);
1107
if (activeImage && displayImage && Currentbuf->img &&
1108
!Currentbuf->image_loaded) {
1111
if (need_resize_screen)
1114
loadImage(Currentbuf, IMG_FLAG_NEXT);
1115
} while (sleep_till_anykey(1, 0) <= 0);
1124
if (need_resize_screen)
1126
} while (sleep_till_anykey(1, 0) <= 0);
1131
if (CurrentAlarm->sec > 0) {
1138
#endif /* USE_MOUSE */
1139
if (IS_ASCII(c)) { /* Ascii */
1140
if (('0' <= c) && (c <= '9') &&
1141
(prec_num || (GlobalKeymap[c] == FUNCNAME_nulcmd))) {
1142
prec_num = prec_num * 10 + (int)(c - '0');
1143
if (prec_num > PREC_LIMIT)
1144
prec_num = PREC_LIMIT;
1147
set_buffer_environ(Currentbuf);
1148
save_buffer_position(Currentbuf);
1149
keyPressEventProc((int)c);
1153
prev_key = CurrentKey;
1155
CurrentKeyData = NULL;
1160
keyPressEventProc(int c)
1163
w3mFuncList[(int)GlobalKeymap[c]].func();
1167
pushEvent(int cmd, void *data)
1176
LastEvent->next = event;
1178
CurrentEvent = event;
1183
dump_source(Buffer *buf)
1187
if (buf->sourcefile == NULL)
1189
f = fopen(buf->sourcefile, "r");
1192
while (c = fgetc(f), !feof(f)) {
1199
dump_head(Buffer *buf)
1203
if (buf->document_header == NULL) {
1204
if (w3m_dump & DUMP_EXTRA)
1208
for (ti = buf->document_header->first; ti; ti = ti->next) {
1211
wc_conv_strict(ti->ptr, InnerCharset,
1212
buf->document_charset)->ptr);
1214
printf("%s", ti->ptr);
1221
dump_extra(Buffer *buf)
1223
printf("W3m-current-url: %s\n", parsedURL2Str(&buf->currentURL)->ptr);
1225
printf("W3m-base-url: %s\n", parsedURL2Str(buf->baseURL)->ptr);
1227
printf("W3m-document-charset: %s\n",
1228
wc_ces_to_charset(buf->document_charset));
1231
if (buf->ssl_certificate) {
1234
for (p = buf->ssl_certificate; *p; p++) {
1235
Strcat_char(tmp, *p);
1237
for (; *(p + 1) == '\n'; p++) ;
1239
Strcat_char(tmp, '\t');
1242
if (Strlastchar(tmp) != '\n')
1243
Strcat_char(tmp, '\n');
1244
printf("W3m-ssl-certificate: %s", tmp->ptr);
1250
do_dump(Buffer *buf)
1252
MySignalHandler(*volatile prevtrap) (SIGNAL_ARG) = NULL;
1254
prevtrap = mySignal(SIGINT, intTrap);
1255
if (SETJMP(IntReturn) != 0) {
1256
mySignal(SIGINT, prevtrap);
1259
if (w3m_dump & DUMP_EXTRA)
1261
if (w3m_dump & DUMP_HEAD)
1263
if (w3m_dump & DUMP_SOURCE)
1265
if (w3m_dump == DUMP_BUFFER) {
1267
saveBuffer(buf, stdout, FALSE);
1268
if (displayLinkNumber && buf->href) {
1269
printf("\nReferences:\n\n");
1270
for (i = 0; i < buf->href->nanchor; i++) {
1272
static Str s = NULL;
1273
if (buf->href->anchors[i].slave)
1275
parseURL2(buf->href->anchors[i].url, &pu, baseURL(buf));
1276
s = parsedURL2Str(&pu);
1278
s = Strnew_charp(url_unquote_conv
1279
(s->ptr, Currentbuf->document_charset));
1280
printf("[%d] %s\n", buf->href->anchors[i].hseq + 1, s->ptr);
1284
mySignal(SIGINT, prevtrap);
1287
DEFUN(nulcmd, NOTHING NULL @@@, "Do nothing")
1292
DEFUN(pcmap, PCMAP, "pcmap")
1294
w3mFuncList[(int)PcKeymap[(int)getch()]].func();
1296
#else /* not __EMX__ */
1304
escKeyProc(int c, int esc, unsigned char *map)
1306
if (CurrentKey >= 0 && CurrentKey & K_MULTI) {
1307
unsigned char **mmap;
1308
mmap = (unsigned char **)getKeyData(MULTI_KEY(CurrentKey));
1325
esc |= (CurrentKey & ~0xFFFF);
1327
CurrentKey = esc | c;
1328
w3mFuncList[(int)map[c]].func();
1331
DEFUN(escmap, ESCMAP, "ESC map")
1336
escKeyProc((int)c, K_ESC, EscKeymap);
1339
DEFUN(escbmap, ESCBMAP, "ESC [ map")
1348
escKeyProc((int)c, K_ESCB, EscBKeymap);
1355
d = (int)c - (int)'0';
1358
d = d * 10 + (int)c - (int)'0';
1362
escKeyProc((int)d, K_ESCD, EscDKeymap);
1365
DEFUN(multimap, MULTIMAP, "multimap")
1370
CurrentKey = K_MULTI | (CurrentKey << 16) | c;
1371
escKeyProc((int)c, 0, NULL);
1376
tmpClearBuffer(Buffer *buf)
1378
if (buf->pagerSource == NULL && writeBufferCache(buf) == 0) {
1379
buf->firstLine = NULL;
1380
buf->topLine = NULL;
1381
buf->currentLine = NULL;
1382
buf->lastLine = NULL;
1386
static Str currentURL(void);
1396
if ((fp = fopen(rcFile("bufinfo"), "w")) == NULL) {
1399
fprintf(fp, "%s\n", currentURL()->ptr);
1405
pushBuffer(Buffer *buf)
1410
deleteImage(Currentbuf);
1413
tmpClearBuffer(Currentbuf);
1414
if (Firstbuf == Currentbuf) {
1415
buf->nextBuffer = Firstbuf;
1416
Firstbuf = Currentbuf = buf;
1418
else if ((b = prevBuffer(Firstbuf, Currentbuf)) != NULL) {
1419
b->nextBuffer = buf;
1420
buf->nextBuffer = Currentbuf;
1430
delBuffer(Buffer *buf)
1434
if (Currentbuf == buf)
1435
Currentbuf = buf->nextBuffer;
1436
Firstbuf = deleteBuffer(Firstbuf, buf);
1438
Currentbuf = Firstbuf;
1442
repBuffer(Buffer *oldbuf, Buffer *buf)
1444
Firstbuf = replaceBuffer(Firstbuf, oldbuf, buf);
1451
{ /* Interrupt catcher */
1452
LONGJMP(IntReturn, 0);
1457
static MySignalHandler
1458
resize_hook(SIGNAL_ARG)
1460
need_resize_screen = TRUE;
1461
mySignal(SIGWINCH, resize_hook);
1468
need_resize_screen = FALSE;
1472
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1474
#endif /* SIGWINCH */
1477
static MySignalHandler
1483
mySignal(SIGPIPE, SigPipe);
1489
* Command functions: These functions are called with a keystroke.
1493
nscroll(int n, int mode)
1495
Buffer *buf = Currentbuf;
1496
Line *top = buf->topLine, *cur = buf->currentLine;
1497
int lnum, tlnum, llnum, diff_n;
1499
if (buf->firstLine == NULL)
1501
lnum = cur->linenumber;
1502
buf->topLine = lineSkip(buf, top, n, FALSE);
1503
if (buf->topLine == top) {
1505
if (lnum < buf->topLine->linenumber)
1506
lnum = buf->topLine->linenumber;
1507
else if (lnum > buf->lastLine->linenumber)
1508
lnum = buf->lastLine->linenumber;
1511
tlnum = buf->topLine->linenumber;
1512
llnum = buf->topLine->linenumber + buf->LINES - 1;
1513
if (nextpage_topline)
1516
diff_n = n - (tlnum - top->linenumber);
1518
lnum = tlnum + diff_n;
1520
lnum = llnum + diff_n;
1522
gotoLine(buf, lnum);
1525
if (buf->currentLine->bpos &&
1526
buf->currentLine->bwidth >= buf->currentColumn + buf->visualpos)
1529
while (buf->currentLine->next && buf->currentLine->next->bpos &&
1530
buf->currentLine->bwidth + buf->currentLine->width <
1531
buf->currentColumn + buf->visualpos)
1532
cursorDown0(buf, 1);
1536
if (buf->currentLine->bwidth + buf->currentLine->width <
1537
buf->currentColumn + buf->visualpos)
1540
while (buf->currentLine->prev && buf->currentLine->bpos &&
1541
buf->currentLine->bwidth >=
1542
buf->currentColumn + buf->visualpos)
1546
displayBuffer(buf, mode);
1549
/* Move page forward */
1550
DEFUN(pgFore, NEXT_PAGE, "Move to next page")
1553
nscroll(searchKeyNum() * (Currentbuf->LINES - 1), B_NORMAL);
1555
nscroll(prec_num ? searchKeyNum() : searchKeyNum()
1556
* (Currentbuf->LINES - 1), prec_num ? B_SCROLL : B_NORMAL);
1559
/* Move page backward */
1560
DEFUN(pgBack, PREV_PAGE, "Move to previous page")
1563
nscroll(-searchKeyNum() * (Currentbuf->LINES - 1), B_NORMAL);
1565
nscroll(-(prec_num ? searchKeyNum() : searchKeyNum()
1566
* (Currentbuf->LINES - 1)), prec_num ? B_SCROLL : B_NORMAL);
1570
DEFUN(lup1, UP, "Scroll up one line")
1572
nscroll(searchKeyNum(), B_SCROLL);
1576
DEFUN(ldown1, DOWN, "Scroll down one line")
1578
nscroll(-searchKeyNum(), B_SCROLL);
1581
/* move cursor position to the center of screen */
1582
DEFUN(ctrCsrV, CENTER_V, "Move to the center column")
1585
if (Currentbuf->firstLine == NULL)
1587
offsety = Currentbuf->LINES / 2 - Currentbuf->cursorY;
1590
Currentbuf->currentLine = lineSkip(Currentbuf,
1591
Currentbuf->currentLine, offsety,
1594
Currentbuf->topLine =
1595
lineSkip(Currentbuf, Currentbuf->topLine, -offsety, FALSE);
1596
arrangeLine(Currentbuf);
1597
displayBuffer(Currentbuf, B_NORMAL);
1601
DEFUN(ctrCsrH, CENTER_H, "Move to the center line")
1604
if (Currentbuf->firstLine == NULL)
1606
offsetx = Currentbuf->cursorX - Currentbuf->COLS / 2;
1608
columnSkip(Currentbuf, offsetx);
1609
arrangeCursor(Currentbuf);
1610
displayBuffer(Currentbuf, B_NORMAL);
1615
DEFUN(rdrwSc, REDRAW, "Redraw screen")
1618
arrangeCursor(Currentbuf);
1619
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1628
for (pos = 0; pos < l->size; pos++)
1629
l->propBuf[pos] &= ~PE_MARK;
1632
/* search by regular expression */
1634
srchcore(char *volatile str, int (*func) (Buffer *, char *))
1636
MySignalHandler(*prevtrap) ();
1637
volatile int i, result = SR_NOTFOUND;
1639
if (str != NULL && str != SearchString)
1641
if (SearchString == NULL || *SearchString == '\0')
1644
str = conv_search_string(SearchString, DisplayCharset);
1645
prevtrap = mySignal(SIGINT, intTrap);
1647
if (SETJMP(IntReturn) == 0) {
1648
for (i = 0; i < PREC_NUM; i++) {
1649
result = func(Currentbuf, str);
1650
if (i < PREC_NUM - 1 && result & SR_FOUND)
1651
clear_mark(Currentbuf->currentLine);
1654
mySignal(SIGINT, prevtrap);
1660
disp_srchresult(int result, char *prompt, char *str)
1664
if (result & SR_NOTFOUND)
1665
disp_message(Sprintf("Not found: %s", str)->ptr, TRUE);
1666
else if (result & SR_WRAPPED)
1667
disp_message(Sprintf("Search wrapped: %s", str)->ptr, TRUE);
1668
else if (show_srch_str)
1669
disp_message(Sprintf("%s%s", prompt, str)->ptr, TRUE);
1673
dispincsrch(int ch, Str buf, Lineprop *prop)
1676
static Line *currentLine;
1679
int do_next_search = FALSE;
1681
if (ch == 0 && buf == NULL) {
1682
SAVE_BUFPOSITION(&sbuf); /* search starting point */
1683
currentLine = sbuf.currentLine;
1691
searchRoutine = backwardSearch;
1692
do_next_search = TRUE;
1695
searchRoutine = forwardSearch;
1696
do_next_search = TRUE;
1701
migemo_active = -migemo_active;
1707
return ch; /* use InputKeymap */
1710
if (do_next_search) {
1712
if (searchRoutine == forwardSearch)
1713
Currentbuf->pos += 1;
1714
SAVE_BUFPOSITION(&sbuf);
1715
if (srchcore(str, searchRoutine) == SR_NOTFOUND
1716
&& searchRoutine == forwardSearch) {
1717
Currentbuf->pos -= 1;
1718
SAVE_BUFPOSITION(&sbuf);
1720
arrangeCursor(Currentbuf);
1721
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1722
clear_mark(Currentbuf->currentLine);
1726
return 020; /* _prev completion for C-s C-s */
1729
RESTORE_BUFPOSITION(&sbuf);
1730
arrangeCursor(Currentbuf);
1731
srchcore(str, searchRoutine);
1732
arrangeCursor(Currentbuf);
1733
currentLine = Currentbuf->currentLine;
1734
pos = Currentbuf->pos;
1736
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1737
clear_mark(Currentbuf->currentLine);
1740
while (*str++ != '\0') {
1741
if (migemo_active > 0)
1742
*prop++ |= PE_UNDER;
1744
*prop++ &= ~PE_UNDER;
1751
isrch(int (*func) (Buffer *, char *), char *prompt)
1755
SAVE_BUFPOSITION(&sbuf);
1756
dispincsrch(0, NULL, NULL); /* initialize incremental search state */
1758
searchRoutine = func;
1759
str = inputLineHistSearch(prompt, NULL, IN_STRING, TextHist, dispincsrch);
1761
RESTORE_BUFPOSITION(&sbuf);
1763
displayBuffer(Currentbuf, B_FORCE_REDRAW);
1767
srch(int (*func) (Buffer *, char *), char *prompt)
1774
str = searchKeyData();
1775
if (str == NULL || *str == '\0') {
1776
str = inputStrHist(prompt, NULL, TextHist);
1777
if (str != NULL && *str == '\0')
1780
displayBuffer(Currentbuf, B_NORMAL);
1785
pos = Currentbuf->pos;
1786
if (func == forwardSearch)
1787
Currentbuf->pos += 1;
1788
result = srchcore(str, func);
1789
if (result & SR_FOUND)
1790
clear_mark(Currentbuf->currentLine);
1792
Currentbuf->pos = pos;
1793
displayBuffer(Currentbuf, B_NORMAL);
1795
disp_srchresult(result, prompt, str);
1796
searchRoutine = func;
1799
/* Search regular expression forward */
1801
DEFUN(srchfor, SEARCH SEARCH_FORE WHEREIS, "Search forward")
1803
srch(forwardSearch, "Forward: ");
1806
DEFUN(isrchfor, ISEARCH, "Incremental search forward")
1808
isrch(forwardSearch, "I-search: ");
1811
/* Search regular expression backward */
1813
DEFUN(srchbak, SEARCH_BACK, "Search backward")
1815
srch(backwardSearch, "Backward: ");
1818
DEFUN(isrchbak, ISEARCH_BACK, "Incremental search backward")
1820
isrch(backwardSearch, "I-search backward: ");
1824
srch_nxtprv(int reverse)
1828
static int (*routine[2]) (Buffer *, char *) = {
1829
forwardSearch, backwardSearch
1833
if (searchRoutine == NULL) {
1834
/* FIXME: gettextize? */
1835
disp_message("No previous regular expression", TRUE);
1840
if (searchRoutine == backwardSearch)
1843
Currentbuf->pos += 1;
1844
result = srchcore(SearchString, routine[reverse]);
1845
if (result & SR_FOUND)
1846
clear_mark(Currentbuf->currentLine);
1847
displayBuffer(Currentbuf, B_NORMAL);
1848
disp_srchresult(result, (reverse ? "Backward: " : "Forward: "),
1852
/* Search next matching */
1853
DEFUN(srchnxt, SEARCH_NEXT, "Search next regexp")
1858
/* Search previous matching */
1859
DEFUN(srchprv, SEARCH_PREV, "Search previous regexp")
1865
shiftvisualpos(Buffer *buf, int shift)
1867
Line *l = buf->currentLine;
1868
buf->visualpos -= shift;
1869
if (buf->visualpos - l->bwidth >= buf->COLS)
1870
buf->visualpos = l->bwidth + buf->COLS - 1;
1871
else if (buf->visualpos - l->bwidth < 0)
1872
buf->visualpos = l->bwidth;
1874
if (buf->visualpos - l->bwidth == -shift && buf->cursorX == 0)
1875
buf->visualpos = l->bwidth;
1878
/* Shift screen left */
1879
DEFUN(shiftl, SHIFT_LEFT, "Shift screen left")
1883
if (Currentbuf->firstLine == NULL)
1885
column = Currentbuf->currentColumn;
1886
columnSkip(Currentbuf, searchKeyNum() * (-Currentbuf->COLS + 1) + 1);
1887
shiftvisualpos(Currentbuf, Currentbuf->currentColumn - column);
1888
displayBuffer(Currentbuf, B_NORMAL);
1891
/* Shift screen right */
1892
DEFUN(shiftr, SHIFT_RIGHT, "Shift screen right")
1896
if (Currentbuf->firstLine == NULL)
1898
column = Currentbuf->currentColumn;
1899
columnSkip(Currentbuf, searchKeyNum() * (Currentbuf->COLS - 1) - 1);
1900
shiftvisualpos(Currentbuf, Currentbuf->currentColumn - column);
1901
displayBuffer(Currentbuf, B_NORMAL);
1904
DEFUN(col1R, RIGHT, "Shift screen one column right")
1906
Buffer *buf = Currentbuf;
1907
Line *l = buf->currentLine;
1908
int j, column, n = searchKeyNum();
1912
for (j = 0; j < n; j++) {
1913
column = buf->currentColumn;
1914
columnSkip(Currentbuf, 1);
1915
if (column == buf->currentColumn)
1917
shiftvisualpos(Currentbuf, 1);
1919
displayBuffer(Currentbuf, B_NORMAL);
1922
DEFUN(col1L, LEFT, "Shift screen one column")
1924
Buffer *buf = Currentbuf;
1925
Line *l = buf->currentLine;
1926
int j, n = searchKeyNum();
1930
for (j = 0; j < n; j++) {
1931
if (buf->currentColumn == 0)
1933
columnSkip(Currentbuf, -1);
1934
shiftvisualpos(Currentbuf, -1);
1936
displayBuffer(Currentbuf, B_NORMAL);
1939
DEFUN(setEnv, SETENV, "Set environment variable")
1944
CurrentKeyData = NULL; /* not allowed in w3m-control: */
1945
env = searchKeyData();
1946
if (env == NULL || *env == '\0' || strchr(env, '=') == NULL) {
1947
if (env != NULL && *env != '\0')
1948
env = Sprintf("%s=", env)->ptr;
1949
env = inputStrHist("Set environ: ", env, TextHist);
1950
if (env == NULL || *env == '\0') {
1951
displayBuffer(Currentbuf, B_NORMAL);
1955
if ((value = strchr(env, '=')) != NULL && value > env) {
1956
var = allocStr(env, value - env);
1958
set_environ(var, value);
1960
displayBuffer(Currentbuf, B_NORMAL);
1963
DEFUN(pipeBuf, PIPE_BUF, "Send rendered document to pipe")
1969
CurrentKeyData = NULL; /* not allowed in w3m-control: */
1970
cmd = searchKeyData();
1971
if (cmd == NULL || *cmd == '\0') {
1972
/* FIXME: gettextize? */
1973
cmd = inputLineHist("Pipe buffer to: ", "", IN_COMMAND, ShellHist);
1976
cmd = conv_to_system(cmd);
1977
if (cmd == NULL || *cmd == '\0') {
1978
displayBuffer(Currentbuf, B_NORMAL);
1981
tmpf = tmpfname(TMPF_DFL, NULL)->ptr;
1982
f = fopen(tmpf, "w");
1984
/* FIXME: gettextize? */
1985
disp_message(Sprintf("Can't save buffer to %s", cmd)->ptr, TRUE);
1988
saveBuffer(Currentbuf, f, TRUE);
1990
buf = getpipe(myExtCommand(cmd, shell_quote(tmpf), TRUE)->ptr);
1992
disp_message("Execution failed", TRUE);
1996
buf->filename = cmd;
1997
buf->buffername = Sprintf("%s %s", PIPEBUFFERNAME,
1998
conv_from_system(cmd))->ptr;
1999
buf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
2000
if (buf->type == NULL)
2001
buf->type = "text/plain";
2002
buf->currentURL.file = "-";
2005
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2008
/* Execute shell command and read output ac pipe. */
2009
DEFUN(pipesh, PIPE_SHELL, "Execute shell command and browse")
2014
CurrentKeyData = NULL; /* not allowed in w3m-control: */
2015
cmd = searchKeyData();
2016
if (cmd == NULL || *cmd == '\0') {
2017
cmd = inputLineHist("(read shell[pipe])!", "", IN_COMMAND, ShellHist);
2020
cmd = conv_to_system(cmd);
2021
if (cmd == NULL || *cmd == '\0') {
2022
displayBuffer(Currentbuf, B_NORMAL);
2027
disp_message("Execution failed", TRUE);
2031
buf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
2032
if (buf->type == NULL)
2033
buf->type = "text/plain";
2036
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2039
/* Execute shell command and load entire output to buffer */
2040
DEFUN(readsh, READ_SHELL, "Execute shell command and load")
2043
MySignalHandler(*prevtrap) ();
2046
CurrentKeyData = NULL; /* not allowed in w3m-control: */
2047
cmd = searchKeyData();
2048
if (cmd == NULL || *cmd == '\0') {
2049
cmd = inputLineHist("(read shell)!", "", IN_COMMAND, ShellHist);
2052
cmd = conv_to_system(cmd);
2053
if (cmd == NULL || *cmd == '\0') {
2054
displayBuffer(Currentbuf, B_NORMAL);
2057
prevtrap = mySignal(SIGINT, intTrap);
2059
buf = getshell(cmd);
2060
mySignal(SIGINT, prevtrap);
2063
/* FIXME: gettextize? */
2064
disp_message("Execution failed", TRUE);
2068
buf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
2069
if (buf->type == NULL)
2070
buf->type = "text/plain";
2073
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2076
/* Execute shell command */
2077
DEFUN(execsh, EXEC_SHELL SHELL, "Execute shell command")
2081
CurrentKeyData = NULL; /* not allowed in w3m-control: */
2082
cmd = searchKeyData();
2083
if (cmd == NULL || *cmd == '\0') {
2084
cmd = inputLineHist("(exec shell)!", "", IN_COMMAND, ShellHist);
2087
cmd = conv_to_system(cmd);
2088
if (cmd != NULL && *cmd != '\0') {
2092
/* FIXME: gettextize? */
2093
printf("\n[Hit any key]");
2098
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2102
DEFUN(ldfile, LOAD, "Load local file")
2106
fn = searchKeyData();
2107
if (fn == NULL || *fn == '\0') {
2108
/* FIXME: gettextize? */
2109
fn = inputFilenameHist("(Load)Filename? ", NULL, LoadHist);
2112
fn = conv_to_system(fn);
2113
if (fn == NULL || *fn == '\0') {
2114
displayBuffer(Currentbuf, B_NORMAL);
2120
/* Load help file */
2121
DEFUN(ldhelp, HELP, "View help")
2129
n = strcspn(lang, ";, \t");
2130
tmp = Sprintf("file:///$LIB/" HELP_CGI CGI_EXTENSION "?version=%s&lang=%s",
2131
Str_form_quote(Strnew_charp(w3m_version))->ptr,
2132
Str_form_quote(Strnew_charp_n(lang, n))->ptr);
2133
cmd_loadURL(tmp->ptr, NULL, NO_REFERER, NULL);
2135
cmd_loadURL(helpFile(HELP_FILE), NULL, NO_REFERER, NULL);
2140
cmd_loadfile(char *fn)
2144
buf = loadGeneralFile(file_to_url(fn), NULL, NO_REFERER, 0, NULL);
2146
/* FIXME: gettextize? */
2147
char *emsg = Sprintf("%s not found", conv_from_system(fn))->ptr;
2148
disp_err_message(emsg, FALSE);
2150
else if (buf != NO_BUFFER) {
2152
if (RenderFrame && Currentbuf->frameset != NULL)
2155
displayBuffer(Currentbuf, B_NORMAL);
2158
/* Move cursor left */
2162
int i, m = searchKeyNum();
2163
if (Currentbuf->firstLine == NULL)
2165
for (i = 0; i < m; i++)
2166
cursorLeft(Currentbuf, n);
2167
displayBuffer(Currentbuf, B_NORMAL);
2170
DEFUN(movL, MOVE_LEFT,
2171
"Move cursor left (a half screen shift at the left edge)")
2173
_movL(Currentbuf->COLS / 2);
2176
DEFUN(movL1, MOVE_LEFT1, "Move cursor left (1 columns shift at the left edge)")
2181
/* Move cursor downward */
2185
int i, m = searchKeyNum();
2186
if (Currentbuf->firstLine == NULL)
2188
for (i = 0; i < m; i++)
2189
cursorDown(Currentbuf, n);
2190
displayBuffer(Currentbuf, B_NORMAL);
2193
DEFUN(movD, MOVE_DOWN,
2194
"Move cursor down (a half screen scroll at the end of screen)")
2196
_movD((Currentbuf->LINES + 1) / 2);
2199
DEFUN(movD1, MOVE_DOWN1,
2200
"Move cursor down (1 line scroll at the end of screen)")
2205
/* move cursor upward */
2209
int i, m = searchKeyNum();
2210
if (Currentbuf->firstLine == NULL)
2212
for (i = 0; i < m; i++)
2213
cursorUp(Currentbuf, n);
2214
displayBuffer(Currentbuf, B_NORMAL);
2217
DEFUN(movU, MOVE_UP,
2218
"Move cursor up (a half screen scroll at the top of screen)")
2220
_movU((Currentbuf->LINES + 1) / 2);
2223
DEFUN(movU1, MOVE_UP1, "Move cursor up (1 line scrol at the top of screen)")
2228
/* Move cursor right */
2232
int i, m = searchKeyNum();
2233
if (Currentbuf->firstLine == NULL)
2235
for (i = 0; i < m; i++)
2236
cursorRight(Currentbuf, n);
2237
displayBuffer(Currentbuf, B_NORMAL);
2240
DEFUN(movR, MOVE_RIGHT,
2241
"Move cursor right (a half screen shift at the right edge)")
2243
_movR(Currentbuf->COLS / 2);
2246
DEFUN(movR1, MOVE_RIGHT1,
2247
"Move cursor right (1 columns shift at the right edge)")
2254
* From: Takashi Nishimoto <g96p0935@mse.waseda.ac.jp> Date: Mon, 14 Jun
2255
* 1999 09:29:56 +0900
2257
#if defined(USE_M17N) && defined(USE_UNICODE)
2258
#define nextChar(s, l) do { (s)++; } while ((s) < (l)->len && (l)->propBuf[s] & PC_WCHAR2)
2259
#define prevChar(s, l) do { (s)--; } while ((s) > 0 && (l)->propBuf[s] & PC_WCHAR2)
2264
return wc_any_to_ucs(wtf_parse1(&p));
2268
is_wordchar(wc_uint32 c)
2270
return wc_is_ucs_alnum(c);
2273
#define nextChar(s, l) (s)++
2274
#define prevChar(s, l) (s)--
2275
#define getChar(p) ((int)*(p))
2285
prev_nonnull_line(Line *line)
2289
for (l = line; l != NULL && l->len == 0; l = l->prev) ;
2290
if (l == NULL || l->len == 0)
2293
Currentbuf->currentLine = l;
2295
Currentbuf->pos = Currentbuf->currentLine->len;
2299
DEFUN(movLW, PREV_WORD, "Move to previous word")
2304
int i, n = searchKeyNum();
2306
if (Currentbuf->firstLine == NULL)
2309
for (i = 0; i < n; i++) {
2310
pline = Currentbuf->currentLine;
2311
ppos = Currentbuf->pos;
2313
if (prev_nonnull_line(Currentbuf->currentLine) < 0)
2317
l = Currentbuf->currentLine;
2319
while (Currentbuf->pos > 0) {
2320
int tmp = Currentbuf->pos;
2322
if (is_wordchar(getChar(&lb[tmp])))
2324
Currentbuf->pos = tmp;
2326
if (Currentbuf->pos > 0)
2328
if (prev_nonnull_line(Currentbuf->currentLine->prev) < 0) {
2329
Currentbuf->currentLine = pline;
2330
Currentbuf->pos = ppos;
2333
Currentbuf->pos = Currentbuf->currentLine->len;
2336
l = Currentbuf->currentLine;
2338
while (Currentbuf->pos > 0) {
2339
int tmp = Currentbuf->pos;
2341
if (!is_wordchar(getChar(&lb[tmp])))
2343
Currentbuf->pos = tmp;
2347
arrangeCursor(Currentbuf);
2348
displayBuffer(Currentbuf, B_NORMAL);
2352
next_nonnull_line(Line *line)
2356
for (l = line; l != NULL && l->len == 0; l = l->next) ;
2358
if (l == NULL || l->len == 0)
2361
Currentbuf->currentLine = l;
2363
Currentbuf->pos = 0;
2367
DEFUN(movRW, NEXT_WORD, "Move to next word")
2372
int i, n = searchKeyNum();
2374
if (Currentbuf->firstLine == NULL)
2377
for (i = 0; i < n; i++) {
2378
pline = Currentbuf->currentLine;
2379
ppos = Currentbuf->pos;
2381
if (next_nonnull_line(Currentbuf->currentLine) < 0)
2384
l = Currentbuf->currentLine;
2386
while (Currentbuf->pos < l->len &&
2387
is_wordchar(getChar(&lb[Currentbuf->pos])))
2388
nextChar(Currentbuf->pos, l);
2391
while (Currentbuf->pos < l->len &&
2392
!is_wordchar(getChar(&lb[Currentbuf->pos])))
2393
nextChar(Currentbuf->pos, l);
2394
if (Currentbuf->pos < l->len)
2396
if (next_nonnull_line(Currentbuf->currentLine->next) < 0) {
2397
Currentbuf->currentLine = pline;
2398
Currentbuf->pos = ppos;
2401
Currentbuf->pos = 0;
2402
l = Currentbuf->currentLine;
2407
arrangeCursor(Currentbuf);
2408
displayBuffer(Currentbuf, B_NORMAL);
2412
_quitfm(int confirm)
2416
if (checkDownloadList())
2417
/* FIXME: gettextize? */
2418
ans = inputChar("Download process retains. "
2419
"Do you want to exit w3m? (y/n)");
2421
/* FIXME: gettextize? */
2422
ans = inputChar("Do you want to exit w3m? (y/n)");
2423
if (!(ans && TOLOWER(*ans) == 'y')) {
2424
displayBuffer(Currentbuf, B_NORMAL);
2428
term_title(""); /* XXX */
2436
#endif /* USE_COOKIE */
2438
if (UseHistory && SaveURLHist)
2439
saveHistory(URLHist, URLHistSize);
2440
#endif /* USE_HISTORY */
2445
DEFUN(quitfm, ABORT EXIT, "Quit w3m without confirmation")
2450
/* Question and Quit */
2451
DEFUN(qquitfm, QUIT, "Quit w3m")
2453
_quitfm(confirm_on_quit);
2457
DEFUN(selBuf, SELECT, "Go to buffer selection panel")
2465
buf = selectBuffer(Firstbuf, Currentbuf, &cmd);
2477
if (Firstbuf == NULL) {
2478
/* No more buffer */
2479
Firstbuf = nullBuffer();
2480
Currentbuf = Firstbuf;
2492
for (buf = Firstbuf; buf != NULL; buf = buf->nextBuffer) {
2493
if (buf == Currentbuf)
2499
tmpClearBuffer(buf);
2501
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2504
/* Suspend (on BSD), or run interactive shell (on SysV) */
2505
DEFUN(susp, INTERRUPT SUSPEND, "Stop loading document")
2509
#endif /* not SIGSTOP */
2515
shell = getenv("SHELL");
2520
kill((pid_t) 0, SIGSTOP);
2521
#endif /* SIGSTOP */
2523
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2526
/* Go to specified line */
2530
if (l == NULL || *l == '\0' || Currentbuf->currentLine == NULL) {
2531
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2534
Currentbuf->pos = 0;
2535
if (((*l == '^') || (*l == '$')) && prec_num) {
2536
gotoRealLine(Currentbuf, prec_num);
2538
else if (*l == '^') {
2539
Currentbuf->topLine = Currentbuf->currentLine = Currentbuf->firstLine;
2541
else if (*l == '$') {
2542
Currentbuf->topLine =
2543
lineSkip(Currentbuf, Currentbuf->lastLine,
2544
-(Currentbuf->LINES + 1) / 2, TRUE);
2545
Currentbuf->currentLine = Currentbuf->lastLine;
2548
gotoRealLine(Currentbuf, atoi(l));
2549
arrangeCursor(Currentbuf);
2550
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2553
DEFUN(goLine, GOTO_LINE, "Go to specified line")
2556
char *str = searchKeyData();
2562
/* FIXME: gettextize? */
2563
_goLine(inputStr("Goto line: ", ""));
2567
DEFUN(goLineF, BEGIN, "Go to the first line")
2572
DEFUN(goLineL, END, "Go to the last line")
2577
/* Go to the beginning of the line */
2578
DEFUN(linbeg, LINE_BEGIN, "Go to the beginning of line")
2580
if (Currentbuf->firstLine == NULL)
2582
while (Currentbuf->currentLine->prev && Currentbuf->currentLine->bpos)
2583
cursorUp0(Currentbuf, 1);
2584
Currentbuf->pos = 0;
2585
arrangeCursor(Currentbuf);
2586
displayBuffer(Currentbuf, B_NORMAL);
2589
/* Go to the bottom of the line */
2590
DEFUN(linend, LINE_END, "Go to the end of line")
2592
if (Currentbuf->firstLine == NULL)
2594
while (Currentbuf->currentLine->next
2595
&& Currentbuf->currentLine->next->bpos)
2596
cursorDown0(Currentbuf, 1);
2597
Currentbuf->pos = Currentbuf->currentLine->len - 1;
2598
arrangeCursor(Currentbuf);
2599
displayBuffer(Currentbuf, B_NORMAL);
2603
cur_real_linenumber(Buffer *buf)
2605
Line *l, *cur = buf->currentLine;
2610
n = cur->real_linenumber ? cur->real_linenumber : 1;
2611
for (l = buf->firstLine; l && l != cur && l->real_linenumber == 0; l = l->next) { /* header */
2618
/* Run editor on the current buffer */
2619
DEFUN(editBf, EDIT, "Edit current document")
2621
char *fn = Currentbuf->filename;
2624
if (fn == NULL || Currentbuf->pagerSource != NULL || /* Behaving as a pager */
2625
(Currentbuf->type == NULL && Currentbuf->edit == NULL) || /* Reading shell */
2626
Currentbuf->real_scheme != SCM_LOCAL || !strcmp(Currentbuf->currentURL.file, "-") || /* file is std input */
2627
Currentbuf->bufferprop & BP_FRAME) { /* Frame */
2628
disp_err_message("Can't edit other than local file", TRUE);
2631
if (Currentbuf->edit)
2632
cmd = unquote_mailcap(Currentbuf->edit, Currentbuf->real_type, fn,
2633
checkHeader(Currentbuf, "Content-Type:"), NULL);
2635
cmd = myEditor(Editor, shell_quote(fn),
2636
cur_real_linenumber(Currentbuf));
2641
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2645
/* Run editor on the current screen */
2646
DEFUN(editScr, EDIT_SCREEN, "Edit currently rendered document")
2651
tmpf = tmpfname(TMPF_DFL, NULL)->ptr;
2652
f = fopen(tmpf, "w");
2654
/* FIXME: gettextize? */
2655
disp_err_message(Sprintf("Can't open %s", tmpf)->ptr, TRUE);
2658
saveBuffer(Currentbuf, f, TRUE);
2661
system(myEditor(Editor, shell_quote(tmpf),
2662
cur_real_linenumber(Currentbuf))->ptr);
2665
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2670
/* Set / unset mark */
2671
DEFUN(_mark, MARK, "Set/unset mark")
2676
if (Currentbuf->firstLine == NULL)
2678
l = Currentbuf->currentLine;
2679
l->propBuf[Currentbuf->pos] ^= PE_MARK;
2680
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2683
/* Go to next mark */
2684
DEFUN(nextMk, NEXT_MARK, "Move to next word")
2691
if (Currentbuf->firstLine == NULL)
2693
i = Currentbuf->pos + 1;
2694
l = Currentbuf->currentLine;
2700
for (; i < l->len; i++) {
2701
if (l->propBuf[i] & PE_MARK) {
2702
Currentbuf->currentLine = l;
2703
Currentbuf->pos = i;
2704
arrangeCursor(Currentbuf);
2705
displayBuffer(Currentbuf, B_NORMAL);
2712
/* FIXME: gettextize? */
2713
disp_message("No mark exist after here", TRUE);
2716
/* Go to previous mark */
2717
DEFUN(prevMk, PREV_MARK, "Move to previous mark")
2724
if (Currentbuf->firstLine == NULL)
2726
i = Currentbuf->pos - 1;
2727
l = Currentbuf->currentLine;
2734
for (; i >= 0; i--) {
2735
if (l->propBuf[i] & PE_MARK) {
2736
Currentbuf->currentLine = l;
2737
Currentbuf->pos = i;
2738
arrangeCursor(Currentbuf);
2739
displayBuffer(Currentbuf, B_NORMAL);
2747
/* FIXME: gettextize? */
2748
disp_message("No mark exist before here", TRUE);
2751
/* Mark place to which the regular expression matches */
2752
DEFUN(reMark, REG_MARK, "Set mark using regexp")
2760
str = searchKeyData();
2761
if (str == NULL || *str == '\0') {
2762
str = inputStrHist("(Mark)Regexp: ", MarkString, TextHist);
2763
if (str == NULL || *str == '\0') {
2764
displayBuffer(Currentbuf, B_NORMAL);
2768
str = conv_search_string(str, DisplayCharset);
2769
if ((str = regexCompile(str, 1)) != NULL) {
2770
disp_message(str, TRUE);
2774
for (l = Currentbuf->firstLine; l != NULL; l = l->next) {
2777
if (regexMatch(p, &l->lineBuf[l->len] - p, p == l->lineBuf) == 1) {
2778
matchedPosition(&p1, &p2);
2779
l->propBuf[p1 - l->lineBuf] |= PE_MARK;
2787
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2789
#endif /* USE_MARK */
2792
loadNormalBuf(Buffer *buf, int renderframe)
2795
if (renderframe && RenderFrame && Currentbuf->frameset != NULL)
2801
loadLink(char *url, char *target, char *referer, FormList *request)
2803
Buffer *buf, *nfbuf;
2804
union frameset_element *f_element = NULL;
2806
ParsedURL *base, pu;
2808
message(Sprintf("loading %s", url)->ptr, 0, 0);
2811
base = baseURL(Currentbuf);
2813
base->scheme == SCM_LOCAL || base->scheme == SCM_LOCAL_CGI)
2814
referer = NO_REFERER;
2815
if (referer == NULL)
2816
referer = parsedURL2Str(&Currentbuf->currentURL)->ptr;
2817
buf = loadGeneralFile(url, baseURL(Currentbuf), referer, flag, request);
2819
char *emsg = Sprintf("Can't load %s", url)->ptr;
2820
disp_err_message(emsg, FALSE);
2824
parseURL2(url, &pu, base);
2825
pushHashHist(URLHist, parsedURL2Str(&pu)->ptr);
2827
if (buf == NO_BUFFER) {
2830
if (!on_target) /* open link as an indivisual page */
2831
return loadNormalBuf(buf, TRUE);
2833
if (do_download) /* download (thus no need to render frame) */
2834
return loadNormalBuf(buf, FALSE);
2836
if (target == NULL || /* no target specified (that means this page is not a frame page) */
2837
!strcmp(target, "_top") || /* this link is specified to be opened as an indivisual * page */
2838
!(Currentbuf->bufferprop & BP_FRAME) /* This page is not a frame page */
2840
return loadNormalBuf(buf, TRUE);
2842
nfbuf = Currentbuf->linkBuffer[LB_N_FRAME];
2843
if (nfbuf == NULL) {
2844
/* original page (that contains <frameset> tag) doesn't exist */
2845
return loadNormalBuf(buf, TRUE);
2848
f_element = search_frame(nfbuf->frameset, target);
2849
if (f_element == NULL) {
2850
/* specified target doesn't exist in this frameset */
2851
return loadNormalBuf(buf, TRUE);
2856
/* stack current frameset */
2857
pushFrameTree(&(nfbuf->frameQ), copyFrameSet(nfbuf->frameset), Currentbuf);
2858
/* delete frame view buffer */
2859
delBuffer(Currentbuf);
2861
/* nfbuf->frameset = copyFrameSet(nfbuf->frameset); */
2862
resetFrameElement(f_element, buf, referer, request);
2867
char *label = pu.label;
2869
if (label && f_element->element->attr == F_BODY) {
2870
al = searchAnchor(f_element->body->nameList, label);
2873
label = Strnew_m_charp("_", target, NULL)->ptr;
2874
al = searchURLLabel(Currentbuf, label);
2877
gotoLine(Currentbuf, al->start.line);
2879
Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->topLine,
2880
Currentbuf->currentLine->
2882
Currentbuf->topLine->linenumber,
2884
Currentbuf->pos = al->start.pos;
2885
arrangeCursor(Currentbuf);
2888
displayBuffer(Currentbuf, B_NORMAL);
2893
gotoLabel(char *label)
2899
al = searchURLLabel(Currentbuf, label);
2901
/* FIXME: gettextize? */
2902
disp_message(Sprintf("%s is not found", label)->ptr, TRUE);
2905
buf = newBuffer(Currentbuf->width);
2906
copyBuffer(buf, Currentbuf);
2907
for (i = 0; i < MAX_LB; i++)
2908
buf->linkBuffer[i] = NULL;
2909
buf->currentURL.label = allocStr(label, -1);
2910
pushHashHist(URLHist, parsedURL2Str(&buf->currentURL)->ptr);
2913
gotoLine(Currentbuf, al->start.line);
2915
Currentbuf->topLine = lineSkip(Currentbuf, Currentbuf->topLine,
2916
Currentbuf->currentLine->linenumber
2917
- Currentbuf->topLine->linenumber,
2919
Currentbuf->pos = al->start.pos;
2920
arrangeCursor(Currentbuf);
2921
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2926
handleMailto(char *url)
2931
if (strncasecmp(url, "mailto:", 7))
2933
#ifdef USE_W3MMAILER
2934
if (! non_null(Mailer) || MailtoOptions == MAILTO_OPTIONS_USE_W3MMAILER)
2937
if (!non_null(Mailer)) {
2938
/* FIXME: gettextize? */
2939
disp_err_message("no mailer is specified", TRUE);
2944
/* invoke external mailer */
2945
if (MailtoOptions == MAILTO_OPTIONS_USE_MAILTO_URL) {
2946
to = Strnew_charp(html_unquote(url));
2948
to = Strnew_charp(url + 7);
2949
if ((pos = strchr(to->ptr, '?')) != NULL)
2950
Strtruncate(to, pos - to->ptr);
2953
system(myExtCommand(Mailer, shell_quote(file_unquote(to->ptr)),
2956
displayBuffer(Currentbuf, B_FORCE_REDRAW);
2957
pushHashHist(URLHist, url);
2961
/* follow HREF link */
2962
DEFUN(followA, GOTO_LINK, "Go to current link")
2968
int x = 0, y = 0, map = 0;
2972
if (Currentbuf->firstLine == NULL)
2974
l = Currentbuf->currentLine;
2977
a = retrieveCurrentImg(Currentbuf);
2978
if (a && a->image && a->image->map) {
2982
if (a && a->image && a->image->ismap) {
2983
getMapXY(Currentbuf, a, &x, &y);
2987
a = retrieveCurrentMap(Currentbuf);
2993
a = retrieveCurrentAnchor(Currentbuf);
2998
if (*a->url == '#') { /* index within this buffer */
2999
gotoLabel(a->url + 1);
3002
parseURL2(a->url, &u, baseURL(Currentbuf));
3003
if (Strcmp(parsedURL2Str(&u), parsedURL2Str(&Currentbuf->currentURL)) == 0) {
3004
/* index within this buffer */
3010
if (handleMailto(a->url))
3013
else if (!strncasecmp(a->url, "news:", 5) && strchr(a->url, '@') == NULL) {
3014
/* news:newsgroup is not supported */
3015
/* FIXME: gettextize? */
3016
disp_err_message("news:newsgroup_name is not supported", TRUE);
3019
#endif /* USE_NNTP */
3023
url = Sprintf("%s?%d,%d", a->url, x, y)->ptr;
3026
if (check_target && open_tab_blank && a->target &&
3027
(!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) {
3032
loadLink(url, a->target, a->referer, NULL);
3033
if (buf != Currentbuf)
3036
deleteTab(CurrentTab);
3037
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3040
loadLink(url, a->target, a->referer, NULL);
3041
displayBuffer(Currentbuf, B_NORMAL);
3044
/* follow HREF link in the buffer */
3053
/* view inline image */
3054
DEFUN(followI, VIEW_IMAGE, "View image")
3060
if (Currentbuf->firstLine == NULL)
3062
l = Currentbuf->currentLine;
3064
a = retrieveCurrentImg(Currentbuf);
3067
/* FIXME: gettextize? */
3068
message(Sprintf("loading %s", a->url)->ptr, 0, 0);
3070
buf = loadGeneralFile(a->url, baseURL(Currentbuf), NULL, 0, NULL);
3072
/* FIXME: gettextize? */
3073
char *emsg = Sprintf("Can't load %s", a->url)->ptr;
3074
disp_err_message(emsg, FALSE);
3076
else if (buf != NO_BUFFER) {
3079
displayBuffer(Currentbuf, B_NORMAL);
3082
static FormItemList *
3083
save_submit_formlist(FormItemList *src)
3087
FormItemList *srcitem;
3089
FormItemList *ret = NULL;
3091
FormSelectOptionItem *opt;
3092
FormSelectOptionItem *curopt;
3093
FormSelectOptionItem *srcopt;
3094
#endif /* MENU_SELECT */
3098
srclist = src->parent;
3099
list = New(FormList);
3100
list->method = srclist->method;
3101
list->action = Strdup(srclist->action);
3103
list->charset = srclist->charset;
3105
list->enctype = srclist->enctype;
3106
list->nitems = srclist->nitems;
3107
list->body = srclist->body;
3108
list->boundary = srclist->boundary;
3109
list->length = srclist->length;
3111
for (srcitem = srclist->item; srcitem; srcitem = srcitem->next) {
3112
item = New(FormItemList);
3113
item->type = srcitem->type;
3114
item->name = Strdup(srcitem->name);
3115
item->value = Strdup(srcitem->value);
3116
item->checked = srcitem->checked;
3117
item->accept = srcitem->accept;
3118
item->size = srcitem->size;
3119
item->rows = srcitem->rows;
3120
item->maxlength = srcitem->maxlength;
3121
item->readonly = srcitem->readonly;
3123
opt = curopt = NULL;
3124
for (srcopt = srcitem->select_option; srcopt; srcopt = srcopt->next) {
3125
if (!srcopt->checked)
3127
opt = New(FormSelectOptionItem);
3128
opt->value = Strdup(srcopt->value);
3129
opt->label = Strdup(srcopt->label);
3130
opt->checked = srcopt->checked;
3131
if (item->select_option == NULL) {
3132
item->select_option = curopt = opt;
3136
curopt = curopt->next;
3139
item->select_option = opt;
3141
item->label = Strdup(srcitem->label);
3142
#endif /* MENU_SELECT */
3143
item->parent = list;
3146
if (list->lastitem == NULL) {
3147
list->item = list->lastitem = item;
3150
list->lastitem->next = item;
3151
list->lastitem = item;
3163
conv_form_encoding(Str val, FormItemList *fi, Buffer *buf)
3165
wc_ces charset = SystemCharset;
3167
if (fi->parent->charset)
3168
charset = fi->parent->charset;
3169
else if (buf->document_charset && buf->document_charset != WC_CES_US_ASCII)
3170
charset = buf->document_charset;
3171
return wc_Str_conv_strict(val, InnerCharset, charset);
3174
#define conv_form_encoding(val, fi, buf) (val)
3178
query_from_followform(Str *query, FormItemList *fi, int multipart)
3184
*query = tmpfname(TMPF_DFL, NULL);
3185
body = fopen((*query)->ptr, "w");
3189
fi->parent->body = (*query)->ptr;
3190
fi->parent->boundary =
3191
Sprintf("------------------------------%d%ld%ld%ld", CurrentPid,
3192
fi->parent, fi->parent->body, fi->parent->boundary)->ptr;
3195
for (f2 = fi->parent->item; f2; f2 = f2->next) {
3196
if (f2->name == NULL)
3198
/* <ISINDEX> is translated into single text form */
3199
if (f2->name->length == 0 &&
3200
(multipart || f2->type != FORM_INPUT_TEXT))
3203
case FORM_INPUT_RESET:
3206
case FORM_INPUT_SUBMIT:
3207
case FORM_INPUT_IMAGE:
3208
if (f2 != fi || f2->value == NULL)
3211
case FORM_INPUT_RADIO:
3212
case FORM_INPUT_CHECKBOX:
3217
if (f2->type == FORM_INPUT_IMAGE) {
3220
getMapXY(Currentbuf, retrieveCurrentImg(Currentbuf), &x, &y);
3222
*query = Strdup(conv_form_encoding(f2->name, fi, Currentbuf));
3223
Strcat_charp(*query, ".x");
3224
form_write_data(body, fi->parent->boundary, (*query)->ptr,
3225
Sprintf("%d", x)->ptr);
3226
*query = Strdup(conv_form_encoding(f2->name, fi, Currentbuf));
3227
Strcat_charp(*query, ".y");
3228
form_write_data(body, fi->parent->boundary, (*query)->ptr,
3229
Sprintf("%d", y)->ptr);
3231
else if (f2->name && f2->name->length > 0 && f2->value != NULL) {
3233
*query = conv_form_encoding(f2->value, fi, Currentbuf);
3234
if (f2->type == FORM_INPUT_FILE)
3235
form_write_from_file(body, fi->parent->boundary,
3236
conv_form_encoding(f2->name, fi,
3239
Str_conv_to_system(f2->value)->ptr);
3241
form_write_data(body, fi->parent->boundary,
3242
conv_form_encoding(f2->name, fi,
3249
if (f2->type == FORM_INPUT_IMAGE) {
3252
getMapXY(Currentbuf, retrieveCurrentImg(Currentbuf), &x, &y);
3255
Str_form_quote(conv_form_encoding
3256
(f2->name, fi, Currentbuf)));
3257
Strcat(*query, Sprintf(".x=%d&", x));
3259
Str_form_quote(conv_form_encoding
3260
(f2->name, fi, Currentbuf)));
3261
Strcat(*query, Sprintf(".y=%d", y));
3265
if (f2->name && f2->name->length > 0) {
3267
Str_form_quote(conv_form_encoding
3268
(f2->name, fi, Currentbuf)));
3269
Strcat_char(*query, '=');
3271
if (f2->value != NULL) {
3272
if (fi->parent->method == FORM_METHOD_INTERNAL)
3273
Strcat(*query, Str_form_quote(f2->value));
3276
Str_form_quote(conv_form_encoding
3277
(f2->value, fi, Currentbuf)));
3282
Strcat_char(*query, '&');
3286
fprintf(body, "--%s--\r\n", fi->parent->boundary);
3290
/* remove trailing & */
3291
while (Strlastchar(*query) == '&')
3292
Strshrink(*query, 1);
3297
DEFUN(submitForm, SUBMIT, "Submit form")
3310
_followForm(int submit)
3315
FormItemList *fi, *f2;
3317
int multipart = 0, i;
3319
if (Currentbuf->firstLine == NULL)
3321
l = Currentbuf->currentLine;
3323
a = retrieveCurrentForm(Currentbuf);
3326
fi = (FormItemList *)a->url;
3328
case FORM_INPUT_TEXT:
3332
/* FIXME: gettextize? */
3333
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3334
/* FIXME: gettextize? */
3335
p = inputStrHist("TEXT:", fi->value ? fi->value->ptr : NULL, TextHist);
3336
if (p == NULL || fi->readonly)
3338
fi->value = Strnew_charp(p);
3339
formUpdateBuffer(a, Currentbuf, fi);
3340
if (fi->accept || fi->parent->nitems == 1)
3343
case FORM_INPUT_FILE:
3347
/* FIXME: gettextize? */
3348
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3349
/* FIXME: gettextize? */
3350
p = inputFilenameHist("Filename:", fi->value ? fi->value->ptr : NULL,
3352
if (p == NULL || fi->readonly)
3354
fi->value = Strnew_charp(p);
3355
formUpdateBuffer(a, Currentbuf, fi);
3356
if (fi->accept || fi->parent->nitems == 1)
3359
case FORM_INPUT_PASSWORD:
3363
/* FIXME: gettextize? */
3364
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3367
/* FIXME: gettextize? */
3368
p = inputLine("Password:", fi->value ? fi->value->ptr : NULL,
3372
fi->value = Strnew_charp(p);
3373
formUpdateBuffer(a, Currentbuf, fi);
3381
/* FIXME: gettextize? */
3382
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3384
formUpdateBuffer(a, Currentbuf, fi);
3386
case FORM_INPUT_RADIO:
3390
/* FIXME: gettextize? */
3391
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3394
formRecheckRadio(a, Currentbuf, fi);
3396
case FORM_INPUT_CHECKBOX:
3400
/* FIXME: gettextize? */
3401
disp_message_nsec("Read only field!", FALSE, 1, TRUE, FALSE);
3404
fi->checked = !fi->checked;
3405
formUpdateBuffer(a, Currentbuf, fi);
3411
if (!formChooseOptionByMenu(fi,
3412
Currentbuf->cursorX - Currentbuf->pos +
3413
a->start.pos + Currentbuf->rootX,
3414
Currentbuf->cursorY + Currentbuf->rootY))
3416
formUpdateBuffer(a, Currentbuf, fi);
3417
if (fi->parent->nitems == 1)
3420
#endif /* MENU_SELECT */
3421
case FORM_INPUT_IMAGE:
3422
case FORM_INPUT_SUBMIT:
3423
case FORM_INPUT_BUTTON:
3427
multipart = (fi->parent->method == FORM_METHOD_POST &&
3428
fi->parent->enctype == FORM_ENCTYPE_MULTIPART);
3429
query_from_followform(&tmp, fi, multipart);
3431
tmp2 = Strdup(fi->parent->action);
3432
if (!Strcmp_charp(tmp2, "!CURRENT_URL!")) {
3433
/* It means "current URL" */
3434
tmp2 = parsedURL2Str(&Currentbuf->currentURL);
3435
if ((p = strchr(tmp2->ptr, '?')) != NULL)
3436
Strshrink(tmp2, (tmp2->ptr + tmp2->length) - p);
3439
if (fi->parent->method == FORM_METHOD_GET) {
3440
if ((p = strchr(tmp2->ptr, '?')) != NULL)
3441
Strshrink(tmp2, (tmp2->ptr + tmp2->length) - p);
3442
Strcat_charp(tmp2, "?");
3444
loadLink(tmp2->ptr, a->target, NULL, NULL);
3446
else if (fi->parent->method == FORM_METHOD_POST) {
3450
stat(fi->parent->body, &st);
3451
fi->parent->length = st.st_size;
3454
fi->parent->body = tmp->ptr;
3455
fi->parent->length = tmp->length;
3457
buf = loadLink(tmp2->ptr, a->target, NULL, fi->parent);
3459
unlink(fi->parent->body);
3461
if (buf && !(buf->bufferprop & BP_REDIRECTED)) { /* buf must be Currentbuf */
3462
/* BP_REDIRECTED means that the buffer is obtained through
3463
* Location: header. In this case, buf->form_submit must not be set
3464
* because the page is not loaded by POST method but GET method.
3466
buf->form_submit = save_submit_formlist(fi);
3469
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 */
3470
do_internal(tmp2->ptr, tmp->ptr);
3473
disp_err_message("Can't send form because of illegal method.",
3477
case FORM_INPUT_RESET:
3478
for (i = 0; i < Currentbuf->formitem->nanchor; i++) {
3479
a2 = &Currentbuf->formitem->anchors[i];
3480
f2 = (FormItemList *)a2->url;
3481
if (f2->parent == fi->parent &&
3482
f2->name && f2->value &&
3483
f2->type != FORM_INPUT_SUBMIT &&
3484
f2->type != FORM_INPUT_HIDDEN &&
3485
f2->type != FORM_INPUT_RESET) {
3486
f2->value = f2->init_value;
3487
f2->checked = f2->init_checked;
3489
f2->label = f2->init_label;
3490
f2->selected = f2->init_selected;
3491
#endif /* MENU_SELECT */
3492
formUpdateBuffer(a2, Currentbuf, f2);
3496
case FORM_INPUT_HIDDEN:
3500
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3503
/* go to the top anchor */
3504
DEFUN(topA, LINK_BEGIN, "Go to the first link")
3506
HmarkerList *hl = Currentbuf->hmarklist;
3511
if (Currentbuf->firstLine == NULL)
3513
if (!hl || hl->nmark == 0)
3516
if (prec_num > hl->nmark)
3517
hseq = hl->nmark - 1;
3518
else if (prec_num > 0)
3519
hseq = prec_num - 1;
3521
if (hseq >= hl->nmark)
3523
po = hl->marks + hseq;
3524
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3526
an = retrieveAnchor(Currentbuf->formitem, po->line, po->pos);
3528
} while (an == NULL);
3530
gotoLine(Currentbuf, po->line);
3531
Currentbuf->pos = po->pos;
3532
arrangeCursor(Currentbuf);
3533
displayBuffer(Currentbuf, B_NORMAL);
3536
/* go to the last anchor */
3537
DEFUN(lastA, LINK_END, "Go to the last link")
3539
HmarkerList *hl = Currentbuf->hmarklist;
3544
if (Currentbuf->firstLine == NULL)
3546
if (!hl || hl->nmark == 0)
3549
if (prec_num >= hl->nmark)
3551
else if (prec_num > 0)
3552
hseq = hl->nmark - prec_num;
3554
hseq = hl->nmark - 1;
3558
po = hl->marks + hseq;
3559
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3561
an = retrieveAnchor(Currentbuf->formitem, po->line, po->pos);
3563
} while (an == NULL);
3565
gotoLine(Currentbuf, po->line);
3566
Currentbuf->pos = po->pos;
3567
arrangeCursor(Currentbuf);
3568
displayBuffer(Currentbuf, B_NORMAL);
3571
/* go to the next anchor */
3572
DEFUN(nextA, NEXT_LINK, "Move to next link")
3577
/* go to the previous anchor */
3578
DEFUN(prevA, PREV_LINK, "Move to previous link")
3583
/* go to the next visited anchor */
3584
DEFUN(nextVA, NEXT_VISITED, "Move to next visited link")
3589
/* go to the previous visited anchor */
3590
DEFUN(prevVA, PREV_VISITED, "Move to previous visited link")
3595
/* go to the next [visited] anchor */
3599
HmarkerList *hl = Currentbuf->hmarklist;
3602
int i, x, y, n = searchKeyNum();
3605
if (Currentbuf->firstLine == NULL)
3607
if (!hl || hl->nmark == 0)
3610
an = retrieveCurrentAnchor(Currentbuf);
3611
if (visited != TRUE && an == NULL)
3612
an = retrieveCurrentForm(Currentbuf);
3614
y = Currentbuf->currentLine->linenumber;
3615
x = Currentbuf->pos;
3617
if (visited == TRUE) {
3621
for (i = 0; i < n; i++) {
3623
if (an && an->hseq >= 0) {
3624
int hseq = an->hseq + 1;
3626
if (hseq >= hl->nmark) {
3627
if (visited == TRUE)
3632
po = &hl->marks[hseq];
3633
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3634
if (visited != TRUE && an == NULL)
3635
an = retrieveAnchor(Currentbuf->formitem, po->line,
3638
if (visited == TRUE && an) {
3639
parseURL2(an->url, &url, baseURL(Currentbuf));
3640
if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
3644
} while (an == NULL || an == pan);
3647
an = closest_next_anchor(Currentbuf->href, NULL, x, y);
3648
if (visited != TRUE)
3649
an = closest_next_anchor(Currentbuf->formitem, an, x, y);
3651
if (visited == TRUE)
3658
if (visited == TRUE) {
3659
parseURL2(an->url, &url, baseURL(Currentbuf));
3660
if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
3666
if (visited == TRUE)
3670
if (an == NULL || an->hseq < 0)
3672
po = &hl->marks[an->hseq];
3673
gotoLine(Currentbuf, po->line);
3674
Currentbuf->pos = po->pos;
3675
arrangeCursor(Currentbuf);
3676
displayBuffer(Currentbuf, B_NORMAL);
3679
/* go to the previous anchor */
3683
HmarkerList *hl = Currentbuf->hmarklist;
3686
int i, x, y, n = searchKeyNum();
3689
if (Currentbuf->firstLine == NULL)
3691
if (!hl || hl->nmark == 0)
3694
an = retrieveCurrentAnchor(Currentbuf);
3695
if (visited != TRUE && an == NULL)
3696
an = retrieveCurrentForm(Currentbuf);
3698
y = Currentbuf->currentLine->linenumber;
3699
x = Currentbuf->pos;
3701
if (visited == TRUE) {
3705
for (i = 0; i < n; i++) {
3707
if (an && an->hseq >= 0) {
3708
int hseq = an->hseq - 1;
3711
if (visited == TRUE)
3716
po = hl->marks + hseq;
3717
an = retrieveAnchor(Currentbuf->href, po->line, po->pos);
3718
if (visited != TRUE && an == NULL)
3719
an = retrieveAnchor(Currentbuf->formitem, po->line,
3722
if (visited == TRUE && an) {
3723
parseURL2(an->url, &url, baseURL(Currentbuf));
3724
if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
3728
} while (an == NULL || an == pan);
3731
an = closest_prev_anchor(Currentbuf->href, NULL, x, y);
3732
if (visited != TRUE)
3733
an = closest_prev_anchor(Currentbuf->formitem, an, x, y);
3735
if (visited == TRUE)
3742
if (visited == TRUE && an) {
3743
parseURL2(an->url, &url, baseURL(Currentbuf));
3744
if (getHashHist(URLHist, parsedURL2Str(&url)->ptr)) {
3750
if (visited == TRUE)
3754
if (an == NULL || an->hseq < 0)
3756
po = hl->marks + an->hseq;
3757
gotoLine(Currentbuf, po->line);
3758
Currentbuf->pos = po->pos;
3759
arrangeCursor(Currentbuf);
3760
displayBuffer(Currentbuf, B_NORMAL);
3763
/* go to the next left/right anchor */
3765
nextX(int d, int dy)
3767
HmarkerList *hl = Currentbuf->hmarklist;
3770
int i, x, y, n = searchKeyNum();
3772
if (Currentbuf->firstLine == NULL)
3774
if (!hl || hl->nmark == 0)
3777
an = retrieveCurrentAnchor(Currentbuf);
3779
an = retrieveCurrentForm(Currentbuf);
3781
l = Currentbuf->currentLine;
3782
x = Currentbuf->pos;
3785
for (i = 0; i < n; i++) {
3787
x = (d > 0) ? an->end.pos : an->start.pos - 1;
3790
for (; x >= 0 && x < l->len; x += d) {
3791
an = retrieveAnchor(Currentbuf->href, y, x);
3793
an = retrieveAnchor(Currentbuf->formitem, y, x);
3801
l = (dy > 0) ? l->next : l->prev;
3804
x = (d > 0) ? 0 : l->len - 1;
3813
gotoLine(Currentbuf, y);
3814
Currentbuf->pos = pan->start.pos;
3815
arrangeCursor(Currentbuf);
3816
displayBuffer(Currentbuf, B_NORMAL);
3819
/* go to the next downward/upward anchor */
3823
HmarkerList *hl = Currentbuf->hmarklist;
3825
int i, x, y, n = searchKeyNum();
3828
if (Currentbuf->firstLine == NULL)
3830
if (!hl || hl->nmark == 0)
3833
an = retrieveCurrentAnchor(Currentbuf);
3835
an = retrieveCurrentForm(Currentbuf);
3837
x = Currentbuf->pos;
3838
y = Currentbuf->currentLine->linenumber + d;
3841
for (i = 0; i < n; i++) {
3843
hseq = abs(an->hseq);
3845
for (; y >= 0 && y <= Currentbuf->lastLine->linenumber; y += d) {
3846
an = retrieveAnchor(Currentbuf->href, y, x);
3848
an = retrieveAnchor(Currentbuf->formitem, y, x);
3849
if (an && hseq != abs(an->hseq)) {
3860
gotoLine(Currentbuf, pan->start.line);
3861
arrangeLine(Currentbuf);
3862
displayBuffer(Currentbuf, B_NORMAL);
3865
/* go to the next left anchor */
3866
DEFUN(nextL, NEXT_LEFT, "Move to next left link")
3871
/* go to the next left-up anchor */
3872
DEFUN(nextLU, NEXT_LEFT_UP, "Move to next left (or upward) link")
3877
/* go to the next right anchor */
3878
DEFUN(nextR, NEXT_RIGHT, "Move to next right link")
3883
/* go to the next right-down anchor */
3884
DEFUN(nextRD, NEXT_RIGHT_DOWN, "Move to next right (or downward) link")
3889
/* go to the next downward anchor */
3890
DEFUN(nextD, NEXT_DOWN, "Move to next downward link")
3895
/* go to the next upward anchor */
3896
DEFUN(nextU, NEXT_UP, "Move to next upward link")
3901
/* go to the next bufferr */
3902
DEFUN(nextBf, NEXT, "Move to next buffer")
3907
for (i = 0; i < PREC_NUM; i++) {
3908
buf = prevBuffer(Firstbuf, Currentbuf);
3916
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3919
/* go to the previous bufferr */
3920
DEFUN(prevBf, PREV, "Move to previous buffer")
3925
for (i = 0; i < PREC_NUM; i++) {
3926
buf = Currentbuf->nextBuffer;
3934
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3938
checkBackBuffer(Buffer *buf)
3940
Buffer *fbuf = buf->linkBuffer[LB_N_FRAME];
3944
return TRUE; /* Currentbuf has stacked frames */
3945
/* when no frames stacked and next is frame source, try next's
3947
if (RenderFrame && fbuf == buf->nextBuffer) {
3948
if (fbuf->nextBuffer != NULL)
3955
if (buf->nextBuffer)
3961
/* delete current buffer and back to the previous buffer */
3962
DEFUN(backBf, BACK, "Back to previous buffer")
3964
Buffer *buf = Currentbuf->linkBuffer[LB_N_FRAME];
3966
if (!checkBackBuffer(Currentbuf)) {
3967
if (close_tab_back && nTab >= 1) {
3968
deleteTab(CurrentTab);
3969
displayBuffer(Currentbuf, B_FORCE_REDRAW);
3972
/* FIXME: gettextize? */
3973
disp_message("Can't back...", TRUE);
3977
delBuffer(Currentbuf);
3981
struct frameset *fs;
3982
long linenumber = buf->frameQ->linenumber;
3983
long top = buf->frameQ->top_linenumber;
3984
int pos = buf->frameQ->pos;
3985
int currentColumn = buf->frameQ->currentColumn;
3986
AnchorList *formitem = buf->frameQ->formitem;
3988
fs = popFrameTree(&(buf->frameQ));
3989
deleteFrameSet(buf->frameset);
3992
if (buf == Currentbuf) {
3994
Currentbuf->topLine = lineSkip(Currentbuf,
3995
Currentbuf->firstLine, top - 1,
3997
gotoLine(Currentbuf, linenumber);
3998
Currentbuf->pos = pos;
3999
Currentbuf->currentColumn = currentColumn;
4000
arrangeCursor(Currentbuf);
4001
formResetBuffer(Currentbuf, formitem);
4004
else if (RenderFrame && buf == Currentbuf) {
4005
delBuffer(Currentbuf);
4008
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4011
DEFUN(deletePrevBuf, DELETE_PREVBUF,
4012
"Delete previous buffer (mainly for local-CGI)")
4014
Buffer *buf = Currentbuf->nextBuffer;
4020
cmd_loadURL(char *url, ParsedURL *current, char *referer, FormList *request)
4024
if (handleMailto(url))
4027
if (!strncasecmp(url, "news:", 5) && strchr(url, '@') == NULL) {
4028
/* news:newsgroup is not supported */
4029
/* FIXME: gettextize? */
4030
disp_err_message("news:newsgroup_name is not supported", TRUE);
4033
#endif /* USE_NNTP */
4036
buf = loadGeneralFile(url, current, referer, 0, request);
4038
/* FIXME: gettextize? */
4039
char *emsg = Sprintf("Can't load %s", conv_from_system(url))->ptr;
4040
disp_err_message(emsg, FALSE);
4042
else if (buf != NO_BUFFER) {
4044
if (RenderFrame && Currentbuf->frameset != NULL)
4047
displayBuffer(Currentbuf, B_NORMAL);
4051
/* go to specified URL */
4053
goURL0(char *prompt, int relative)
4055
char *url, *referer;
4056
ParsedURL p_url, *current;
4057
Buffer *cur_buf = Currentbuf;
4059
url = searchKeyData();
4061
Hist *hist = copyHist(URLHist);
4064
current = baseURL(Currentbuf);
4066
char *c_url = parsedURL2Str(current)->ptr;
4067
if (DefaultURLString == DEFAULT_URL_CURRENT) {
4070
url = url_unquote_conv(url, 0);
4073
pushHist(hist, c_url);
4075
a = retrieveCurrentAnchor(Currentbuf);
4078
parseURL2(a->url, &p_url, current);
4079
a_url = parsedURL2Str(&p_url)->ptr;
4080
if (DefaultURLString == DEFAULT_URL_LINK) {
4083
url = url_unquote_conv(url, Currentbuf->document_charset);
4086
pushHist(hist, a_url);
4088
url = inputLineHist(prompt, url, IN_URL, hist);
4094
if ((relative || *url == '#') && Currentbuf->document_charset)
4095
url = wc_conv_strict(url, InnerCharset,
4096
Currentbuf->document_charset)->ptr;
4098
url = conv_to_system(url);
4101
if (url == NULL || *url == '\0') {
4102
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4110
current = baseURL(Currentbuf);
4111
referer = parsedURL2Str(&Currentbuf->currentURL)->ptr;
4117
parseURL2(url, &p_url, current);
4118
pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);
4119
cmd_loadURL(url, current, referer, NULL);
4120
if (Currentbuf != cur_buf) /* success */
4121
pushHashHist(URLHist, parsedURL2Str(&Currentbuf->currentURL)->ptr);
4124
DEFUN(goURL, GOTO, "Go to URL")
4126
goURL0("Goto URL: ", FALSE);
4129
DEFUN(gorURL, GOTO_RELATIVE, "Go to relative URL")
4131
goURL0("Goto relative URL: ", TRUE);
4135
cmd_loadBuffer(Buffer *buf, int prop, int linkid)
4138
disp_err_message("Can't load string", FALSE);
4140
else if (buf != NO_BUFFER) {
4141
buf->bufferprop |= (BP_INTERNAL | prop);
4142
if (!(buf->bufferprop & BP_NO_URL))
4143
copyParsedURL(&buf->currentURL, &Currentbuf->currentURL);
4144
if (linkid != LB_NOLINK) {
4145
buf->linkBuffer[REV_LB[linkid]] = Currentbuf;
4146
Currentbuf->linkBuffer[linkid] = buf;
4150
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4154
DEFUN(ldBmark, BOOKMARK VIEW_BOOKMARK, "Read bookmark")
4156
cmd_loadURL(BookmarkFile, NULL, NO_REFERER, NULL);
4160
/* Add current to bookmark */
4161
DEFUN(adBmark, ADD_BOOKMARK, "Add current page to bookmark")
4166
tmp = Sprintf("mode=panel&cookie=%s&bmark=%s&url=%s&title=%s"
4171
(Str_form_quote(localCookie()))->ptr,
4172
(Str_form_quote(Strnew_charp(BookmarkFile)))->ptr,
4173
(Str_form_quote(parsedURL2Str(&Currentbuf->currentURL)))->
4176
(Str_form_quote(wc_conv_strict(Currentbuf->buffername,
4178
BookmarkCharset)))->ptr,
4179
wc_ces_to_charset(BookmarkCharset));
4181
(Str_form_quote(Strnew_charp(Currentbuf->buffername)))->ptr);
4183
request = newFormList(NULL, "post", NULL, NULL, NULL, NULL, NULL);
4184
request->body = tmp->ptr;
4185
request->length = tmp->length;
4186
cmd_loadURL("file:///$LIB/" W3MBOOKMARK_CMDNAME, NULL, NO_REFERER,
4190
/* option setting */
4191
DEFUN(ldOpt, OPTIONS, "Option setting panel")
4193
cmd_loadBuffer(load_option_panel(), BP_NO_URL, LB_NOLINK);
4197
DEFUN(setOpt, SET_OPTION, "Set option")
4201
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4202
opt = searchKeyData();
4203
if (opt == NULL || *opt == '\0' || strchr(opt, '=') == NULL) {
4204
if (opt != NULL && *opt != '\0') {
4205
char *v = get_param_option(opt);
4206
opt = Sprintf("%s=%s", opt, v ? v : "")->ptr;
4208
opt = inputStrHist("Set option: ", opt, TextHist);
4209
if (opt == NULL || *opt == '\0') {
4210
displayBuffer(Currentbuf, B_NORMAL);
4214
if (set_param_option(opt))
4216
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
4219
/* error message list */
4220
DEFUN(msgs, MSGS, "Display error messages")
4222
cmd_loadBuffer(message_list_panel(), BP_NO_URL, LB_NOLINK);
4226
DEFUN(pginfo, INFO, "View info of current document")
4230
if ((buf = Currentbuf->linkBuffer[LB_N_INFO]) != NULL) {
4232
displayBuffer(Currentbuf, B_NORMAL);
4235
if ((buf = Currentbuf->linkBuffer[LB_INFO]) != NULL)
4237
buf = page_info_panel(Currentbuf);
4238
cmd_loadBuffer(buf, BP_NORMAL, LB_INFO);
4242
follow_map(struct parsed_tagarg *arg)
4244
char *name = tag_get_value(arg, "link");
4245
#if defined(MENU_MAP) || defined(USE_IMAGE)
4251
an = retrieveCurrentImg(Currentbuf);
4252
x = Currentbuf->cursorX + Currentbuf->rootX;
4253
y = Currentbuf->cursorY + Currentbuf->rootY;
4254
a = follow_map_menu(Currentbuf, name, an, x, y);
4255
if (a == NULL || a->url == NULL || *(a->url) == '\0') {
4258
Buffer *buf = follow_map_panel(Currentbuf, name);
4261
cmd_loadBuffer(buf, BP_NORMAL, LB_NOLINK);
4263
#if defined(MENU_MAP) || defined(USE_IMAGE)
4266
if (*(a->url) == '#') {
4267
gotoLabel(a->url + 1);
4270
parseURL2(a->url, &p_url, baseURL(Currentbuf));
4271
pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);
4272
if (check_target && open_tab_blank && a->target &&
4273
(!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) {
4278
cmd_loadURL(a->url, baseURL(Currentbuf),
4279
parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL);
4280
if (buf != Currentbuf)
4283
deleteTab(CurrentTab);
4284
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4287
cmd_loadURL(a->url, baseURL(Currentbuf),
4288
parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL);
4294
DEFUN(linkMn, LINK_MENU, "Popup link element menu")
4296
LinkList *l = link_menu(Currentbuf);
4301
if (*(l->url) == '#') {
4302
gotoLabel(l->url + 1);
4305
parseURL2(l->url, &p_url, baseURL(Currentbuf));
4306
pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr);
4307
cmd_loadURL(l->url, baseURL(Currentbuf),
4308
parsedURL2Str(&Currentbuf->currentURL)->ptr, NULL);
4312
anchorMn(Anchor *(*menu_func) (Buffer *), int go)
4317
if (!Currentbuf->href || !Currentbuf->hmarklist)
4319
a = menu_func(Currentbuf);
4320
if (!a || a->hseq < 0)
4322
po = &Currentbuf->hmarklist->marks[a->hseq];
4323
gotoLine(Currentbuf, po->line);
4324
Currentbuf->pos = po->pos;
4325
arrangeCursor(Currentbuf);
4326
displayBuffer(Currentbuf, B_NORMAL);
4332
DEFUN(accessKey, ACCESSKEY, "Popup acceskey menu")
4334
anchorMn(accesskey_menu, TRUE);
4338
DEFUN(listMn, LIST_MENU, "Popup link list menu and go to selected link")
4340
anchorMn(list_menu, TRUE);
4343
DEFUN(movlistMn, MOVE_LIST_MENU,
4344
"Popup link list menu and move cursor to selected link")
4346
anchorMn(list_menu, FALSE);
4350
/* link,anchor,image list */
4351
DEFUN(linkLst, LIST, "Show all links and images")
4355
buf = link_list_panel(Currentbuf);
4358
buf->document_charset = Currentbuf->document_charset;
4360
cmd_loadBuffer(buf, BP_NORMAL, LB_NOLINK);
4366
DEFUN(cooLst, COOKIE, "View cookie list")
4370
buf = cookie_list_panel();
4372
cmd_loadBuffer(buf, BP_NO_URL, LB_NOLINK);
4374
#endif /* USE_COOKIE */
4378
DEFUN(ldHist, HISTORY, "View history of URL")
4380
cmd_loadBuffer(historyBuffer(URLHist), BP_NO_URL, LB_NOLINK);
4382
#endif /* USE_HISTORY */
4384
/* download HREF link */
4385
DEFUN(svA, SAVE_LINK, "Save link to file")
4387
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4390
do_download = FALSE;
4393
/* download IMG link */
4394
DEFUN(svI, SAVE_IMAGE, "Save image to file")
4396
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4399
do_download = FALSE;
4403
DEFUN(svBuf, PRINT SAVE_SCREEN, "Save rendered document to file")
4405
char *qfile = NULL, *file;
4409
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4410
file = searchKeyData();
4411
if (file == NULL || *file == '\0') {
4412
/* FIXME: gettextize? */
4413
qfile = inputLineHist("Save buffer to: ", NULL, IN_COMMAND, SaveHist);
4414
if (qfile == NULL || *qfile == '\0') {
4415
displayBuffer(Currentbuf, B_NORMAL);
4419
file = conv_to_system(qfile ? qfile : file);
4422
f = popen(file + 1, "w");
4426
file = unescape_spaces(Strnew_charp(qfile))->ptr;
4427
file = conv_to_system(file);
4429
file = expandPath(file);
4430
if (checkOverWrite(file) < 0) {
4431
displayBuffer(Currentbuf, B_NORMAL);
4434
f = fopen(file, "w");
4438
/* FIXME: gettextize? */
4439
char *emsg = Sprintf("Can't open %s", conv_from_system(file))->ptr;
4440
disp_err_message(emsg, TRUE);
4443
saveBuffer(Currentbuf, f, TRUE);
4448
displayBuffer(Currentbuf, B_NORMAL);
4452
DEFUN(svSrc, DOWNLOAD SAVE, "Save document source to file")
4456
if (Currentbuf->sourcefile == NULL)
4458
CurrentKeyData = NULL; /* not allowed in w3m-control: */
4459
PermitSaveToPipe = TRUE;
4460
if (Currentbuf->real_scheme == SCM_LOCAL)
4461
file = conv_from_system(guess_save_name(NULL,
4462
Currentbuf->currentURL.
4465
file = guess_save_name(Currentbuf, Currentbuf->currentURL.file);
4466
doFileCopy(Currentbuf->sourcefile, file);
4467
PermitSaveToPipe = FALSE;
4468
displayBuffer(Currentbuf, B_NORMAL);
4472
_peekURL(int only_img)
4477
static Str s = NULL;
4479
static Lineprop *p = NULL;
4482
static int offset = 0, n;
4484
if (Currentbuf->firstLine == NULL)
4486
if (CurrentKey == prev_key && s != NULL) {
4487
if (s->length - offset >= COLS)
4489
else if (s->length <= offset) /* bug ? */
4497
a = (only_img ? NULL : retrieveCurrentAnchor(Currentbuf));
4499
a = (only_img ? NULL : retrieveCurrentForm(Currentbuf));
4501
a = retrieveCurrentImg(Currentbuf);
4506
s = Strnew_charp(form2str((FormItemList *)a->url));
4509
parseURL2(a->url, &pu, baseURL(Currentbuf));
4510
s = parsedURL2Str(&pu);
4513
s = Strnew_charp(url_unquote_conv
4514
(s->ptr, Currentbuf->document_charset));
4516
s = checkType(s, &pp, NULL);
4517
p = NewAtom_N(Lineprop, s->length);
4518
bcopy((void *)pp, (void *)p, s->length * sizeof(Lineprop));
4522
if (n > 1 && s->length > (n - 1) * (COLS - 1))
4523
offset = (n - 1) * (COLS - 1);
4525
while (offset < s->length && p[offset] & PC_WCHAR2)
4528
disp_message_nomouse(&s->ptr[offset], TRUE);
4532
DEFUN(peekURL, PEEK_LINK, "Peek link URL")
4537
/* peek URL of image */
4538
DEFUN(peekIMG, PEEK_IMG, "Peek image URL")
4543
/* show current URL */
4547
if (Currentbuf->bufferprop & BP_INTERNAL)
4548
return Strnew_size(0);
4549
return parsedURL2Str(&Currentbuf->currentURL);
4552
DEFUN(curURL, PEEK, "Peek current URL")
4554
static Str s = NULL;
4556
static Lineprop *p = NULL;
4559
static int offset = 0, n;
4561
if (Currentbuf->bufferprop & BP_INTERNAL)
4563
if (CurrentKey == prev_key && s != NULL) {
4564
if (s->length - offset >= COLS)
4566
else if (s->length <= offset) /* bug ? */
4573
s = Strnew_charp(url_unquote_conv(s->ptr, 0));
4575
s = checkType(s, &pp, NULL);
4576
p = NewAtom_N(Lineprop, s->length);
4577
bcopy((void *)pp, (void *)p, s->length * sizeof(Lineprop));
4581
if (n > 1 && s->length > (n - 1) * (COLS - 1))
4582
offset = (n - 1) * (COLS - 1);
4584
while (offset < s->length && p[offset] & PC_WCHAR2)
4587
disp_message_nomouse(&s->ptr[offset], TRUE);
4589
/* view HTML source */
4591
DEFUN(vwSrc, SOURCE VIEW, "View HTML source")
4595
if (Currentbuf->type == NULL || Currentbuf->bufferprop & BP_FRAME)
4597
if ((buf = Currentbuf->linkBuffer[LB_SOURCE]) != NULL ||
4598
(buf = Currentbuf->linkBuffer[LB_N_SOURCE]) != NULL) {
4600
displayBuffer(Currentbuf, B_NORMAL);
4603
if (Currentbuf->sourcefile == NULL) {
4604
if (Currentbuf->pagerSource &&
4605
!strcasecmp(Currentbuf->type, "text/plain")) {
4608
wc_bool old_fix_width_conv;
4611
Str tmpf = tmpfname(TMPF_SRC, NULL);
4612
f = fopen(tmpf->ptr, "w");
4616
old_charset = DisplayCharset;
4617
old_fix_width_conv = WcOption.fix_width_conv;
4618
DisplayCharset = (Currentbuf->document_charset != WC_CES_US_ASCII)
4619
? Currentbuf->document_charset : 0;
4620
WcOption.fix_width_conv = WC_FALSE;
4622
saveBufferBody(Currentbuf, f, TRUE);
4624
DisplayCharset = old_charset;
4625
WcOption.fix_width_conv = old_fix_width_conv;
4628
Currentbuf->sourcefile = tmpf->ptr;
4635
buf = newBuffer(INIT_BUFFER_WIDTH);
4637
if (is_html_type(Currentbuf->type)) {
4638
buf->type = "text/plain";
4639
if (Currentbuf->real_type &&
4640
is_html_type(Currentbuf->real_type))
4641
buf->real_type = "text/plain";
4643
buf->real_type = Currentbuf->real_type;
4644
buf->buffername = Sprintf("source of %s", Currentbuf->buffername)->ptr;
4645
buf->linkBuffer[LB_N_SOURCE] = Currentbuf;
4646
Currentbuf->linkBuffer[LB_SOURCE] = buf;
4648
else if (!strcasecmp(Currentbuf->type, "text/plain")) {
4649
buf->type = "text/html";
4650
if (Currentbuf->real_type &&
4651
!strcasecmp(Currentbuf->real_type, "text/plain"))
4652
buf->real_type = "text/html";
4654
buf->real_type = Currentbuf->real_type;
4655
buf->buffername = Sprintf("HTML view of %s",
4656
Currentbuf->buffername)->ptr;
4657
buf->linkBuffer[LB_SOURCE] = Currentbuf;
4658
Currentbuf->linkBuffer[LB_N_SOURCE] = buf;
4663
buf->currentURL = Currentbuf->currentURL;
4664
buf->real_scheme = Currentbuf->real_scheme;
4665
buf->filename = Currentbuf->filename;
4666
buf->sourcefile = Currentbuf->sourcefile;
4667
buf->header_source = Currentbuf->header_source;
4668
buf->search_header = Currentbuf->search_header;
4670
buf->document_charset = Currentbuf->document_charset;
4672
buf->clone = Currentbuf->clone;
4675
buf->need_reshape = TRUE;
4678
displayBuffer(Currentbuf, B_NORMAL);
4682
DEFUN(reload, RELOAD, "Reload buffer")
4684
Buffer *buf, *fbuf = NULL, sbuf;
4692
if (Currentbuf->bufferprop & BP_INTERNAL) {
4693
if (!strcmp(Currentbuf->buffername, DOWNLOAD_LIST_TITLE)) {
4697
/* FIXME: gettextize? */
4698
disp_err_message("Can't reload...", TRUE);
4701
if (Currentbuf->currentURL.scheme == SCM_LOCAL &&
4702
!strcmp(Currentbuf->currentURL.file, "-")) {
4703
/* file is std input */
4704
/* FIXME: gettextize? */
4705
disp_err_message("Can't reload stdin", TRUE);
4708
copyBuffer(&sbuf, Currentbuf);
4709
if (Currentbuf->bufferprop & BP_FRAME &&
4710
(fbuf = Currentbuf->linkBuffer[LB_N_FRAME])) {
4711
if (fmInitialized) {
4712
message("Rendering frame", 0, 0);
4715
if (!(buf = renderFrame(fbuf, 1))) {
4716
displayBuffer(Currentbuf, B_NORMAL);
4719
if (fbuf->linkBuffer[LB_FRAME]) {
4720
if (buf->sourcefile &&
4721
fbuf->linkBuffer[LB_FRAME]->sourcefile &&
4722
!strcmp(buf->sourcefile,
4723
fbuf->linkBuffer[LB_FRAME]->sourcefile))
4724
fbuf->linkBuffer[LB_FRAME]->sourcefile = NULL;
4725
delBuffer(fbuf->linkBuffer[LB_FRAME]);
4727
fbuf->linkBuffer[LB_FRAME] = buf;
4728
buf->linkBuffer[LB_N_FRAME] = fbuf;
4731
if (Currentbuf->firstLine) {
4732
COPY_BUFROOT(Currentbuf, &sbuf);
4733
restorePosition(Currentbuf, &sbuf);
4735
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4738
else if (Currentbuf->frameset != NULL)
4739
fbuf = Currentbuf->linkBuffer[LB_FRAME];
4741
if (Currentbuf->form_submit) {
4742
request = Currentbuf->form_submit->parent;
4743
if (request->method == FORM_METHOD_POST
4744
&& request->enctype == FORM_ENCTYPE_MULTIPART) {
4748
query_from_followform(&query, Currentbuf->form_submit, multipart);
4749
stat(request->body, &st);
4750
request->length = st.st_size;
4756
url = parsedURL2Str(&Currentbuf->currentURL);
4757
/* FIXME: gettextize? */
4758
message("Reloading...", 0, 0);
4761
old_charset = DocumentCharset;
4762
if (Currentbuf->document_charset != WC_CES_US_ASCII)
4763
DocumentCharset = Currentbuf->document_charset;
4765
SearchHeader = Currentbuf->search_header;
4766
DefaultType = Currentbuf->real_type;
4767
buf = loadGeneralFile(url->ptr, NULL, NO_REFERER, RG_NOCACHE, request);
4769
DocumentCharset = old_charset;
4771
SearchHeader = FALSE;
4775
unlink(request->body);
4777
/* FIXME: gettextize? */
4778
disp_err_message("Can't reload...", TRUE);
4781
else if (buf == NO_BUFFER) {
4782
displayBuffer(Currentbuf, B_NORMAL);
4786
Firstbuf = deleteBuffer(Firstbuf, fbuf);
4787
repBuffer(Currentbuf, buf);
4788
if ((buf->type != NULL) && (sbuf.type != NULL) &&
4789
((!strcasecmp(buf->type, "text/plain") &&
4790
is_html_type(sbuf.type)) ||
4791
(is_html_type(buf->type) &&
4792
!strcasecmp(sbuf.type, "text/plain")))) {
4794
if (Currentbuf != buf)
4795
Firstbuf = deleteBuffer(Firstbuf, buf);
4797
Currentbuf->search_header = sbuf.search_header;
4798
Currentbuf->form_submit = sbuf.form_submit;
4799
if (Currentbuf->firstLine) {
4800
COPY_BUFROOT(Currentbuf, &sbuf);
4801
restorePosition(Currentbuf, &sbuf);
4803
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4807
DEFUN(reshape, RESHAPE, "Re-render buffer")
4809
Currentbuf->need_reshape = TRUE;
4810
reshapeBuffer(Currentbuf);
4811
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4816
_docCSet(wc_ces charset)
4818
if (Currentbuf->bufferprop & BP_INTERNAL)
4820
if (Currentbuf->sourcefile == NULL) {
4821
disp_message("Can't reload...", FALSE);
4824
Currentbuf->document_charset = charset;
4825
Currentbuf->need_reshape = TRUE;
4826
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4830
change_charset(struct parsed_tagarg *arg)
4832
Buffer *buf = Currentbuf->linkBuffer[LB_N_INFO];
4837
delBuffer(Currentbuf);
4839
if (Currentbuf->bufferprop & BP_INTERNAL)
4841
charset = Currentbuf->document_charset;
4842
for (; arg; arg = arg->next) {
4843
if (!strcmp(arg->arg, "charset"))
4844
charset = atoi(arg->value);
4849
DEFUN(docCSet, CHARSET, "Change the current document charset")
4854
cs = searchKeyData();
4855
if (cs == NULL || *cs == '\0')
4856
/* FIXME: gettextize? */
4857
cs = inputStr("Document charset: ",
4858
wc_ces_to_charset(Currentbuf->document_charset));
4859
charset = wc_guess_charset_short(cs, 0);
4861
displayBuffer(Currentbuf, B_NORMAL);
4867
DEFUN(defCSet, DEFAULT_CHARSET, "Change the default document charset")
4872
cs = searchKeyData();
4873
if (cs == NULL || *cs == '\0')
4874
/* FIXME: gettextize? */
4875
cs = inputStr("Default document charset: ",
4876
wc_ces_to_charset(DocumentCharset));
4877
charset = wc_guess_charset_short(cs, 0);
4879
DocumentCharset = charset;
4880
displayBuffer(Currentbuf, B_NORMAL);
4884
/* mark URL-like patterns as anchors */
4886
chkURLBuffer(Buffer *buf)
4888
static char *url_like_pat[] = {
4889
"https?://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$;]*[a-zA-Z0-9_/=\\-]",
4890
"file:/[a-zA-Z0-9:%\\-\\./=_\\+@#,\\$;]*",
4892
"gopher://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./_]*",
4893
#endif /* USE_GOPHER */
4894
"ftp://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./=_+@#,\\$]*[a-zA-Z0-9_/]",
4896
"news:[^<> ][^<> ]*",
4897
"nntp://[a-zA-Z0-9][a-zA-Z0-9:%\\-\\./_]*",
4898
#endif /* USE_NNTP */
4899
#ifndef USE_W3MMAILER /* see also chkExternalURIBuffer() */
4900
"mailto:[^<> ][^<> ]*@[a-zA-Z0-9][a-zA-Z0-9\\-\\._]*[a-zA-Z0-9]",
4903
"https?://[a-zA-Z0-9:%\\-\\./_@]*\\[[a-fA-F0-9:][a-fA-F0-9:\\.]*\\][a-zA-Z0-9:%\\-\\./?=~_\\&+@#,\\$;]*",
4904
"ftp://[a-zA-Z0-9:%\\-\\./_@]*\\[[a-fA-F0-9:][a-fA-F0-9:\\.]*\\][a-zA-Z0-9:%\\-\\./=_+@#,\\$]*",
4909
for (i = 0; url_like_pat[i]; i++) {
4910
reAnchor(buf, url_like_pat[i]);
4912
#ifdef USE_EXTERNAL_URI_LOADER
4913
chkExternalURIBuffer(buf);
4915
buf->check_url |= CHK_URL;
4918
DEFUN(chkURL, MARK_URL, "Mark URL-like strings as anchors")
4920
chkURLBuffer(Currentbuf);
4921
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4924
DEFUN(chkWORD, MARK_WORD, "Mark current word as anchor")
4928
p = getCurWord(Currentbuf, &spos, &epos);
4931
reAnchorWord(Currentbuf, Currentbuf->currentLine, spos, epos);
4932
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4936
/* mark Message-ID-like patterns as NEWS anchors */
4938
chkNMIDBuffer(Buffer *buf)
4940
static char *url_like_pat[] = {
4941
"<[!-;=?-~]+@[a-zA-Z0-9\\.\\-_]+>",
4945
for (i = 0; url_like_pat[i]; i++) {
4946
reAnchorNews(buf, url_like_pat[i]);
4948
buf->check_url |= CHK_NMID;
4951
DEFUN(chkNMID, MARK_MID, "Mark Message-ID-like strings as anchors")
4953
chkNMIDBuffer(Currentbuf);
4954
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4956
#endif /* USE_NNTP */
4959
DEFUN(rFrame, FRAME, "Render frame")
4963
if ((buf = Currentbuf->linkBuffer[LB_FRAME]) != NULL) {
4965
displayBuffer(Currentbuf, B_NORMAL);
4968
if (Currentbuf->frameset == NULL) {
4969
if ((buf = Currentbuf->linkBuffer[LB_N_FRAME]) != NULL) {
4971
displayBuffer(Currentbuf, B_NORMAL);
4975
if (fmInitialized) {
4976
message("Rendering frame", 0, 0);
4979
buf = renderFrame(Currentbuf, 0);
4981
displayBuffer(Currentbuf, B_NORMAL);
4984
buf->linkBuffer[LB_N_FRAME] = Currentbuf;
4985
Currentbuf->linkBuffer[LB_FRAME] = buf;
4987
if (fmInitialized && display_ok)
4988
displayBuffer(Currentbuf, B_FORCE_REDRAW);
4991
/* spawn external browser */
4993
invoke_browser(char *url)
4996
char *browser = NULL;
4999
CurrentKeyData = NULL; /* not allowed in w3m-control: */
5000
browser = searchKeyData();
5001
if (browser == NULL || *browser == '\0') {
5005
browser = ExtBrowser;
5008
browser = ExtBrowser2;
5011
browser = ExtBrowser3;
5014
if (browser == NULL || *browser == '\0') {
5015
browser = inputStr("Browse command: ", NULL);
5016
if (browser != NULL)
5017
browser = conv_to_system(browser);
5021
browser = conv_to_system(browser);
5023
if (browser == NULL || *browser == '\0') {
5024
displayBuffer(Currentbuf, B_NORMAL);
5028
if ((len = strlen(browser)) >= 2 && browser[len - 1] == '&' &&
5029
browser[len - 2] != '\\') {
5030
browser = allocStr(browser, len - 2);
5033
cmd = myExtCommand(browser, shell_quote(url), FALSE);
5034
Strremovetrailingspaces(cmd);
5036
mySystem(cmd->ptr, bg);
5038
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5041
DEFUN(extbrz, EXTERN, "Execute external browser")
5043
if (Currentbuf->bufferprop & BP_INTERNAL) {
5044
/* FIXME: gettextize? */
5045
disp_err_message("Can't browse...", TRUE);
5048
if (Currentbuf->currentURL.scheme == SCM_LOCAL &&
5049
!strcmp(Currentbuf->currentURL.file, "-")) {
5050
/* file is std input */
5051
/* FIXME: gettextize? */
5052
disp_err_message("Can't browse stdin", TRUE);
5055
invoke_browser(parsedURL2Str(&Currentbuf->currentURL)->ptr);
5058
DEFUN(linkbrz, EXTERN_LINK, "View current link using external browser")
5063
if (Currentbuf->firstLine == NULL)
5065
a = retrieveCurrentAnchor(Currentbuf);
5068
parseURL2(a->url, &pu, baseURL(Currentbuf));
5069
invoke_browser(parsedURL2Str(&pu)->ptr);
5072
/* show current line number and number of lines in the entire document */
5073
DEFUN(curlno, LINE_INFO, "Show current line number")
5075
Line *l = Currentbuf->currentLine;
5077
int cur = 0, all = 0, col = 0, len = 0;
5080
cur = l->real_linenumber;
5081
col = l->bwidth + Currentbuf->currentColumn + Currentbuf->cursorX + 1;
5082
while (l->next && l->next->bpos)
5085
l->width = COLPOS(l, l->len);
5086
len = l->bwidth + l->width;
5088
if (Currentbuf->lastLine)
5089
all = Currentbuf->lastLine->real_linenumber;
5090
if (Currentbuf->pagerSource && !(Currentbuf->bufferprop & BP_CLOSE))
5091
tmp = Sprintf("line %d col %d/%d", cur, col, len);
5093
tmp = Sprintf("line %d/%d (%d%%) col %d/%d", cur, all,
5094
(int)((double)cur * 100.0 / (double)(all ? all : 1)
5097
Strcat_charp(tmp, " ");
5098
Strcat_charp(tmp, wc_ces_to_charset_desc(Currentbuf->document_charset));
5101
disp_message(tmp->ptr, FALSE);
5105
DEFUN(dispI, DISPLAY_IMAGE, "Restart loading and drawing of images")
5111
displayImage = TRUE;
5113
* if (!(Currentbuf->type && is_html_type(Currentbuf->type)))
5116
Currentbuf->image_flag = IMG_FLAG_AUTO;
5117
Currentbuf->need_reshape = TRUE;
5118
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
5121
DEFUN(stopI, STOP_IMAGE, "Stop loading and drawing of images")
5126
* if (!(Currentbuf->type && is_html_type(Currentbuf->type)))
5129
Currentbuf->image_flag = IMG_FLAG_SKIP;
5130
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
5137
mouse_scroll_line(void)
5139
if (relative_wheel_scroll)
5140
return (relative_wheel_scroll_ratio * LASTLINE + 99) / 100;
5142
return fixed_wheel_scroll_count;
5146
posTab(int x, int y)
5150
if (mouse_action.menu_str && x < mouse_action.menu_width && y == 0)
5151
return NO_TABBUFFER;
5154
for (tab = FirstTab; tab; tab = tab->nextTab) {
5155
if (tab->x1 <= x && x <= tab->x2 && tab->y == y)
5162
do_mouse_action(int btn, int x, int y)
5164
MouseActionMap *map = NULL;
5167
if (nTab > 1 || mouse_action.menu_str)
5168
ny = LastTab->y + 1;
5171
case MOUSE_BTN1_DOWN:
5174
case MOUSE_BTN2_DOWN:
5177
case MOUSE_BTN3_DOWN:
5184
if (mouse_action.menu_str && x >= 0 && x < mouse_action.menu_width) {
5185
if (mouse_action.menu_map[btn])
5186
map = &mouse_action.menu_map[btn][x];
5189
map = &mouse_action.tab_map[btn];
5191
else if (y == LASTLINE) {
5192
if (mouse_action.lastline_str && x >= 0 &&
5193
x < mouse_action.lastline_width) {
5194
if (mouse_action.lastline_map[btn])
5195
map = &mouse_action.lastline_map[btn][x];
5199
if (y == Currentbuf->cursorY + Currentbuf->rootY &&
5200
(x == Currentbuf->cursorX + Currentbuf->rootX
5202
|| (WcOption.use_wide && Currentbuf->currentLine != NULL &&
5203
(CharType(Currentbuf->currentLine->propBuf[Currentbuf->pos])
5205
&& x == Currentbuf->cursorX + Currentbuf->rootX + 1)
5208
if (retrieveCurrentAnchor(Currentbuf) ||
5209
retrieveCurrentForm(Currentbuf)) {
5210
map = &mouse_action.active_map[btn];
5211
if (!(map && map->func))
5212
map = &mouse_action.anchor_map[btn];
5216
int cx = Currentbuf->cursorX, cy = Currentbuf->cursorY;
5217
cursorXY(Currentbuf, x - Currentbuf->rootX, y - Currentbuf->rootY);
5218
if (y == Currentbuf->cursorY + Currentbuf->rootY &&
5219
(x == Currentbuf->cursorX + Currentbuf->rootX
5221
|| (WcOption.use_wide && Currentbuf->currentLine != NULL &&
5222
(CharType(Currentbuf->currentLine->
5223
propBuf[Currentbuf->pos]) == PC_KANJI1)
5224
&& x == Currentbuf->cursorX + Currentbuf->rootX + 1)
5227
(retrieveCurrentAnchor(Currentbuf) ||
5228
retrieveCurrentForm(Currentbuf)))
5229
map = &mouse_action.anchor_map[btn];
5230
cursorXY(Currentbuf, cx, cy);
5236
if (!(map && map->func))
5237
map = &mouse_action.default_map[btn];
5238
if (map && map->func) {
5239
mouse_action.in_action = TRUE;
5240
mouse_action.cursorX = x;
5241
mouse_action.cursorY = y;
5243
CurrentKeyData = NULL;
5244
CurrentCmdData = map->data;
5246
CurrentCmdData = NULL;
5251
process_mouse(int btn, int x, int y)
5253
int delta_x, delta_y, i;
5254
static int press_btn = MOUSE_BTN_RESET, press_x, press_y;
5258
if (nTab > 1 || mouse_action.menu_str)
5259
ny = LastTab->y + 1;
5260
if (btn == MOUSE_BTN_UP) {
5261
switch (press_btn) {
5262
case MOUSE_BTN1_DOWN:
5263
if (press_y == y && press_x == x)
5264
do_mouse_action(press_btn, x, y);
5265
else if (ny > 0 && y < ny) {
5267
moveTab(posTab(press_x, press_y), posTab(x, y),
5268
(press_y == y) ? (press_x < x) : (press_y < y));
5271
else if (press_x >= Currentbuf->rootX) {
5272
Buffer *buf = Currentbuf;
5273
int cx = Currentbuf->cursorX, cy = Currentbuf->cursorY;
5278
if (t == NO_TABBUFFER)
5279
t = NULL; /* open new tab */
5280
cursorXY(Currentbuf, press_x - Currentbuf->rootX,
5281
press_y - Currentbuf->rootY);
5282
if (Currentbuf->cursorY == press_y - Currentbuf->rootY &&
5283
(Currentbuf->cursorX == press_x - Currentbuf->rootX
5285
|| (WcOption.use_wide &&
5286
Currentbuf->currentLine != NULL &&
5287
(CharType(Currentbuf->currentLine->
5288
propBuf[Currentbuf->pos]) == PC_KANJI1)
5289
&& Currentbuf->cursorX == press_x
5290
- Currentbuf->rootX - 1)
5293
displayBuffer(Currentbuf, B_NORMAL);
5296
if (buf == Currentbuf)
5297
cursorXY(Currentbuf, cx, cy);
5302
delta_x = x - press_x;
5303
delta_y = y - press_y;
5305
if (abs(delta_x) < abs(delta_y) / 3)
5307
if (abs(delta_y) < abs(delta_x) / 3)
5309
if (reverse_mouse) {
5317
else if (delta_y < 0) {
5318
prec_num = -delta_y;
5325
else if (delta_x < 0) {
5326
prec_num = -delta_x;
5331
case MOUSE_BTN2_DOWN:
5332
case MOUSE_BTN3_DOWN:
5333
if (press_y == y && press_x == x)
5334
do_mouse_action(press_btn, x, y);
5336
case MOUSE_BTN4_DOWN_RXVT:
5337
for (i = 0; i < mouse_scroll_line(); i++)
5340
case MOUSE_BTN5_DOWN_RXVT:
5341
for (i = 0; i < mouse_scroll_line(); i++)
5346
else if (btn == MOUSE_BTN4_DOWN_XTERM) {
5347
for (i = 0; i < mouse_scroll_line(); i++)
5350
else if (btn == MOUSE_BTN5_DOWN_XTERM) {
5351
for (i = 0; i < mouse_scroll_line(); i++)
5355
if (btn != MOUSE_BTN4_DOWN_RXVT || press_btn == MOUSE_BTN_RESET) {
5361
press_btn = MOUSE_BTN_RESET;
5365
DEFUN(msToggle, MOUSE_TOGGLE, "Toggle activity of mouse")
5373
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5376
DEFUN(mouse, MOUSE, "mouse operation")
5380
btn = (unsigned char)getch() - 32;
5381
#if defined(__CYGWIN__) && CYGWIN_VERSION_DLL_MAJOR < 1005
5382
if (cygwin_mouse_btn_swapped) {
5383
if (btn == MOUSE_BTN2_DOWN)
5384
btn = MOUSE_BTN3_DOWN;
5385
else if (btn == MOUSE_BTN3_DOWN)
5386
btn = MOUSE_BTN2_DOWN;
5389
x = (unsigned char)getch() - 33;
5392
y = (unsigned char)getch() - 33;
5396
if (x < 0 || x >= COLS || y < 0 || y > LASTLINE)
5398
process_mouse(btn, x, y);
5403
gpm_process_mouse(Gpm_Event * event, void *data)
5405
int btn = MOUSE_BTN_RESET, x, y;
5406
if (event->type & GPM_UP)
5408
else if (event->type & GPM_DOWN) {
5409
switch (event->buttons) {
5411
btn = MOUSE_BTN1_DOWN;
5414
btn = MOUSE_BTN2_DOWN;
5417
btn = MOUSE_BTN3_DOWN;
5422
GPM_DRAWPOINTER(event);
5427
process_mouse(btn, x - 1, y - 1);
5430
#endif /* USE_GPM */
5434
sysm_process_mouse(int x, int y, int nbs, int obs)
5441
else if (nbs & ~obs) {
5443
btn = bits & 0x1 ? MOUSE_BTN1_DOWN :
5444
(bits & 0x2 ? MOUSE_BTN2_DOWN :
5445
(bits & 0x4 ? MOUSE_BTN3_DOWN : 0));
5447
else /* nbs == obs */
5449
process_mouse(btn, x, y);
5452
#endif /* USE_SYSMOUSE */
5454
DEFUN(movMs, MOVE_MOUSE, "Move cursor to mouse cursor (for mouse action)")
5456
if (!mouse_action.in_action)
5458
if ((nTab > 1 || mouse_action.menu_str) &&
5459
mouse_action.cursorY < LastTab->y + 1)
5461
else if (mouse_action.cursorX >= Currentbuf->rootX &&
5462
mouse_action.cursorY < LASTLINE) {
5463
cursorXY(Currentbuf, mouse_action.cursorX - Currentbuf->rootX,
5464
mouse_action.cursorY - Currentbuf->rootY);
5466
displayBuffer(Currentbuf, B_NORMAL);
5470
#ifdef KANJI_SYMBOLS
5471
#define FRAME_WIDTH 2
5473
#define FRAME_WIDTH 1
5476
DEFUN(menuMs, MENU_MOUSE, "Popup menu at mouse cursor (for mouse action)")
5478
if (!mouse_action.in_action)
5480
if ((nTab > 1 || mouse_action.menu_str) &&
5481
mouse_action.cursorY < LastTab->y + 1)
5482
mouse_action.cursorX -= FRAME_WIDTH + 1;
5483
else if (mouse_action.cursorX >= Currentbuf->rootX &&
5484
mouse_action.cursorY < LASTLINE) {
5485
cursorXY(Currentbuf, mouse_action.cursorX - Currentbuf->rootX,
5486
mouse_action.cursorY - Currentbuf->rootY);
5487
displayBuffer(Currentbuf, B_NORMAL);
5493
DEFUN(tabMs, TAB_MOUSE, "Move to tab on mouse cursor (for mouse action)")
5497
if (!mouse_action.in_action)
5499
tab = posTab(mouse_action.cursorX, mouse_action.cursorY);
5500
if (!tab || tab == NO_TABBUFFER)
5503
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5506
DEFUN(closeTMs, CLOSE_TAB_MOUSE,
5507
"Close tab on mouse cursor (for mouse action)")
5511
if (!mouse_action.in_action)
5513
tab = posTab(mouse_action.cursorX, mouse_action.cursorY);
5514
if (!tab || tab == NO_TABBUFFER)
5517
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5519
#endif /* USE_MOUSE */
5521
DEFUN(dispVer, VERSION, "Display version of w3m")
5523
disp_message(Sprintf("w3m version %s", w3m_version)->ptr, TRUE);
5526
DEFUN(wrapToggle, WRAP_TOGGLE, "Toggle wrap search mode")
5530
/* FIXME: gettextize? */
5531
disp_message("Wrap search off", TRUE);
5535
/* FIXME: gettextize? */
5536
disp_message("Wrap search on", TRUE);
5541
getCurWord(Buffer *buf, int *spos, int *epos)
5544
Line *l = buf->currentLine;
5553
while (e > 0 && !is_wordchar(getChar(&p[e])))
5555
if (!is_wordchar(getChar(&p[e])))
5561
if (!is_wordchar(getChar(&p[tmp])))
5565
while (e < l->len && is_wordchar(getChar(&p[e])))
5573
GetWord(Buffer *buf)
5578
if ((p = getCurWord(buf, &b, &e)) != NULL) {
5579
return Strnew_charp_n(p, e - b)->ptr;
5586
execdict(char *word)
5591
if (!UseDictCommand || word == NULL || *word == '\0') {
5592
displayBuffer(Currentbuf, B_NORMAL);
5595
w = conv_to_system(word);
5597
displayBuffer(Currentbuf, B_NORMAL);
5600
dictcmd = Sprintf("%s?%s", DictCommand,
5601
Str_form_quote(Strnew_charp(w))->ptr)->ptr;
5602
buf = loadGeneralFile(dictcmd, NULL, NO_REFERER, 0, NULL);
5604
disp_message("Execution failed", TRUE);
5609
buf->buffername = Sprintf("%s %s", DICTBUFFERNAME, word)->ptr;
5610
if (buf->type == NULL)
5611
buf->type = "text/plain";
5614
displayBuffer(Currentbuf, B_FORCE_REDRAW);
5617
DEFUN(dictword, DICT_WORD, "Execute dictionary command (see README.dict)")
5619
execdict(inputStr("(dictionary)!", ""));
5622
DEFUN(dictwordat, DICT_WORD_AT,
5623
"Execute dictionary command for word at cursor")
5625
execdict(GetWord(Currentbuf));
5627
#endif /* USE_DICT */
5630
set_buffer_environ(Buffer *buf)
5632
static Buffer *prev_buf = NULL;
5633
static Line *prev_line = NULL;
5634
static int prev_pos = -1;
5639
if (buf != prev_buf) {
5640
set_environ("W3M_SOURCEFILE", buf->sourcefile);
5641
set_environ("W3M_FILENAME", buf->filename);
5642
set_environ("W3M_TITLE", buf->buffername);
5643
set_environ("W3M_URL", parsedURL2Str(&buf->currentURL)->ptr);
5644
set_environ("W3M_TYPE", buf->real_type ? buf->real_type : "unknown");
5646
set_environ("W3M_CHARSET", wc_ces_to_charset(buf->document_charset));
5649
l = buf->currentLine;
5650
if (l && (buf != prev_buf || l != prev_line || buf->pos != prev_pos)) {
5653
char *s = GetWord(buf);
5654
set_environ("W3M_CURRENT_WORD", s ? s : "");
5655
a = retrieveCurrentAnchor(buf);
5657
parseURL2(a->url, &pu, baseURL(buf));
5658
set_environ("W3M_CURRENT_LINK", parsedURL2Str(&pu)->ptr);
5661
set_environ("W3M_CURRENT_LINK", "");
5662
a = retrieveCurrentImg(buf);
5664
parseURL2(a->url, &pu, baseURL(buf));
5665
set_environ("W3M_CURRENT_IMG", parsedURL2Str(&pu)->ptr);
5668
set_environ("W3M_CURRENT_IMG", "");
5669
a = retrieveCurrentForm(buf);
5671
set_environ("W3M_CURRENT_FORM", form2str((FormItemList *)a->url));
5673
set_environ("W3M_CURRENT_FORM", "");
5674
set_environ("W3M_CURRENT_LINE", Sprintf("%d",
5675
l->real_linenumber)->ptr);
5676
set_environ("W3M_CURRENT_COLUMN", Sprintf("%d",
5677
buf->currentColumn +
5678
buf->cursorX + 1)->ptr);
5681
set_environ("W3M_CURRENT_WORD", "");
5682
set_environ("W3M_CURRENT_LINK", "");
5683
set_environ("W3M_CURRENT_IMG", "");
5684
set_environ("W3M_CURRENT_FORM", "");
5685
set_environ("W3M_CURRENT_LINE", "0");
5686
set_environ("W3M_CURRENT_COLUMN", "0");
5690
prev_pos = buf->pos;
5698
if (CurrentKeyData != NULL && *CurrentKeyData != '\0')
5699
data = CurrentKeyData;
5700
else if (CurrentCmdData != NULL && *CurrentCmdData != '\0')
5701
data = CurrentCmdData;
5702
else if (CurrentKey >= 0)
5703
data = getKeyData(CurrentKey);
5704
CurrentKeyData = NULL;
5705
CurrentCmdData = NULL;
5706
if (data == NULL || *data == '\0')
5708
return allocStr(data, -1);
5717
d = searchKeyData();
5720
return n * PREC_NUM;
5728
unsigned long CpList[8], CpSize;
5730
if (!getenv("WINDOWID") && !DosQueryCp(sizeof(CpList), CpList, &CpSize))
5731
return Sprintf("CP%d", *CpList)->ptr;
5743
for (CurrentTab = FirstTab; CurrentTab; CurrentTab = CurrentTab->nextTab) {
5744
while (Firstbuf && Firstbuf != NO_BUFFER) {
5745
buf = Firstbuf->nextBuffer;
5746
discardBuffer(Firstbuf);
5750
while ((f = popText(fileToDelete)) != NULL)
5758
init_migemo(); /* close pipe to migemo */
5769
#ifdef __MINGW32_VERSION
5775
DEFUN(execCmd, COMMAND, "Execute w3m command(s)")
5780
CurrentKeyData = NULL; /* not allowed in w3m-control: */
5781
data = searchKeyData();
5782
if (data == NULL || *data == '\0') {
5783
data = inputStrHist("command [; ...]: ", "", TextHist);
5785
displayBuffer(Currentbuf, B_NORMAL);
5789
/* data: FUNC [DATA] [; FUNC [DATA] ...] */
5797
cmd = getFuncList(p);
5800
p = getQWord(&data);
5802
CurrentKeyData = NULL;
5803
CurrentCmdData = *p ? p : NULL;
5808
w3mFuncList[cmd].func();
5813
CurrentCmdData = NULL;
5815
displayBuffer(Currentbuf, B_NORMAL);
5819
static MySignalHandler
5820
SigAlarm(SIGNAL_ARG)
5824
if (CurrentAlarm->sec > 0) {
5826
CurrentKeyData = NULL;
5827
CurrentCmdData = data = (char *)CurrentAlarm->data;
5832
w3mFuncList[CurrentAlarm->cmd].func();
5837
CurrentCmdData = NULL;
5838
if (CurrentAlarm->status == AL_IMPLICIT_ONCE) {
5839
CurrentAlarm->sec = 0;
5840
CurrentAlarm->status = AL_UNSET;
5842
if (Currentbuf->event) {
5843
if (Currentbuf->event->status != AL_UNSET)
5844
CurrentAlarm = Currentbuf->event;
5846
Currentbuf->event = NULL;
5848
if (!Currentbuf->event)
5849
CurrentAlarm = &DefaultAlarm;
5850
if (CurrentAlarm->sec > 0) {
5851
mySignal(SIGALRM, SigAlarm);
5852
alarm(CurrentAlarm->sec);
5859
DEFUN(setAlarm, ALARM, "Set alarm")
5862
int sec = 0, cmd = -1;
5864
CurrentKeyData = NULL; /* not allowed in w3m-control: */
5865
data = searchKeyData();
5866
if (data == NULL || *data == '\0') {
5867
data = inputStrHist("(Alarm)sec command: ", "", TextHist);
5869
displayBuffer(Currentbuf, B_NORMAL);
5873
if (*data != '\0') {
5874
sec = atoi(getWord(&data));
5876
cmd = getFuncList(getWord(&data));
5879
data = getQWord(&data);
5880
setAlarmEvent(&DefaultAlarm, sec, AL_EXPLICIT, cmd, data);
5881
disp_message_nsec(Sprintf("%dsec %s %s", sec, w3mFuncList[cmd].id,
5882
data)->ptr, FALSE, 1, FALSE, TRUE);
5885
setAlarmEvent(&DefaultAlarm, 0, AL_UNSET, FUNCNAME_nulcmd, NULL);
5887
displayBuffer(Currentbuf, B_NORMAL);
5891
setAlarmEvent(AlarmEvent * event, int sec, short status, int cmd, void *data)
5894
event = New(AlarmEvent);
5896
event->status = status;
5903
DEFUN(reinit, REINIT, "Reload configuration files")
5905
char *resource = searchKeyData();
5907
if (resource == NULL) {
5913
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
5917
if (!strcasecmp(resource, "CONFIG") || !strcasecmp(resource, "RC")) {
5920
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
5925
if (!strcasecmp(resource, "COOKIE")) {
5931
if (!strcasecmp(resource, "KEYMAP")) {
5936
if (!strcasecmp(resource, "MAILCAP")) {
5942
if (!strcasecmp(resource, "MOUSE")) {
5944
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
5950
if (!strcasecmp(resource, "MENU")) {
5956
if (!strcasecmp(resource, "MIMETYPES")) {
5961
#ifdef USE_EXTERNAL_URI_LOADER
5962
if (!strcasecmp(resource, "URIMETHODS")) {
5968
disp_err_message(Sprintf("Don't know how to reinitialize '%s'", resource)->
5972
DEFUN(defKey, DEFINE_KEY,
5973
"Define a binding between a key stroke and a user command")
5977
CurrentKeyData = NULL; /* not allowed in w3m-control: */
5978
data = searchKeyData();
5979
if (data == NULL || *data == '\0') {
5980
data = inputStrHist("Key definition: ", "", TextHist);
5981
if (data == NULL || *data == '\0') {
5982
displayBuffer(Currentbuf, B_NORMAL);
5986
setKeymap(allocStr(data, -1), -1, TRUE);
5987
displayBuffer(Currentbuf, B_NORMAL);
5999
n->currentBuffer = NULL;
6000
n->firstBuffer = NULL;
6015
buf = newBuffer(Currentbuf->width);
6016
copyBuffer(buf, Currentbuf);
6017
buf->nextBuffer = NULL;
6018
for (i = 0; i < MAX_LB; i++)
6019
buf->linkBuffer[i] = NULL;
6021
tag->firstBuffer = tag->currentBuffer = buf;
6023
tag->nextTab = CurrentTab->nextTab;
6024
tag->prevTab = CurrentTab;
6025
if (CurrentTab->nextTab)
6026
CurrentTab->nextTab->prevTab = tag;
6029
CurrentTab->nextTab = tag;
6034
DEFUN(newT, NEW_TAB, "Open new tab")
6037
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6052
for (tab = FirstTab, i = 1; tab && i < n; tab = tab->nextTab, i++) ;
6061
int lcol = 0, rcol = 2, col;
6063
int lcol = 0, rcol = 0, col;
6065
int n1, n2, na, nx, ny, ix, iy;
6068
lcol = mouse_action.menu_str ? mouse_action.menu_width : 0;
6073
n1 = (COLS - rcol - lcol) / TabCols;
6081
n2 = COLS / TabCols;
6084
ny = (nTab - n1 - 1) / n2 + 2;
6086
na = n1 + n2 * (ny - 1);
6087
n1 -= (na - nTab) / ny;
6090
na = n1 + n2 * (ny - 1);
6092
for (iy = 0; iy < ny && tab; iy++) {
6095
col = COLS - rcol - lcol;
6098
nx = n2 - (na - nTab + (iy - 1)) / (ny - 1);
6101
for (ix = 0; ix < nx && tab; ix++, tab = tab->nextTab) {
6102
tab->x1 = col * ix / nx;
6103
tab->x2 = col * (ix + 1) / nx - 1;
6114
deleteTab(TabBuffer * tab)
6122
tab->nextTab->prevTab = tab->prevTab;
6124
LastTab = tab->prevTab;
6125
tab->prevTab->nextTab = tab->nextTab;
6126
if (tab == CurrentTab)
6127
CurrentTab = tab->prevTab;
6129
else { /* tab == FirstTab */
6130
tab->nextTab->prevTab = NULL;
6131
FirstTab = tab->nextTab;
6132
if (tab == CurrentTab)
6133
CurrentTab = tab->nextTab;
6136
buf = tab->firstBuffer;
6137
while (buf && buf != NO_BUFFER) {
6138
next = buf->nextBuffer;
6145
DEFUN(closeT, CLOSE_TAB, "Close current tab")
6152
tab = numTab(PREC_NUM);
6157
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6160
DEFUN(nextT, NEXT_TAB, "Move to next tab")
6166
for (i = 0; i < PREC_NUM; i++) {
6167
if (CurrentTab->nextTab)
6168
CurrentTab = CurrentTab->nextTab;
6170
CurrentTab = FirstTab;
6172
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6175
DEFUN(prevT, PREV_TAB, "Move to previous tab")
6181
for (i = 0; i < PREC_NUM; i++) {
6182
if (CurrentTab->prevTab)
6183
CurrentTab = CurrentTab->prevTab;
6185
CurrentTab = LastTab;
6187
displayBuffer(Currentbuf, B_REDRAW_IMAGE);
6191
followTab(TabBuffer * tab)
6197
a = retrieveCurrentImg(Currentbuf);
6198
if (!(a && a->image && a->image->map))
6200
a = retrieveCurrentAnchor(Currentbuf);
6204
if (tab == CurrentTab) {
6205
check_target = FALSE;
6207
check_target = TRUE;
6212
check_target = FALSE;
6214
check_target = TRUE;
6216
if (buf != Currentbuf)
6219
deleteTab(CurrentTab);
6221
else if (buf != Currentbuf) {
6222
/* buf <- p <- ... <- Currentbuf = c */
6226
p = prevBuffer(c, buf);
6227
p->nextBuffer = NULL;
6229
deleteTab(CurrentTab);
6231
for (buf = p; buf; buf = p) {
6232
p = prevBuffer(c, buf);
6236
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6239
DEFUN(tabA, TAB_LINK, "Open current link on new tab")
6241
followTab(prec_num ? numTab(PREC_NUM) : NULL);
6245
tabURL0(TabBuffer * tab, char *prompt, int relative)
6249
if (tab == CurrentTab) {
6250
goURL0(prompt, relative);
6255
goURL0(prompt, relative);
6257
if (buf != Currentbuf)
6260
deleteTab(CurrentTab);
6262
else if (buf != Currentbuf) {
6263
/* buf <- p <- ... <- Currentbuf = c */
6267
p = prevBuffer(c, buf);
6268
p->nextBuffer = NULL;
6270
deleteTab(CurrentTab);
6272
for (buf = p; buf; buf = p) {
6273
p = prevBuffer(c, buf);
6277
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6280
DEFUN(tabURL, TAB_GOTO, "Open URL on new tab")
6282
tabURL0(prec_num ? numTab(PREC_NUM) : NULL,
6283
"Goto URL on new tab: ", FALSE);
6286
DEFUN(tabrURL, TAB_GOTO_RELATIVE, "Open relative URL on new tab")
6288
tabURL0(prec_num ? numTab(PREC_NUM) : NULL,
6289
"Goto relative URL on new tab: ", TRUE);
6293
moveTab(TabBuffer * t, TabBuffer * t2, int right)
6295
if (t2 == NO_TABBUFFER)
6297
if (!t || !t2 || t == t2 || t == NO_TABBUFFER)
6301
t->nextTab->prevTab = t->prevTab;
6303
LastTab = t->prevTab;
6304
t->prevTab->nextTab = t->nextTab;
6307
t->nextTab->prevTab = NULL;
6308
FirstTab = t->nextTab;
6311
t->nextTab = t2->nextTab;
6314
t2->nextTab->prevTab = t;
6320
t->prevTab = t2->prevTab;
6323
t2->prevTab->nextTab = t;
6328
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6331
DEFUN(tabR, TAB_RIGHT, "Move current tab right")
6336
for (tab = CurrentTab, i = 0; tab && i < PREC_NUM;
6337
tab = tab->nextTab, i++) ;
6338
moveTab(CurrentTab, tab ? tab : LastTab, TRUE);
6341
DEFUN(tabL, TAB_LEFT, "Move current tab left")
6346
for (tab = CurrentTab, i = 0; tab && i < PREC_NUM;
6347
tab = tab->prevTab, i++) ;
6348
moveTab(CurrentTab, tab ? tab : FirstTab, FALSE);
6352
addDownloadList(pid_t pid, char *url, char *save, char *lock, clen_t size)
6356
d = New(DownloadList);
6359
if (save[0] != '/' && save[0] != '~')
6360
save = Strnew_m_charp(CurrentDir, "/", save, NULL)->ptr;
6361
d->save = expandPath(save);
6374
add_download_list = TRUE;
6378
checkDownloadList(void)
6385
for (d = FirstDL; d != NULL; d = d->next) {
6386
if (d->running && !lstat(d->lock, &st))
6393
convert_size3(clen_t size)
6401
tmp = Sprintf(size ? ",%.3d%s" : "%d%s", n, tmp->ptr);
6407
DownloadListBuffer(void)
6413
int duration, rate, eta;
6419
/* FIXME: gettextize? */
6420
src = Strnew_charp("<html><head><title>" DOWNLOAD_LIST_TITLE
6421
"</title></head>\n<body><h1 align=center>"
6422
DOWNLOAD_LIST_TITLE "</h1>\n"
6423
"<form method=internal action=download><hr>\n");
6424
for (d = LastDL; d != NULL; d = d->prev) {
6425
if (lstat(d->lock, &st))
6427
Strcat_charp(src, "<pre>\n");
6428
Strcat(src, Sprintf("%s\n --> %s\n ", html_quote(d->url),
6429
html_quote(conv_from_system(d->save))));
6430
duration = cur_time - d->time;
6431
if (!stat(d->save, &st)) {
6436
duration = st.st_mtime - d->time;
6442
int i, l = COLS - 6;
6444
i = 1.0 * l * size / d->size;
6449
Strcat_char(src, '#');
6451
Strcat_char(src, '_');
6452
Strcat_char(src, '\n');
6454
if ((d->running || d->err) && size < d->size)
6455
Strcat(src, Sprintf(" %s / %s bytes (%d%%)",
6456
convert_size3(size), convert_size3(d->size),
6457
(int)(100.0 * size / d->size)));
6459
Strcat(src, Sprintf(" %s bytes loaded", convert_size3(size)));
6461
rate = size / duration;
6462
Strcat(src, Sprintf(" %02d:%02d:%02d rate %s/sec",
6463
duration / (60 * 60), (duration / 60) % 60,
6464
duration % 60, convert_size(rate, 1)));
6465
if (d->running && size < d->size && rate) {
6466
eta = (d->size - size) / rate;
6467
Strcat(src, Sprintf(" eta %02d:%02d:%02d", eta / (60 * 60),
6468
(eta / 60) % 60, eta % 60));
6471
Strcat_char(src, '\n');
6473
Strcat(src, Sprintf("<input type=submit name=ok%d value=OK>",
6476
case 0: if (size < d->size)
6477
Strcat_charp(src, " Download ended but probably not complete");
6479
Strcat_charp(src, " Download complete");
6481
case 1: Strcat_charp(src, " Error: could not open destination file");
6483
case 2: Strcat_charp(src, " Error: could not write to file (disk full)");
6485
default: Strcat_charp(src, " Error: unknown reason");
6489
Strcat(src, Sprintf("<input type=submit name=stop%d value=STOP>",
6491
Strcat_charp(src, "\n</pre><hr>\n");
6493
Strcat_charp(src, "</form></body></html>");
6494
return loadHTMLString(src);
6498
download_action(struct parsed_tagarg *arg)
6503
for (; arg; arg = arg->next) {
6504
if (!strncmp(arg->arg, "stop", 4)) {
6505
pid = (pid_t) atoi(&arg->arg[4]);
6506
#ifndef __MINGW32_VERSION
6510
else if (!strncmp(arg->arg, "ok", 2))
6511
pid = (pid_t) atoi(&arg->arg[2]);
6514
for (d = FirstDL; d; d = d->next) {
6515
if (d->pid == pid) {
6518
d->prev->next = d->next;
6522
d->next->prev = d->prev;
6539
for (d = FirstDL; d != NULL; d = d->next) {
6542
#ifndef __MINGW32_VERSION
6543
kill(d->pid, SIGKILL);
6549
/* download panel */
6550
DEFUN(ldDL, DOWNLOAD_LIST, "Display download list panel")
6553
int replace = FALSE, new_tab = FALSE;
6558
if (Currentbuf->bufferprop & BP_INTERNAL &&
6559
!strcmp(Currentbuf->buffername, DOWNLOAD_LIST_TITLE))
6563
if (Currentbuf == Firstbuf && Currentbuf->nextBuffer == NULL) {
6565
deleteTab(CurrentTab);
6568
delBuffer(Currentbuf);
6569
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6574
reload = checkDownloadList();
6576
buf = DownloadListBuffer();
6578
displayBuffer(Currentbuf, B_NORMAL);
6581
buf->bufferprop |= (BP_INTERNAL | BP_NO_URL);
6583
COPY_BUFROOT(buf, Currentbuf);
6584
restorePosition(buf, Currentbuf);
6586
if (!replace && open_tab_dl_list) {
6591
if (replace || new_tab)
6595
Currentbuf->event = setAlarmEvent(Currentbuf->event, 1, AL_IMPLICIT,
6596
FUNCNAME_reload, NULL);
6598
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6602
save_buffer_position(Buffer *buf)
6604
BufferPos *b = buf->undo;
6606
if (!buf->firstLine)
6608
if (b && b->top_linenumber == TOP_LINENUMBER(buf) &&
6609
b->cur_linenumber == CUR_LINENUMBER(buf) &&
6610
b->currentColumn == buf->currentColumn && b->pos == buf->pos)
6613
b->top_linenumber = TOP_LINENUMBER(buf);
6614
b->cur_linenumber = CUR_LINENUMBER(buf);
6615
b->currentColumn = buf->currentColumn;
6617
b->bpos = buf->currentLine ? buf->currentLine->bpos : 0;
6619
b->prev = buf->undo;
6621
buf->undo->next = b;
6626
resetPos(BufferPos * b)
6631
top.linenumber = b->top_linenumber;
6632
cur.linenumber = b->cur_linenumber;
6635
buf.currentLine = &cur;
6637
buf.currentColumn = b->currentColumn;
6638
restorePosition(Currentbuf, &buf);
6639
Currentbuf->undo = b;
6640
displayBuffer(Currentbuf, B_FORCE_REDRAW);
6643
DEFUN(undoPos, UNDO, "Cancel the last cursor movement")
6645
BufferPos *b = Currentbuf->undo;
6648
if (!Currentbuf->firstLine)
6652
for (i = 0; i < PREC_NUM && b->prev; i++, b = b->prev) ;
6656
DEFUN(redoPos, REDO, "Cancel the last undo")
6658
BufferPos *b = Currentbuf->undo;
6661
if (!Currentbuf->firstLine)
6665
for (i = 0; i < PREC_NUM && b->next; i++, b = b->next) ;