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:
M | ChangeLog | | | 123 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | display.c | | | 61 | ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- |
M | doc-jp/README.func | | | 10 | ++++++++++ |
M | doc/README.func | | | 10 | ++++++++++ |
M | etc.c | | | 8 | ++++---- |
M | file.c | | | 6 | ++++-- |
M | fm.h | | | 23 | ++++++++++++++++++++++- |
M | funcname.tab | | | 10 | ++++++++++ |
M | html.c | | | 4 | ++-- |
M | image.c | | | 2 | +- |
M | main.c | | | 514 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ |
M | map.c | | | 7 | ++++--- |
M | menu.c | | | 160 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
M | proto.h | | | 20 | +++++++++++++++++--- |
M | rc.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