w3m

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/w3m.git/
Log | Files | Refs | README

commit 7c36643431ba5c4b69deb0a177976a712a81cbc7
parent 97303a1dd05cf8f1f47c4a3fd0ba0d1b519a3a14
Author: ukai <ukai>
Date:   Tue,  5 Nov 2002 17:10:04 +0000

[w3m-dev 03372] tab browser
* display.c (displayBuffer): add ny
			rootY offset by tab
			tab line
	(cursorDown): offset rootY
	(arrangeCursor): offset rootY
* etc.c (columnSkip): offset rootY
	(lineSkip): offset rootY
	(currentLineSkip): offset rootY
* file.c (HTMLlineproc2body): ATTR_TARGET
* fm.h (MapArea): add target
	(Buffer): add rootY
	(TabBuffer): added
	(Currentbuf): comment out
	(Firstbuf): comment out
	(CurrentTab): added
	(FirstTab): added
	(LastTab): added
	(open_tab_blank): added
	(close_tab_back): added
	(nTab): added
	(TabCols): added
	(N_TAB): added
	(Currentbuf): CurrentTab->currentBuffer
	(Firstbuf): CurrentTab->firstBuffer
* funcname.tab (CLOSE_TAB): added
	(NEW_TAB): added
	(NEXT_TAB): added
	(PREV_TAB): added
	(TAB_GOTO): added
	(TAB_GOTO_RELATIVE): added
	(TAB_LEFT): added
	(TAB_LINK): added
	(TAB_MENU): added
	(TAB_RIGHT): added
* html.c (ALST_AREA): add ATTR_TARGET
* image.c (showImageProgress): offset rootY
* main.c (_newT): added
	(followTab): added
	(moveTab): added
	(check_target): added
	(MAIN): init tab related values
		buf => tab
	(nscroll): offset rootY
	(pgFore): offset rootY
	(pgBack): offset rootY
	(ctrCsrV): offset rootY
	(_movD): offset rootY
	(_movU): offset rootY
	(_goLine): offset rootY
	(_mark): offset rootY
	(followA): check target
	(_followForm): offset rootY
	(drawAnchorCursor0): offset rootY
	(drawAnchorCursor): offset rootY
	(backBf): check close_tab_back
	(follow_map): rewrite for tab, check target
	(posTab): added
	(process_mouse): tab operation
			offset rootY
	(deleteFiles): for all buffers in all tabs
	(newTab): added
	(newT): added
	(numTab): added
	(deleteTab): added
	(closeT): added
	(nextT): added
	(prevT): added
	(followTab): added
	(tabA): added
	(tabURL0): added
	(tabURL): added
	(tabrURL): added
	(moveTab): added
	(tabR): added
	(tabL): added
* map.c (follow_map_menu): return MapArea
	(newMapArea): add target args
* menu.c (SelTabMenu): added
	(SelTabV): added
	(initSelTabMenu): added
	(smChTab): added
	(smDelTab): added
	(MainMenuItem): add Select Tab
				on New Tab
	(popupMenu): add initSelTabMenu()
			offset rootY
	(mainMn): offset rootY
	(selMn): offset rootY
	(initSelectMenu): offset rootY
	(tabMn): added
* proto.h (newT): added
	(closeT): added
	(nextT): added
	(prevT): added
	(tabA): added
	(tabURL): added
	(tabrURL): added
	(tabR): added
	(tabL): added
	(newTab): added
	(deleteTab): added
	(follow_map_menu): return MapArea
	(newMapArea): add target arg
	(tabMn): added
* rc.c (CMT_OPEN_TAB_BLANK): added
	(CMT_CLOSE_TAB_BACK): added
	(open_tab_blank): added
	(close_tab_back): added
* doc/README.func (CLOSE_TAB): added
	(NEW_TAB): added
	(NEXT_TAB): added
	(PREV_TAB): added
	(TAB_GOTO): added
	(TAB_GOTO_RELATIVE): added
	(TAB_LEFT): added
	(TAB_LINK): added
	(TAB_MENU): added
	(TAB_RIGHT): added
* doc-jp/README.func: ditto doc/README.func
From: Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp>

Diffstat:
MChangeLog | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdisplay.c | 61++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mdoc-jp/README.func | 10++++++++++
Mdoc/README.func | 10++++++++++
Metc.c | 8++++----
Mfile.c | 6++++--
Mfm.h | 23++++++++++++++++++++++-
Mfuncname.tab | 10++++++++++
Mhtml.c | 4++--
Mimage.c | 2+-
Mmain.c | 514+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Mmap.c | 7++++---
Mmenu.c | 160++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Mproto.h | 20+++++++++++++++++---
Mrc.c | 8++++++++
15 files changed, 898 insertions(+), 68 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,126 @@ +2002-11-06 Hironori SAKAMOTO <hsaka@mth.biglobe.ne.jp> + + * [w3m-dev 03372] tab browser + * display.c (displayBuffer): add ny + rootY offset by tab + tab line + (cursorDown): offset rootY + (arrangeCursor): offset rootY + * etc.c (columnSkip): offset rootY + (lineSkip): offset rootY + (currentLineSkip): offset rootY + * file.c (HTMLlineproc2body): ATTR_TARGET + * fm.h (MapArea): add target + (Buffer): add rootY + (TabBuffer): added + (Currentbuf): comment out + (Firstbuf): comment out + (CurrentTab): added + (FirstTab): added + (LastTab): added + (open_tab_blank): added + (close_tab_back): added + (nTab): added + (TabCols): added + (N_TAB): added + (Currentbuf): CurrentTab->currentBuffer + (Firstbuf): CurrentTab->firstBuffer + * funcname.tab (CLOSE_TAB): added + (NEW_TAB): added + (NEXT_TAB): added + (PREV_TAB): added + (TAB_GOTO): added + (TAB_GOTO_RELATIVE): added + (TAB_LEFT): added + (TAB_LINK): added + (TAB_MENU): added + (TAB_RIGHT): added + * html.c (ALST_AREA): add ATTR_TARGET + * image.c (showImageProgress): offset rootY + * main.c (_newT): added + (followTab): added + (moveTab): added + (check_target): added + (MAIN): init tab related values + buf => tab + (nscroll): offset rootY + (pgFore): offset rootY + (pgBack): offset rootY + (ctrCsrV): offset rootY + (_movD): offset rootY + (_movU): offset rootY + (_goLine): offset rootY + (_mark): offset rootY + (followA): check target + (_followForm): offset rootY + (drawAnchorCursor0): offset rootY + (drawAnchorCursor): offset rootY + (backBf): check close_tab_back + (follow_map): rewrite for tab, check target + (posTab): added + (process_mouse): tab operation + offset rootY + (deleteFiles): for all buffers in all tabs + (newTab): added + (newT): added + (numTab): added + (deleteTab): added + (closeT): added + (nextT): added + (prevT): added + (followTab): added + (tabA): added + (tabURL0): added + (tabURL): added + (tabrURL): added + (moveTab): added + (tabR): added + (tabL): added + * map.c (follow_map_menu): return MapArea + (newMapArea): add target args + * menu.c (SelTabMenu): added + (SelTabV): added + (initSelTabMenu): added + (smChTab): added + (smDelTab): added + (MainMenuItem): add Select Tab + on New Tab + (popupMenu): add initSelTabMenu() + offset rootY + (mainMn): offset rootY + (selMn): offset rootY + (initSelectMenu): offset rootY + (tabMn): added + * proto.h (newT): added + (closeT): added + (nextT): added + (prevT): added + (tabA): added + (tabURL): added + (tabrURL): added + (tabR): added + (tabL): added + (newTab): added + (deleteTab): added + (follow_map_menu): return MapArea + (newMapArea): add target arg + (tabMn): added + * rc.c (CMT_OPEN_TAB_BLANK): added + (CMT_CLOSE_TAB_BACK): added + (open_tab_blank): added + (close_tab_back): added + * doc/README.func (CLOSE_TAB): added + (NEW_TAB): added + (NEXT_TAB): added + (PREV_TAB): added + (TAB_GOTO): added + (TAB_GOTO_RELATIVE): added + (TAB_LEFT): added + (TAB_LINK): added + (TAB_MENU): added + (TAB_RIGHT): added + * doc-jp/README.func: ditto doc/README.func + 2002-11-06 Fumitoshi UKAI <ukai@debian.or.jp> * doc-jp/README.pre_form: added [w3m-dev 03373] diff --git a/display.c b/display.c @@ -227,6 +227,7 @@ displayBuffer(Buffer *buf, int mode) { Str msg; Anchor *aa = NULL; + int ny = 0; if (buf->topLine == NULL && readBufferCache(buf) == 0) { /* clear_buffer */ mode = B_FORCE_REDRAW; @@ -253,6 +254,12 @@ displayBuffer(Buffer *buf, int mode) else buf->rootX = 0; buf->COLS = COLS - buf->rootX; + if (nTab > 1) + ny = (nTab - 1) / N_TAB + 2; + if (buf->rootY != ny) { + buf->rootY = ny; + arrangeCursor(buf); + } if (mode == B_FORCE_REDRAW || mode == B_SCROLL || #ifdef USE_IMAGE mode == B_REDRAW_IMAGE || @@ -388,7 +395,7 @@ displayBuffer(Buffer *buf, int mode) refresh(); } standout(); - message(msg->ptr, buf->cursorX + buf->rootX, buf->cursorY); + message(msg->ptr, buf->cursorX + buf->rootX, buf->cursorY + buf->rootY); standend(); term_title(buf->buffername); refresh(); @@ -428,8 +435,41 @@ redrawNLine(Buffer *buf, int n) #endif /* USE_BG_COLOR */ } #endif /* USE_COLOR */ - for (i = 0, l = buf->topLine; i < LASTLINE; i++) { - if (i >= LASTLINE - n || i < -n) + if (nTab > 1) { + TabBuffer *t; + int nx = N_TAB, col = COLS - 2, x, l; + + move(0, 0); + for (t = FirstTab, i = 0; t; t = t->nextTab, i++) { + x = col * (i % nx) / nx; + move(i / nx, x); + if (t == CurrentTab) + bold(); + addch('['); + l = strlen(t->currentBuffer->buffername); + if (col / nx - 2 > l) + addnstr_sup(" ", (col / nx - 2 - l) / 2); + if (t == CurrentTab) + EFFECT_ACTIVE_START; + addstr(t->currentBuffer->buffername); + if (t == CurrentTab) + EFFECT_ACTIVE_END; + clrtoeol(); + x = col * (i % nx + 1) / nx - 1; + move(i / nx, x); + addch(']'); + if (t == CurrentTab) + boldend(); + clrtoeol(); + } + move(0, col); + addstr(" x"); + move((nTab - 1) / nx + 1, 0); + for (i = 0; i < COLS; i++) + addch('~'); + } + for (i = buf->rootY, l = buf->topLine; i < LASTLINE; i++) { + if (i >= LASTLINE - n || (i - buf->rootY) < -n) l0 = redrawLine(buf, l, i); else { l0 = (l) ? l->next : NULL; @@ -444,7 +484,7 @@ redrawNLine(Buffer *buf, int n) #ifdef USE_IMAGE if (!(activeImage && displayImage && buf->img)) return; - move(buf->cursorY, buf->cursorX); + move(buf->cursorY + buf->rootY, buf->cursorX + buf->rootX); for (i = 0, l = buf->topLine; i < LASTLINE; i++) { if (i >= LASTLINE - n || i < -n) l0 = redrawLineImage(buf, l, i); @@ -666,7 +706,7 @@ redrawLineImage(Buffer *buf, Line *l, int i) buf->need_reshape = TRUE; } x = (int)((rcol - column + buf->rootX) * pixel_per_char); - y = (int)(i * pixel_per_line); + y = (int)((i + buf->rootY) * pixel_per_line); sx = (int)((rcol - COLPOS(l, a->start.pos)) * pixel_per_char); sy = (int)((l->linenumber - image->y) * pixel_per_line); if (sx == 0 && x + image->xoffset >= 0) @@ -1009,7 +1049,7 @@ disp_message_nsec(char *s, int redraw_current, int sec, int purge, int mouse) } if (Currentbuf != NULL) message(s, Currentbuf->cursorX + Currentbuf->rootX, - Currentbuf->cursorY); + Currentbuf->cursorY + Currentbuf->rootY); else message(s, LASTLINE, 0); refresh(); @@ -1065,7 +1105,7 @@ cursorDown(Buffer *buf, int n) { if (buf->firstLine == NULL) return; - if (buf->cursorY < LASTLINE - 1) + if (buf->cursorY + buf->rootY < LASTLINE - 1) cursorUpDown(buf, 1); else { buf->topLine = lineSkip(buf, buf->topLine, n, FALSE); @@ -1180,9 +1220,12 @@ arrangeCursor(Buffer *buf) if (buf == NULL || buf->currentLine == NULL) return; /* Arrange line */ - if (buf->currentLine->linenumber - buf->topLine->linenumber >= LASTLINE || - buf->currentLine->linenumber < buf->topLine->linenumber) { + if (buf->currentLine->linenumber - buf->topLine->linenumber >= LASTLINE - + buf->rootY || buf->currentLine->linenumber < buf->topLine->linenumber) { +/* buf->topLine = buf->currentLine; +*/ + buf->topLine = lineSkip(buf, buf->currentLine, 0, FALSE); } /* Arrange column */ if (buf->currentLine->len == 0) diff --git a/doc-jp/README.func b/doc-jp/README.func @@ -6,6 +6,7 @@ BEGIN 文 BOOKMARK ブックマークを読み込みます CENTER_H カーソルのある位置を行の中央に移動します CENTER_V カーソルのある行を画面の中央に移動します +CLOSE_TAB 現在のタブを閉じます COMMAND w3mのコマンドを実行します COOKIE クッキー一覧を表示します DEFINE_KEY キー入力とコマンドの対応を定義します @@ -57,6 +58,7 @@ MOVE_RIGHT1 MOVE_UP カーソルを上に移動します(改ページ時には半ページスクロール) MOVE_UP1 カーソルを上に移動します(改ページ時には1行スクロール) MSGS エラーメッセージの一覧の表示 +NEW_TAB 新しいタブを開きます NEXT_DOWN カーソルの下側にあるリンクに移動します NEXT_LEFT カーソルの左側にあるリンクに移動します NEXT_LEFT_UP カーソルの左側(無ければ前の行以前)にあるリンクに移動します @@ -65,6 +67,7 @@ NEXT_MARK NEXT_PAGE 次のページを表示します NEXT_RIGHT カーソルの右側にあるリンクに移動します NEXT_RIGHT_DOWN カーソルの右側(無ければ次行以降)にあるリンクに移動します +NEXT_TAB 次のタブに移動します NEXT_UP カーソルの上側にあるリンクに移動します NEXT_WORD 次の単語に移動します NOTHING 何もしません @@ -78,6 +81,7 @@ PIPE_SHELL PREV_LINK 前のリンクに移動します PREV_MARK 一つ前のマークに移動します PREV_PAGE 前のページを表示します +PREV_TAB 前のタブに移動します PREV_WORD 前の単語に移動します PRINT バッファの表示内容をファイルに保存します QUIT w3mを終了します @@ -106,6 +110,12 @@ SOURCE HTML STOP_IMAGE 画像の読込/表示を停止します SUBMIT フォームにサブミットします SUSPEND サスペンド +TAB_GOTO URLを指定して新しいタブで開きます +TAB_GOTO_RELATIVE 相対URLを指定して新しいタブで開きます +TAB_LEFT 現在のタブを左に移動します +TAB_LINK リンクが指す先の文書を新しいタブで開きます +TAB_MENU タブ選択メニューを立ち上げます +TAB_RIGHT 現在のタブを右に移動します UP 画面を1行上にスクロールします VERSION w3m のバージョンを表示します VIEW HTMLのソースを表示します diff --git a/doc/README.func b/doc/README.func @@ -6,6 +6,7 @@ BEGIN Go to the first line BOOKMARK Read bookmark CENTER_H Move to the center line CENTER_V Move to the center column +CLOSE_TAB Close current tab COMMAND Execute w3m command(s) COOKIE View cookie list DEFINE_KEY Define a binding between a key stroke and a user command @@ -57,6 +58,7 @@ MOVE_RIGHT1 Move cursor right (1 columns shift at the right edge) MOVE_UP Move cursor up (a half screen scroll at the top of screen) MOVE_UP1 Move cursor up (1 line scrol at the top of screen) MSGS Display error messages +NEW_TAB Open new tab NEXT_DOWN Move to next downward link NEXT_LEFT Move to next left link NEXT_LEFT_UP Move to next left (or upward) link @@ -65,6 +67,7 @@ NEXT_MARK Move to next word NEXT_PAGE Move to next page NEXT_RIGHT Move to next right link NEXT_RIGHT_DOWN Move to next right (or downward) link +NEXT_TAB Move to next tab NEXT_UP Move to next upward link NEXT_WORD Move to next word NOTHING Do nothing @@ -78,6 +81,7 @@ PIPE_SHELL Execute shell command and browse PREV_LINK Move to previous link PREV_MARK Move to previous mark PREV_PAGE Move to previous page +PREV_TAB Move to previous tab PREV_WORD Move to previous word PRINT Save buffer to file QUIT Quit w3m @@ -106,6 +110,12 @@ SOURCE View HTML source STOP_IMAGE Stop loading and drawing of images SUBMIT Submit form SUSPEND Stop loading document +TAB_GOTO Open URL on new tab +TAB_GOTO_RELATIVE Open relative URL on new tab +TAB_LEFT Move current tab left +TAB_LINK Open current link on new tab +TAB_MENU Popup tab selection menu +TAB_RIGHT Move current tab right UP Scroll up one line VERSION Display version of w3m VIEW View HTML source diff --git a/etc.c b/etc.c @@ -42,7 +42,7 @@ columnSkip(Buffer *buf, int offset) { int i, maxColumn; int column = buf->currentColumn + offset; - int nlines = LASTLINE + 1; + int nlines = LASTLINE + 1 - buf->rootY; Line *l; maxColumn = 0; @@ -91,8 +91,8 @@ lineSkip(Buffer *buf, Line *line, int offset, int last) #ifdef NEXTPAGE_TOPLINE if (!nextpage_topline) #endif - for (i = (LASTLINE - 1) - (buf->lastLine->linenumber - l->linenumber); - i > 0 && l->prev != NULL; i--, l = l->prev) ; + for (i = (LASTLINE - 1 - buf->rootY) - (buf->lastLine->linenumber + - l->linenumber); i > 0 && l->prev != NULL; i--, l = l->prev) ; return l; } @@ -103,7 +103,7 @@ currentLineSkip(Buffer *buf, Line *line, int offset, int last) Line *l = line; if (buf->pagerSource && !(buf->bufferprop & BP_CLOSE)) { - n = line->linenumber + offset + LASTLINE; + n = line->linenumber + offset + LASTLINE - buf->rootY; if (buf->lastLine->linenumber < n) getNextPage(buf, n - buf->lastLine->linenumber); while ((last || (buf->lastLine->linenumber < n)) && diff --git a/file.c b/file.c @@ -4730,7 +4730,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) { Anchor *a_href = NULL, *a_img = NULL, *a_form = NULL; char outc[LINELEN]; - char *p, *q, *r, *s, *str; + char *p, *q, *r, *s, *t, *str; Lineprop outp[LINELEN], mode, effect; int pos; int nlines; @@ -5081,6 +5081,8 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) MapArea *a; p = remove_space(p); p = url_quote_conv(p, buf->document_code); + t = NULL; + parsedtag_get_value(tag, ATTR_TARGET, &t); q = ""; parsedtag_get_value(tag, ATTR_ALT, &q); r = NULL; @@ -5089,7 +5091,7 @@ HTMLlineproc2body(Buffer *buf, Str (*feed) (), int llimit) parsedtag_get_value(tag, ATTR_SHAPE, &r); parsedtag_get_value(tag, ATTR_COORDS, &s); #endif - a = newMapArea(p, q, r, s); + a = newMapArea(p, t, q, r, s); pushValue(buf->maplist->area, (void *)a); } break; diff --git a/fm.h b/fm.h @@ -285,6 +285,7 @@ typedef unsigned char Linecolor; typedef struct _MapArea { char *url; + char *target; char *alt; #ifdef MENU_MAP #ifdef USE_IMAGE @@ -401,6 +402,7 @@ typedef struct _Buffer { short pos; short visualpos; short rootX; + short rootY; short COLS; InputStream pagerSource; AnchorList *href; @@ -441,6 +443,12 @@ typedef struct _Buffer { Anchor *submit; } Buffer; +typedef struct _TabBuffer { + struct _TabBuffer *nextTab; + struct _TabBuffer *prevTab; + Buffer *currentBuffer; + Buffer *firstBuffer; +} TabBuffer; #define COPY_BUFPOSITION(dstbuf, srcbuf) {\ (dstbuf)->topLine = (srcbuf)->topLine; \ @@ -466,7 +474,7 @@ typedef struct _Buffer { #define FONTSTAT_SIZE 4 -#define INIT_BUFFER_WIDTH (COLS-1) +#define INIT_BUFFER_WIDTH (COLS - 1) typedef struct { int pos; @@ -763,8 +771,21 @@ global char *cgi_bin init(NULL); global char *index_file init(NULL); global char *CurrentDir; +/* global Buffer *Currentbuf; global Buffer *Firstbuf; +*/ +global TabBuffer *CurrentTab; +global TabBuffer *FirstTab; +global TabBuffer *LastTab; +global int open_tab_blank init(FALSE); +global int close_tab_back init(FALSE); +global int nTab; +global int TabCols init(10); +#define N_TAB ((COLS - 2 > TabCols * nTab) ? nTab \ + : (nTab - 1) / ((nTab * TabCols - 1) / (COLS - 2) + 1) + 1) +#define Currentbuf (CurrentTab->currentBuffer) +#define Firstbuf (CurrentTab->firstBuffer) global int CurrentKey; global char *CurrentKeyData; global char *CurrentCmdData; diff --git a/funcname.tab b/funcname.tab @@ -10,6 +10,7 @@ BEGIN goLineF BOOKMARK ldBmark CENTER_H ctrCsrH CENTER_V ctrCsrV +CLOSE_TAB closeT COMMAND execCmd COOKIE cooLst DEFINE_KEY defKey @@ -63,6 +64,7 @@ MOVE_RIGHT1 movR1 MOVE_UP movU MOVE_UP1 movU1 MSGS msgs +NEW_TAB newT NEXT_DOWN nextD NEXT_LEFT nextL NEXT_LEFT_UP nextLU @@ -71,6 +73,7 @@ NEXT_MARK nextMk NEXT_PAGE pgFore NEXT_RIGHT nextR NEXT_RIGHT_DOWN nextRD +NEXT_TAB nextT NEXT_UP nextU NEXT_WORD movRW NOTHING nulcmd @@ -85,6 +88,7 @@ PIPE_SHELL pipesh PREV_LINK prevA PREV_MARK prevMk PREV_PAGE pgBack +PREV_TAB prevT PREV_WORD movLW PRINT svBuf QUIT qquitfm @@ -114,6 +118,12 @@ SOURCE vwSrc STOP_IMAGE stopI SUBMIT submitForm SUSPEND susp +TAB_GOTO tabURL +TAB_GOTO_RELATIVE tabrURL +TAB_LEFT tabL +TAB_LINK tabA +TAB_MENU tabMn +TAB_RIGHT tabR UP lup1 VERSION dispVer VIEW vwSrc diff --git a/html.c b/html.c @@ -64,8 +64,8 @@ unsigned char ALST_ISINDEX[] = { ATTR_ACTION, ATTR_PROMPT, ATTR_CORE }; unsigned char ALST_MAP[] = { ATTR_NAME, ATTR_CORE }; #define MAXA_MAP MAXA_CORE + 1 unsigned char ALST_AREA[] = - { ATTR_HREF, ATTR_ALT, ATTR_SHAPE, ATTR_COORDS, ATTR_CORE }; -#define MAXA_AREA MAXA_CORE + 4 + { ATTR_HREF, ATTR_TARGET, ATTR_ALT, ATTR_SHAPE, ATTR_COORDS, ATTR_CORE }; +#define MAXA_AREA MAXA_CORE + 5 unsigned char ALST_BASE[] = { ATTR_HREF, ATTR_TARGET, ATTR_CORE }; #define MAXA_BASE MAXA_CORE + 2 unsigned char ALST_BODY[] = { ATTR_BACKGROUND, ATTR_CORE }; diff --git a/image.c b/image.c @@ -358,7 +358,7 @@ showImageProgress(Buffer *buf) } if (n) { message(Sprintf("%d/%d images loaded", l, n)->ptr, - buf->cursorX + buf->rootX, buf->cursorY); + buf->cursorX + buf->rootX, buf->cursorY + buf->rootY); refresh(); } } diff --git a/main.c b/main.c @@ -90,6 +90,10 @@ void set_buffer_environ(Buffer *); static void _followForm(int); static void _goLine(char *); +static void _newT(void); +static void followTab(TabBuffer *tab); +static void moveTab(TabBuffer *t, TabBuffer *t2, int right); +static int check_target = TRUE; #define PREC_NUM (prec_num ? prec_num : 1) #define PREC_LIMIT 10000 static int searchKeyNum(void); @@ -707,8 +711,10 @@ MAIN(int argc, char **argv, char **envp) sock_init(); #endif - Firstbuf = NULL; - Currentbuf = NULL; + FirstTab = NULL; + LastTab = NULL; + nTab = 0; + CurrentTab = NULL; CurrentKey = -1; if (BookmarkFile == NULL) BookmarkFile = rcFile(BOOKMARK); @@ -879,8 +885,11 @@ MAIN(int argc, char **argv, char **envp) else if (newbuf == NO_BUFFER) continue; newbuf->search_header = search_header; - if (Currentbuf == NULL) + if (CurrentTab == NULL) { + FirstTab = LastTab = CurrentTab = newTab(); + nTab = 1; Firstbuf = Currentbuf = newbuf; + } else { Currentbuf->nextBuffer = newbuf; Currentbuf = newbuf; @@ -914,7 +923,7 @@ MAIN(int argc, char **argv, char **envp) w3m_exit(0); } - if (!Firstbuf || Firstbuf == NO_BUFFER) { + if (!FirstTab || !Firstbuf || Firstbuf == NO_BUFFER) { if (newbuf == NO_BUFFER) { if (fmInitialized) inputChar("Hit any key to quit w3m:"); @@ -1313,7 +1322,8 @@ nscroll(int n, int mode) } else { tlnum = Currentbuf->topLine->linenumber; - llnum = Currentbuf->topLine->linenumber + LASTLINE - 1; + llnum = Currentbuf->topLine->linenumber + LASTLINE - Currentbuf->rootY + - 1; #ifdef NEXTPAGE_TOPLINE if (nextpage_topline) diff_n = 0; @@ -1336,10 +1346,11 @@ pgFore(void) { #ifdef VI_PREC_NUM if (vi_prec_num) - nscroll(searchKeyNum() * (LASTLINE - 1), B_NORMAL); + nscroll(searchKeyNum() * (LASTLINE - Currentbuf->rootY - 1), B_NORMAL); else #endif - nscroll(prec_num ? searchKeyNum() : searchKeyNum() * (LASTLINE - 1), + nscroll(prec_num ? searchKeyNum() : searchKeyNum() + * (LASTLINE - Currentbuf->rootY - 1), prec_num ? B_SCROLL : B_NORMAL); } @@ -1349,10 +1360,11 @@ pgBack(void) { #ifdef VI_PREC_NUM if (vi_prec_num) - nscroll(-searchKeyNum() * (LASTLINE - 1), B_NORMAL); + nscroll(-searchKeyNum() * (LASTLINE - Currentbuf->rootY - 1), B_NORMAL); else #endif - nscroll(-(prec_num ? searchKeyNum() : searchKeyNum() * (LASTLINE - 1)), + nscroll(-(prec_num ? searchKeyNum() : searchKeyNum() + * (LASTLINE - Currentbuf->rootY - 1)), prec_num ? B_SCROLL : B_NORMAL); } @@ -1377,7 +1389,7 @@ ctrCsrV(void) int offsety; if (Currentbuf->firstLine == NULL) return; - offsety = LASTLINE / 2 - Currentbuf->cursorY; + offsety = (LASTLINE - Currentbuf->rootY) / 2 - Currentbuf->cursorY; if (offsety != 0) { #if 0 Currentbuf->currentLine = lineSkip(Currentbuf, @@ -1971,7 +1983,7 @@ _movD(int n) void movD(void) { - _movD((LASTLINE + 1) / 2); + _movD((LASTLINE - Currentbuf->rootY + 1) / 2); } void @@ -1995,7 +2007,7 @@ _movU(int n) void movU(void) { - _movU((LASTLINE + 1) / 2); + _movU((LASTLINE - Currentbuf->rootY + 1) / 2); } void @@ -2285,8 +2297,8 @@ _goLine(char *l) } else if (*l == '$') { Currentbuf->topLine = - lineSkip(Currentbuf, Currentbuf->lastLine, -(LASTLINE + 1) / 2, - TRUE); + lineSkip(Currentbuf, Currentbuf->lastLine, + -(LASTLINE - Currentbuf->rootY + 1) / 2, TRUE); Currentbuf->currentLine = Currentbuf->lastLine; } else @@ -2441,7 +2453,8 @@ _mark(void) return; l = Currentbuf->currentLine; l->propBuf[Currentbuf->pos] ^= PE_MARK; - redrawLine(Currentbuf, l, l->linenumber - Currentbuf->topLine->linenumber); + redrawLine(Currentbuf, l, l->linenumber - Currentbuf->topLine->linenumber + + Currentbuf->rootY); } /* Go to next mark */ @@ -2766,6 +2779,21 @@ followA(void) if (map) url = Sprintf("%s?%d,%d", a->url, x, y)->ptr; #endif + + if (check_target && open_tab_blank && a->target && + (!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) { + Buffer *buf; + + _newT(); + buf = Currentbuf; + loadLink(url, a->target, a->referer, NULL); + if (buf != Currentbuf) + delBuffer(buf); + else + deleteTab(CurrentTab); + displayBuffer(Currentbuf, B_NORMAL); + return; + } loadLink(url, a->target, a->referer, NULL); displayBuffer(Currentbuf, B_NORMAL); } @@ -3123,7 +3151,7 @@ _followForm(int submit) if (!formChooseOptionByMenu(fi, Currentbuf->cursorX - Currentbuf->pos + a->start.pos + Currentbuf->rootX, - Currentbuf->cursorY)) + Currentbuf->cursorY + Currentbuf->rootY)) break; formUpdateBuffer(a, Currentbuf, fi); if (fi->parent->nitems == 1) @@ -3241,12 +3269,12 @@ drawAnchorCursor0(Buffer *buf, int hseq, int prevhseq, int tline, int eline, } } if (active) - redrawLineRegion(buf, l, l->linenumber - tline, + redrawLineRegion(buf, l, l->linenumber - tline + buf->rootY, an->start.pos, an->end.pos); } else if (prevhseq >= 0 && an->hseq == prevhseq) { if (active) - redrawLineRegion(buf, l, l->linenumber - tline, + redrawLineRegion(buf, l, l->linenumber - tline + buf->rootY, an->start.pos, an->end.pos); } } @@ -3271,7 +3299,7 @@ drawAnchorCursor(Buffer *buf) else hseq = -1; tline = buf->topLine->linenumber; - eline = tline + LASTLINE; + eline = tline + LASTLINE - buf->rootY; prevhseq = buf->hmarklist->prevhseq; drawAnchorCursor0(buf, hseq, prevhseq, tline, eline, 1); @@ -3652,7 +3680,12 @@ backBf(void) Buffer *buf = Currentbuf->linkBuffer[LB_N_FRAME]; if (!checkBackBuffer(Currentbuf)) { - disp_message("Can't back...", TRUE); + if (close_tab_back && nTab >= 1) { + deleteTab(CurrentTab); + displayBuffer(Currentbuf, B_FORCE_REDRAW); + } + else + disp_message("Can't back...", TRUE); return; } @@ -3938,23 +3971,39 @@ void follow_map(struct parsed_tagarg *arg) { #ifdef MENU_MAP - Anchor *a; - char *url; - int x; + Anchor *an; + MapArea *a; + int x, y; ParsedURL p_url; - a = retrieveCurrentImg(Currentbuf); + an = retrieveCurrentImg(Currentbuf); x = Currentbuf->cursorX + Currentbuf->rootX; - url = follow_map_menu(Currentbuf, arg, a, x, Currentbuf->cursorY); - if (url == NULL || *url == '\0') + y = Currentbuf->cursorY + Currentbuf->rootY; + a = follow_map_menu(Currentbuf, arg, an, x, y); + if (a == NULL || a->url == NULL || *(a->url) == '\0') return; - if (*url == '#') { - gotoLabel(url + 1); + if (*(a->url) == '#') { + gotoLabel(a->url + 1); return; } - parseURL2(url, &p_url, baseURL(Currentbuf)); + parseURL2(a->url, &p_url, baseURL(Currentbuf)); pushHashHist(URLHist, parsedURL2Str(&p_url)->ptr); - cmd_loadURL(url, baseURL(Currentbuf), + if (check_target && open_tab_blank && a->target && + (!strcasecmp(a->target, "_new") || !strcasecmp(a->target, "_blank"))) { + Buffer *buf; + + _newT(); + buf = Currentbuf; + cmd_loadURL(a->url, baseURL(Currentbuf), + parsedURL2Str(&Currentbuf->currentURL)->ptr); + if (buf != Currentbuf) + delBuffer(buf); + else + deleteTab(CurrentTab); + displayBuffer(Currentbuf, B_NORMAL); + return; + } + cmd_loadURL(a->url, baseURL(Currentbuf), parsedURL2Str(&Currentbuf->currentURL)->ptr); #else Buffer *buf; @@ -4629,15 +4678,76 @@ stopI(void) #ifdef USE_MOUSE +static TabBuffer * +posTab(int x, int y) +{ + TabBuffer *t; + int i, n, col = COLS - 2; + + if (col <= 0) + return NULL; + n = x * N_TAB / col + y * N_TAB; + for (t = FirstTab, i = 0; t && i < n; t = t->nextTab, i++) + ; + return t; +} + static void process_mouse(int btn, int x, int y) { int delta_x, delta_y, i; static int press_btn = MOUSE_BTN_RESET, press_x, press_y; + TabBuffer *t; + int ny = 0; + if (nTab > 1) + ny = (nTab - 1) / N_TAB + 1; if (btn == MOUSE_BTN_UP) { switch (press_btn) { case MOUSE_BTN1_DOWN: + if (nTab > 1 && y < ny) { + if (press_y == y && press_x == x) { + if (y == 0 && x >= COLS - 2) { + deleteTab(CurrentTab); + displayBuffer(Currentbuf, B_NORMAL); + } + t = posTab(x, y); + if (t) + CurrentTab = t; + displayBuffer(Currentbuf, B_FORCE_REDRAW); + return; + } + else if (press_y < ny) { + moveTab(posTab(press_x, press_y), posTab(x, y), + (press_y == y) ? (press_x < x) : (press_y < y)); + return; + } + else if (press_x >= Currentbuf->rootX) { + Buffer *buf = Currentbuf; + int cx = Currentbuf->cursorX, cy = Currentbuf->cursorY; + + t = posTab(x, y); + if (t == NULL) + return; + cursorXY(Currentbuf, press_x - Currentbuf->rootX, + press_y - Currentbuf->rootY); + if (Currentbuf->cursorY == press_y - Currentbuf->rootY && + (Currentbuf->cursorX == press_x - Currentbuf->rootX +#ifdef JP_CHARSET + || (Currentbuf->currentLine != NULL && + (Currentbuf->currentLine->propBuf[Currentbuf->pos] + & PC_KANJI1) && Currentbuf->cursorX == press_x + - Currentbuf->rootX - 1) +#endif + )) { + onA(); + followTab(t); + } + if (buf == Currentbuf) + cursorXY(Currentbuf, cx, cy); + } + return; + } if (press_x != x || press_y != y) { delta_x = x - press_x; delta_y = y - press_y; @@ -4685,7 +4795,7 @@ process_mouse(int btn, int x, int y) } return; } - if (y == Currentbuf->cursorY && + if (y == Currentbuf->cursorY + Currentbuf->rootY && (x == Currentbuf->cursorX + Currentbuf->rootX #ifdef JP_CHARSET || (Currentbuf->currentLine != NULL && @@ -4698,18 +4808,30 @@ process_mouse(int btn, int x, int y) return; } if (x >= Currentbuf->rootX) - cursorXY(Currentbuf, x - Currentbuf->rootX, y); + cursorXY(Currentbuf, x - Currentbuf->rootX, + y - Currentbuf->rootY); displayBuffer(Currentbuf, B_NORMAL); } break; case MOUSE_BTN2_DOWN: + if (nTab > 1 && y < ny) { + if (press_y == y && press_x == x) { + t = posTab(x, y); + if (t) { + deleteTab(t); + displayBuffer(Currentbuf, B_FORCE_REDRAW); + } + } + return; + } backBf(); break; case MOUSE_BTN3_DOWN: #ifdef USE_MENU - if (x >= Currentbuf->rootX) - cursorXY(Currentbuf, x - Currentbuf->rootX, y); + if (x >= Currentbuf->rootX && y > ny) + cursorXY(Currentbuf, x - Currentbuf->rootX, + y - Currentbuf->rootY); onA(); mainMenu(x, y); #endif /* USE_MENU */ @@ -5023,10 +5145,13 @@ deleteFiles() { Buffer *buf; char *f; - while (Firstbuf && Firstbuf != NO_BUFFER) { - buf = Firstbuf->nextBuffer; - discardBuffer(Firstbuf); - Firstbuf = buf; + + for (CurrentTab = FirstTab; CurrentTab; CurrentTab = CurrentTab->nextTab) { + while (Firstbuf && Firstbuf != NO_BUFFER) { + buf = Firstbuf->nextBuffer; + discardBuffer(Firstbuf); + Firstbuf = buf; + } } while ((f = popText(fileToDelete)) != NULL) unlink(f); @@ -5257,3 +5382,316 @@ defKey(void) setKeymap(allocStr(data, -1), -1, TRUE); displayBuffer(Currentbuf, B_NORMAL); } + +TabBuffer * +newTab(void) +{ + TabBuffer *n; + + n = New(TabBuffer); + if (n == NULL) + return NULL; + n->nextTab = NULL; + n->currentBuffer = NULL; + n->firstBuffer = NULL; + return n; +} + +static void +_newT(void) +{ + TabBuffer *tag; + Buffer *buf; + int i; + + tag = newTab(); + if (! tag) + return; + + buf = newBuffer(Currentbuf->width); + copyBuffer(buf, Currentbuf); + buf->nextBuffer = NULL; + for (i = 0; i < MAX_LB; i++) + buf->linkBuffer[i] = NULL; + (*buf->clone)++; + tag->firstBuffer = tag->currentBuffer = buf; + + tag->nextTab = CurrentTab->nextTab; + tag->prevTab = CurrentTab; + if (CurrentTab->nextTab) + CurrentTab->nextTab->prevTab = tag; + else + LastTab = tag; + CurrentTab->nextTab = tag; + CurrentTab = tag; + nTab++; +} + +void +newT(void) +{ + _newT(); + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +TabBuffer * +numTab(int n) +{ + TabBuffer *tab; + int i; + + if (n == 0) + return CurrentTab; + if (n == 1) + return FirstTab; + if (nTab <= 1) + return NULL; + for (tab = FirstTab, i = 1; tab && i < n; tab = tab->nextTab, i++) + ; + return tab; +} + +TabBuffer * +deleteTab(TabBuffer *tab) +{ + Buffer *buf, *next; + + if (nTab <= 1) + return FirstTab; + if (tab->prevTab) { + if (tab->nextTab) + tab->nextTab->prevTab = tab->prevTab; + else + LastTab = tab->prevTab; + tab->prevTab->nextTab = tab->nextTab; + if (tab == CurrentTab) + CurrentTab = tab->prevTab; + } + else { /* tab == FirstTab */ + tab->nextTab->prevTab = NULL; + FirstTab = tab->nextTab; + if (tab == CurrentTab) + CurrentTab = tab->nextTab; + } + nTab--; + buf = tab->firstBuffer; + while (buf && buf != NO_BUFFER) { + next = buf->nextBuffer; + discardBuffer(buf); + buf = next; + } + return FirstTab; +} + +void +closeT(void) +{ + TabBuffer *tab; + + if (nTab <= 1) + return; + if (prec_num) + tab = numTab(PREC_NUM); + else + tab = CurrentTab; + if (tab) + deleteTab(tab); + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +nextT(void) +{ + int i; + + if (nTab <= 1) + return; + for (i = 0; i < PREC_NUM; i++) { + if (CurrentTab->nextTab) + CurrentTab = CurrentTab->nextTab; + else + CurrentTab = FirstTab; + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +prevT(void) +{ + int i; + + if (nTab <= 1) + return; + for (i = 0; i < PREC_NUM; i++) { + if (CurrentTab->prevTab) + CurrentTab = CurrentTab->prevTab; + else + CurrentTab = LastTab; + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +followTab(TabBuffer *tab) +{ + Buffer *buf; + Anchor *a; + +#ifdef USE_IMAGE + a = retrieveCurrentImg(Currentbuf); + if (! (a && a->image && a->image->map)) +#endif + a = retrieveCurrentAnchor(Currentbuf); + if (a == NULL) + return; + + if (tab == CurrentTab) { + check_target = FALSE; + followA(); + check_target = TRUE; + return; + } + _newT(); + buf = Currentbuf; + check_target = FALSE; + followA(); + check_target = TRUE; + if (tab == NULL) { + if (buf != Currentbuf) + delBuffer(buf); + else + deleteTab(CurrentTab); + } + else if (buf != Currentbuf) { + /* buf <- p <- ... <- Currentbuf = c */ + Buffer *c, *p; + + c = Currentbuf; + p = prevBuffer(c, buf); + p->nextBuffer = NULL; + Firstbuf = buf; + deleteTab(CurrentTab); + CurrentTab = tab; + for (buf = p; buf; buf = p) { + p = prevBuffer(c, buf); + pushBuffer(buf); + } + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +tabA(void) +{ + followTab(prec_num ? numTab(PREC_NUM) : NULL); +} + +static void +tabURL0(TabBuffer *tab, char *prompt, int relative) +{ + Buffer *buf; + + if (tab == CurrentTab) { + goURL0(prompt, relative); + return; + } + _newT(); + buf = Currentbuf; + goURL0(prompt, relative); + if (tab == NULL) { + if (buf != Currentbuf) + delBuffer(buf); + else + deleteTab(CurrentTab); + } + else if (buf != Currentbuf) { + /* buf <- p <- ... <- Currentbuf = c */ + Buffer *c, *p; + + c = Currentbuf; + p = prevBuffer(c, buf); + p->nextBuffer = NULL; + Firstbuf = buf; + deleteTab(CurrentTab); + CurrentTab = tab; + for (buf = p; buf; buf = p) { + p = prevBuffer(c, buf); + pushBuffer(buf); + } + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +tabURL(void) +{ + tabURL0(prec_num ? numTab(PREC_NUM) : NULL, + "Goto URL on new tab: ", FALSE); +} + +void +tabrURL(void) +{ + tabURL0(prec_num ? numTab(PREC_NUM) : NULL, + "Goto relative URL on new tab: ", TRUE); +} + +void +moveTab(TabBuffer *t, TabBuffer *t2, int right) +{ + if (!t || !t2 || t == t2) + return; + if (t->prevTab) { + if (t->nextTab) + t->nextTab->prevTab = t->prevTab; + else + LastTab = t->prevTab; + t->prevTab->nextTab = t->nextTab; + } + else { + t->nextTab->prevTab = NULL; + FirstTab = t->nextTab; + } + if (right) { + t->nextTab = t2->nextTab; + t->prevTab = t2; + if (t2->nextTab) + t2->nextTab->prevTab = t; + else + LastTab = t; + t2->nextTab = t; + } + else { + t->prevTab = t2->prevTab; + t->nextTab = t2; + if (t2->prevTab) + t2->prevTab->nextTab = t; + else + FirstTab = t; + t2->prevTab = t; + } + displayBuffer(Currentbuf, B_FORCE_REDRAW); +} + +void +tabR(void) +{ + TabBuffer *tab; + int i; + + for (tab = CurrentTab, i = 0; tab && i < PREC_NUM; tab = tab->nextTab, i++) + ; + moveTab(CurrentTab, tab ? tab : LastTab, TRUE); +} + +void +tabL(void) +{ + TabBuffer *tab; + int i; + + for (tab = CurrentTab, i = 0; tab && i < PREC_NUM; tab = tab->prevTab, i++) + ; + moveTab(CurrentTab, tab ? tab : FirstTab, FALSE); +} + diff --git a/map.c b/map.c @@ -59,7 +59,7 @@ inMapArea(MapArea * a, int x, int y) } #endif -char * +MapArea * follow_map_menu(Buffer *buf, struct parsed_tagarg *arg, Anchor *a_img, int x, int y) { @@ -122,7 +122,7 @@ follow_map_menu(Buffer *buf, struct parsed_tagarg *arg, Anchor *a_img, int x, if (selected >= 0) { for (i = 0, al = ml->area->first; al != NULL; i++, al = al->next) { if (al->ptr && i == selected) - return ((MapArea *) al->ptr)->url; + return (MapArea *) al->ptr; } } return NULL; @@ -193,7 +193,7 @@ getMapXY(Buffer *buf, Anchor *a, int *x, int *y) #endif MapArea * -newMapArea(char *url, char *alt, char *shape, char *coords) +newMapArea(char *url, char *target, char *alt, char *shape, char *coords) { MapArea *a = New(MapArea); #ifdef MENU_MAP @@ -204,6 +204,7 @@ newMapArea(char *url, char *alt, char *shape, char *coords) #endif a->url = url; + a->target = target; a->alt = alt ? alt : ""; #ifdef MENU_MAP #ifdef USE_IMAGE diff --git a/menu.c b/menu.c @@ -276,6 +276,16 @@ static int smDelBuf(char c); /* --- SelectMenu (END) --- */ +/* --- SelTabMenu --- */ + +static Menu SelTabMenu; +static int SelTabV = 0; +static void initSelTabMenu(void); +static void smChTab(void); +static int smDelTab(char c); + +/* --- SelTabMenu (END) --- */ + /* --- MainMenu --- */ static Menu MainMenu; @@ -284,12 +294,14 @@ static MenuItem MainMenuItem[] = { /* type label variabel value func popup keys data */ {MENU_FUNC, "戻る (b)", NULL, 0, backBf, NULL, "b", NULL}, {MENU_POPUP, "バッファ選択 (s)", NULL, 0, NULL, &SelectMenu, "s", NULL}, + {MENU_POPUP, "タブ選択 (t)", NULL, 0, NULL, &SelTabMenu, "tT", NULL}, {MENU_FUNC, "ソースを表示 (v)", NULL, 0, vwSrc, NULL, "vV", NULL}, {MENU_FUNC, "ソースを編集 (e)", NULL, 0, editBf, NULL, "eE", NULL}, {MENU_FUNC, "ソースを保存 (S)", NULL, 0, svSrc, NULL, "S", NULL}, {MENU_FUNC, "再読み込み (r)", NULL, 0, reload, NULL, "rR", NULL}, {MENU_NOP, "────────", NULL, 0, nulcmd, NULL, "", NULL}, {MENU_FUNC, "リンクを表示 (a)", NULL, 0, followA, NULL, "a", NULL}, + {MENU_FUNC, "新タブで表示 (n)", NULL, 0, tabA, NULL, "nN", NULL}, {MENU_FUNC, "リンクを保存 (A)", NULL, 0, svA, NULL, "A", NULL}, {MENU_FUNC, "画像を表示 (i)", NULL, 0, followI, NULL, "i", NULL}, {MENU_FUNC, "画像を保存 (I)", NULL, 0, svI, NULL, "I", NULL}, @@ -307,12 +319,14 @@ static MenuItem MainMenuItem[] = { /* type label variable value func popup keys data */ {MENU_FUNC, " Back (b) ", NULL, 0, backBf, NULL, "b", NULL}, {MENU_POPUP, " Select Buffer(s) ", NULL, 0, NULL, &SelectMenu, "s", NULL}, + {MENU_POPUP, " Select Tab (t) ", NULL, 0, NULL, &SelTabMenu, "tT", NULL}, {MENU_FUNC, " View Source (v) ", NULL, 0, vwSrc, NULL, "vV", NULL}, {MENU_FUNC, " Edit Source (e) ", NULL, 0, editBf, NULL, "eE", NULL}, {MENU_FUNC, " Save Source (S) ", NULL, 0, svSrc, NULL, "S", NULL}, {MENU_FUNC, " Reload (r) ", NULL, 0, reload, NULL, "rR", NULL}, {MENU_NOP, " ---------------- ", NULL, 0, nulcmd, NULL, "", NULL}, {MENU_FUNC, " Go Link (a) ", NULL, 0, followA, NULL, "a", NULL}, + {MENU_FUNC, " on New Tab (n) ", NULL, 0, tabA, NULL, "nN", NULL}, {MENU_FUNC, " Save Link (A) ", NULL, 0, svA, NULL, "A", NULL}, {MENU_FUNC, " View Image (i) ", NULL, 0, followI, NULL, "i", NULL}, {MENU_FUNC, " Save Image (I) ", NULL, 0, svI, NULL, "I", NULL}, @@ -1209,9 +1223,10 @@ void popupMenu(int x, int y, Menu *menu) { initSelectMenu(); + initSelTabMenu(); menu->cursorX = Currentbuf->cursorX + Currentbuf->rootX; - menu->cursorY = Currentbuf->cursorY; + menu->cursorY = Currentbuf->cursorY + Currentbuf->rootY; menu->x = x + FRAME_WIDTH + 1; menu->y = y + 2; @@ -1238,8 +1253,8 @@ mainMn(void) return; menu = w3mMenuList[n].menu; } - popupMenu(Currentbuf->cursorX + Currentbuf->rootX, Currentbuf->cursorY, - menu); + popupMenu(Currentbuf->cursorX + Currentbuf->rootX, + Currentbuf->cursorY + Currentbuf->rootY, menu); } /* --- MainMenu (END) --- */ @@ -1249,7 +1264,8 @@ mainMn(void) void selMn(void) { - popupMenu(Currentbuf->cursorX, Currentbuf->cursorY, &SelectMenu); + popupMenu(Currentbuf->cursorX + Currentbuf->rootX, + Currentbuf->cursorY + Currentbuf->rootY, &SelectMenu); } static void @@ -1312,7 +1328,7 @@ initSelectMenu(void) new_option_menu(&SelectMenu, label, &SelectV, smChBuf); SelectMenu.initial = SelectV; SelectMenu.cursorX = Currentbuf->cursorX + Currentbuf->rootX; - SelectMenu.cursorY = Currentbuf->cursorY; + SelectMenu.cursorY = Currentbuf->cursorY + Currentbuf->rootY; SelectMenu.keymap['D'] = smDelBuf; SelectMenu.item[nitem].type = MENU_NOP; } @@ -1380,6 +1396,140 @@ smDelBuf(char c) /* --- SelectMenu (END) --- */ +/* --- SelTabMenu --- */ + +void +tabMn(void) +{ + popupMenu(Currentbuf->cursorX + Currentbuf->rootX, + Currentbuf->cursorY + Currentbuf->rootY, &SelTabMenu); +} + +static void +initSelTabMenu(void) +{ + int i, nitem, len = 0, l; + TabBuffer *tab; + Buffer *buf; + Str str; + char **label; + static char *comment = " SPC for select / D for delete tab "; + + SelTabV = -1; + for (i = 0, tab = LastTab; tab != NULL; i++, tab = tab->prevTab) { + if (tab == CurrentTab) + SelTabV = i; + } + nitem = i; + + label = New_N(char *, nitem + 2); + for (i = 0, tab = LastTab; i < nitem; i++, tab = tab->prevTab) { + buf = tab->currentBuffer; + str = Sprintf("<%s>", buf->buffername); + if (buf->filename != NULL) { + switch (buf->currentURL.scheme) { + case SCM_LOCAL: + case SCM_LOCAL_CGI: + if (strcmp(buf->currentURL.file, "-")) { + Strcat_char(str, ' '); + Strcat_charp(str, + conv_from_system(buf->currentURL.real_file)); + } + break; + /* case SCM_UNKNOWN: */ + case SCM_MISSING: + break; + default: + Strcat_char(str, ' '); + Strcat(str, parsedURL2Str(&buf->currentURL)); + break; + } + } + label[i] = str->ptr; + if (len < str->length) + len = str->length; + } + l = strlen(comment); + if (len < l + 4) + len = l + 4; + if (len > COLS - 2 * FRAME_WIDTH) + len = COLS - 2 * FRAME_WIDTH; + len = (len > 1) ? ((len - l + 1) / 2) : 0; + str = Strnew(); + for (i = 0; i < len; i++) + Strcat_char(str, '-'); + Strcat_charp(str, comment); + for (i = 0; i < len; i++) + Strcat_char(str, '-'); + label[nitem] = str->ptr; + label[nitem + 1] = NULL; + + new_option_menu(&SelTabMenu, label, &SelTabV, smChTab); + SelTabMenu.initial = SelTabV; + SelTabMenu.cursorX = Currentbuf->cursorX + Currentbuf->rootX; + SelTabMenu.cursorY = Currentbuf->cursorY + Currentbuf->rootY; + SelTabMenu.keymap['D'] = smDelTab; + SelTabMenu.item[nitem].type = MENU_NOP; +} + +static void +smChTab(void) +{ + int i; + TabBuffer *tab; + Buffer *buf; + + if (SelTabV < 0 || SelTabV >= SelTabMenu.nitem) + return; + for (i = 0, tab = LastTab; i < SelTabV && tab != NULL; + i++, tab = tab->prevTab) ; + CurrentTab = tab; + for (tab = LastTab; tab != NULL; tab = tab->prevTab) { + if (tab == CurrentTab) + continue; + buf = tab->currentBuffer; +#ifdef USE_IMAGE + deleteImage(buf); +#endif + if (clear_buffer) + tmpClearBuffer(buf); + } +} + +static int +smDelTab(char c) +{ + int i, x, y, mselect; + TabBuffer *tab; + + if (CurrentMenu->select < 0 || CurrentMenu->select >= SelTabMenu.nitem) + return (MENU_NOTHING); + for (i = 0, tab = LastTab; i < CurrentMenu->select && tab != NULL; + i++, tab = tab->prevTab) ; + deleteTab(tab); + + x = CurrentMenu->x; + y = CurrentMenu->y; + mselect = CurrentMenu->select; + + initSelTabMenu(); + + CurrentMenu->x = x; + CurrentMenu->y = y; + + geom_menu(CurrentMenu, x, y, 0); + + CurrentMenu->select = (mselect <= CurrentMenu->nitem - 2) ? mselect + : (CurrentMenu->nitem - 2); + + displayBuffer(Currentbuf, B_FORCE_REDRAW); + draw_all_menu(CurrentMenu); + select_menu(CurrentMenu, CurrentMenu->select); + return (MENU_NOTHING); +} + +/* --- SelectMenu (END) --- */ + /* --- OptionMenu --- */ void diff --git a/proto.h b/proto.h @@ -119,6 +119,16 @@ extern void setAlarmEvent(int sec, short status, int cmd, void *data); #endif extern void reinit(void); extern void defKey(void); +extern void newT(void); +extern void closeT(void); +extern void nextT(void); +extern void prevT(void); +extern void tabA(void); +extern void tabURL(void); +extern void tabrURL(void); +extern void tabR(void); +extern void tabL(void); + extern int currentLn(Buffer *buf); extern void tmpClearBuffer(Buffer *buf); extern char *filename_extension(char *patch, int is_url); @@ -209,6 +219,8 @@ extern char *inputAnswer(char *prompt); extern int matchattr(char *p, char *attr, int len, Str *value); extern void readHeader(URLFile *uf, Buffer *newBuf, int thru, ParsedURL *pu); extern char *checkHeader(Buffer *buf, char *field); +extern TabBuffer *newTab(void); +extern TabBuffer *deleteTab(TabBuffer *tab); extern Buffer *newBuffer(int width); extern Buffer *nullBuffer(void); extern void clearBuffer(Buffer *buf); @@ -340,15 +352,16 @@ extern void form_write_from_file(FILE * f, char *boundary, char *name, char *filename, char *file); extern void follow_map(struct parsed_tagarg *arg); #ifdef MENU_MAP -extern char *follow_map_menu(Buffer *buf, struct parsed_tagarg *arg, - Anchor *a_img, int x, int y); +extern MapArea *follow_map_menu(Buffer *buf, struct parsed_tagarg *arg, + Anchor *a_img, int x, int y); #else extern Buffer *follow_map_panel(Buffer *buf, struct parsed_tagarg *arg); #endif #ifdef USE_IMAGE extern int getMapXY(Buffer *buf, Anchor *a, int *x, int *y); #endif -extern MapArea *newMapArea(char *url, char *alt, char *shape, char *coords); +extern MapArea *newMapArea(char *url, char *target, char *alt, char *shape, + char *coords); extern Buffer *page_info_panel(Buffer *buf); extern struct frame_body *newFrame(struct parsed_tag *tag, Buffer *buf); extern struct frameset *newFrameSet(struct parsed_tag *tag); @@ -624,6 +637,7 @@ extern void popupMenu(int x, int y, Menu *menu); extern void mainMenu(int x, int y); extern void mainMn(void); extern void selMn(void); +extern void tabMn(void); extern void optionMenu(int x, int y, char **label, int *variable, int initial, void (*func) ()); extern void initMenu(void); diff --git a/rc.c b/rc.c @@ -65,6 +65,7 @@ static char *config_file = NULL; #define CMT_FRAME "フレームの自動表示" #define CMT_ARGV_IS_URL "scheme のない引数も URL とみなす" #define CMT_TSELF "targetが未指定の場合に_selfを使用する" +#define CMT_OPEN_TAB_BLANK "targetが_blankか_newの場合は新しいタブで開く" #define CMT_DISPLINK "リンク先の自動表示" #define CMT_DISPLINEINFO "現在の行番号の表示" #define CMT_DISP_IMAGE "インライン画像を表示" @@ -102,6 +103,7 @@ static char *config_file = NULL; #define CMT_PDROOT "/~user で表されるディレクトリ" #define CMT_CGIBIN "/cgi-bin で表されるディレクトリ" #define CMT_CONFIRM_QQ "q での終了時に確認する" +#define CMT_CLOSE_TAB_BACK "戻る時にバッファが最後ならタブを閉じる" #ifdef USE_MARK #define CMT_USE_MARK "マーク機能を有効にする" #endif @@ -207,6 +209,7 @@ static char *config_file = NULL; #define CMT_FRAME "Render frames automatically" #define CMT_ARGV_IS_URL "Treat argument without scheme as URL" #define CMT_TSELF "Use _self as default target" +#define CMT_OPEN_TAB_BLANK "Open link on new tab if target is _blank or _new" #define CMT_DISPLINK "Display link URL automatically" #define CMT_DISPLINEINFO "Display current line number" #define CMT_DISP_IMAGE "Display inline images" @@ -244,6 +247,7 @@ static char *config_file = NULL; #define CMT_PDROOT "Directory corresponding to /~user" #define CMT_CGIBIN "Directory corresponding to /cgi-bin" #define CMT_CONFIRM_QQ "Confirm when quitting with q" +#define CMT_CLOSE_TAB_BACK "Close tab if buffer is last when back" #ifdef USE_MARK #define CMT_USE_MARK "Enable mark operations" #endif @@ -463,6 +467,8 @@ struct param_ptr params1[] = { #endif /* JP_CHARSET */ {"frame", P_CHARINT, PI_ONOFF, (void *)&RenderFrame, CMT_FRAME, NULL}, {"target_self", P_CHARINT, PI_ONOFF, (void *)&TargetSelf, CMT_TSELF, NULL}, + {"open_tab_blank", P_INT, PI_ONOFF, (void *)&open_tab_blank, + CMT_OPEN_TAB_BLANK, NULL}, {"display_link", P_INT, PI_ONOFF, (void *)&displayLink, CMT_DISPLINK, NULL}, {"display_lineinfo", P_INT, PI_ONOFF, (void *)&displayLineInfo, @@ -551,6 +557,8 @@ struct param_ptr params3[] = { #endif /* USE_HISTORY */ {"confirm_qq", P_INT, PI_ONOFF, (void *)&confirm_on_quit, CMT_CONFIRM_QQ, NULL}, + {"close_tab_back", P_INT, PI_ONOFF, (void *)&close_tab_back, + CMT_CLOSE_TAB_BACK, NULL}, #ifdef USE_MARK {"mark", P_INT, PI_ONOFF, (void *)&use_mark, CMT_USE_MARK, NULL}, #endif