* NEWS: w3m-img merge
* .cvsignore: add w3mimgdisplay, w3mimgsize
* XMakefile: add image.c to SRCS
	     add image.o to OBJS
             add IMGDISPLAY, IMGSIZE
* config.h.dist: USE_IMAGE, IMGSIZE, IMGDISPLAY
* configure: add find_imlib
		ask use_image
	(config.h) add $imgtarget to EXT_TARGETS
		   $def_use_image
		   IMGSIZE, IMGDISPLAY
* fm.h (MAX_IMAGE): added
* fm.h (DEFAULT_PIXEL_PER_CHAR): fix for USE_IMAGE
* fm.h (DEFAULT_PIXEL_PER_LINE): added
* fm.h (B_REDRAW_IMAGE): added
* fm.h (IMG_FLAG_SKIP): added
* fm.h (IMG_FLAG_AUTO): added
* fm.h (IMG_FLAG_START): added
* fm.h (IMG_FLAG_STOP): added
* fm.h (IMG_FLAG_NEXT): added
* fm.h (IMG_FLAG_UNLOADED): added
* fm.h (IMG_FLAG_LOADED): added
* fm.h (IMG_FLAG_ERROR): added
* fm.h (MapArea): added
* fm.h (MapList): s/urls/alts/, add area
* fm.h (ImageCache): added
* fm.h (Image): added
* fm.h (Anchor): add image
* fm.h (Buffer): add imarklist, image_flag, need_reshape
* fm.h (RG_FRAME_SRC): added
* fm.h (ALIGN_MIDDLE): added
* fm.h (ALIGN_TOP): added
* fm.h (ALIGN_BOTTOM): added
* fm.h (QuietMessage): added
* fm.h (Imgdisplay): added
* fm.h (Imgsize): added
* fm.h (activeImage): added
* fm.h (displayImage): added
* fm.h (autoImage): added
* fm.h (useExtImageViewer): added
* fm.h (image_source): added
* fm.h (view_unseenobject): change default if USE_IMAGE
* fm.h (set_pixel_per_char): added
* fm.h (pixel_per_line): added
* fm.h (set_pixel_per_line): added
* fm.h (image_scale): added
* proto.h (dispI): added
* proto.h (stopI): added
* proto.h (deleteImage): added
* proto.h (getAllImage): added
* proto.h (loadImage): added
* proto.h (getImage): added
* proto.h (getImageSize): added
* proto.h (process_img): add width arg
* proto.h (loadImageBuffer): added
* proto.h (follow_map_menu): add a_img arg
* proto.h (getMapXY): added
* proto.h (newMapArea): added
* proto.h (touch_cursor): added
* proto.h (cURLcode): added
* proto.h (initImage): added
* proto.h (termImage): added
* proto.h (addImage): added
* proto.h (drawImage): added
* proto.h (clearImage): added
* anchor.c (addMultirowsImg): added
* buffer.c (discardBuffer): deleteImage if USE_IMAGE
* buffer.c (reshapeBuffer): buf->need_reshape check
* display.c (fmTerm): if activeImage, stop load image
* display.c (fmInit): if displayImage, initImage
* display.c (image_touch): added
* display.c (draw_image_flag): added
* display.c (redrawLineImage): added
* display.c (displayBuffer): buf->need_reshape = TRUE
			mode == B_REDRAW_IMAGE
			image flag checks
			force redraw image in mode == B_REDRAW_IMAGE
			displayBuffer if need reshape
			drawImage
* display.c (redrawNLine): redrawLineImage
* display.c (redrawLineImage): added
* display.c (disp_message_nsec): return immediately if QuietMessage
* etc.c (reset_signals): ignore SIGUSR1
* file.c (frame_source): added
* file.c (_MoveFile): added
* file.c (cur_baseURL): added
* file.c (cur_document_code): added
* file.c (cur_iseq): added
* file.c (loadGeneralFile): fix fmInitialized and prevtrap checks
			save cur_baseURL
			image_source load
			loadImageBuffer for "image/*"
			frame_source flag
			fix b->type when proc is loadImageBuffer
* file.c (process_img): add width arg
		parse height and width attr, align
		fix for inline-image
* file.c (process_input): fix for form <input type="image">
* file.c (HTMLtagproc1): pass h_env->limit to process_img()
		fix <img_alt> for inline-image
		save cur_baseURL
* file.c (HTMLlineproc2body): fix <img_alt> for inline-image
* file.c (loadHTMLstream): fix for inline-image
		fix fmInitialized and prevtrap checks
		save cur_document_code
		save image_flag
* file.c (loadGopherDir): save cur_document_code
		fix fmInitialized and prevtrap checks
* file.c (loadImageBuffer): added for inline-image
* file.c (save2tmp): fix fmInitialized and prevtrap checks
* frame.c (frame_download_source): set RG_FRAME_SRC flag
		image check
* funcname.tab (DISPLAY_IMAGE): added
* funcname.tab (STOP_IMAGE): added
* html.c (ALST_IMG): add align, ismap
* html.c (ALST_AREA): add shape, coords
* html.c (ALST_IMG_ALT): add width, height, usemap, ismap, hseq,
			xoffset, yoffset, top_margin, bottom_margin
* html.c (AttrMap): add shape, coords, ismap, xoffset, yoffset
* html.h (ATTR_SHAPE): added
* html.h (ATTR_COORDS): added
* html.h (ATTR_ISMAP): added
* html.h (ATTR_XOFFSET): added
* html.h (ATTR_YOFFSET): added
* html.h (ATTR_TOP_MARGIN): added
* html.h (ATTR_BOTTOM_MARGIN): added
* html.h (SHAPE_UNKNOWN): added
* html.h (SHAPE_DEFAULT): added
* html.h (SHAPE_RECT): added
* html.h (SHAPE_CIRCLE): added
* html.h (SHAPE_POLY): added
* image.c: added
* main.c (fversion): add USE_IMAGE
* main.c (fusage): -ppl option
* main.c (MAIN): set_pixel_per_char if ppc specified
		-ppl option
		loadImage
* main.c (pushBuffer): deleteImage
* main.c (quitfm): termImage
* main.c (selBuf): deleteImage
* main.c (followA): fix for inline-image and map area
* main.c (query_from_followform): getMapXY()
* main.c (setOpt): displayBuffer B_REDRAW_IMAGE
* main.c (follow_map): fix calculate x, y
* main.c (dispI): added
* main.c (stopI): added
* map.c: include <math.h>
* map.c (inMapArea): added
* map.c (follow_map_menu): add a_img arg to handle inline-image
* map.c (follow_map_panel): use MapArea
* map.c (getMapXY): added
* map.c (newMapArea): added
* menu.c (smChBuf): deleteImage
* parsetagx.c (toAlign): align top, bottom, middle
* rc.c (P_SCALE): added
* rc.c (CMT_PIXEL_PER_LINE): added
* rc.c (CMT_DISP_IMAGE): added
* rc.c (CMT_AUTO_IMAGE): added
* rc.c (CMT_EXT_IMAGE_VIEWER): added
* rc.c (CMT_IMAGE_SCALE): added
* rc.c (CMT_IMGDISPLAY): added
* rc.c (CMT_IMGSIZE): added
* rc.c (show_param): P_PIXELS
* rc.c (set_param): P_PIXELS
* rc.c (sync_with_option): initImage
* rc.c (to_str): P_PIXELS
* table.c (feed_table_tag): fix <img> for inline-image
* tagtable.tab (image): added
* terms.c (wgetch): retry read when EINTR or EAGAIN
* terms.c (touch_cursor): added
* w3mimgdisplay.c: added
* w3mimgsize.c: added
* doc/README.func (DISPLAY_IMAGE): added
* doc/README.func (STOP_IMAGE): added
* doc/README.img: added
* doc-jp/README.func (DISPLAY_IMAGE): added
* doc-jp/README.func (STOP_IMAGE): added
* doc-jp/README.img: added
* scripts/w3mhelp.cgi.in: show dispI, stopI
* scripts/multipart/multipart.cgi.in: inline image support
From: Fumitoshi UKAI  <ukai@debian.or.jp>
		
	
		
			
				
	
	
		
			681 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			681 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* $Id: buffer.c,v 1.10 2002/01/31 17:54:49 ukai Exp $ */
 | |
| #include "fm.h"
 | |
| 
 | |
| #ifdef USE_MOUSE
 | |
| #ifdef USE_GPM
 | |
| #include <gpm.h>
 | |
| #endif
 | |
| #if defined(USE_GPM) || defined(USE_SYSMOUSE)
 | |
| extern int do_getch();
 | |
| #define getch()	do_getch()
 | |
| #endif				/* USE_GPM */
 | |
| #endif				/* USE_MOUSE */
 | |
| 
 | |
| #ifdef __EMX__
 | |
| #include <sys/kbdscan.h>
 | |
| #include <strings.h>
 | |
| #endif
 | |
| char *NullLine = "";
 | |
| Lineprop NullProp[] = { 0 };
 | |
| 
 | |
| /* 
 | |
|  * Buffer creation
 | |
|  */
 | |
| Buffer *
 | |
| newBuffer(int width)
 | |
| {
 | |
|     Buffer *n;
 | |
| 
 | |
|     n = New(Buffer);
 | |
|     if (n == NULL)
 | |
| 	return NULL;
 | |
|     bzero((void *)n, sizeof(Buffer));
 | |
|     n->width = width;
 | |
|     n->COLS = COLS;
 | |
|     n->currentURL.scheme = SCM_UNKNOWN;
 | |
|     n->baseURL = NULL;
 | |
|     n->baseTarget = NULL;
 | |
|     n->buffername = "";
 | |
|     n->bufferprop = BP_NORMAL;
 | |
|     n->clone = New(int);
 | |
|     *n->clone = 1;
 | |
|     n->linelen = 0;
 | |
|     n->trbyte = 0;
 | |
| #ifdef USE_SSL
 | |
|     n->ssl_certificate = NULL;
 | |
| #endif
 | |
|     return n;
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * Create null buffer
 | |
|  */
 | |
| Buffer *
 | |
| nullBuffer(void)
 | |
| {
 | |
|     Buffer *b;
 | |
| 
 | |
|     b = newBuffer(COLS);
 | |
|     b->buffername = "*Null*";
 | |
|     return b;
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * clearBuffer: clear buffer content
 | |
|  */
 | |
| void
 | |
| clearBuffer(Buffer *buf)
 | |
| {
 | |
|     buf->firstLine = buf->topLine = buf->currentLine = buf->lastLine = NULL;
 | |
|     buf->allLine = 0;
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * discardBuffer: free buffer structure
 | |
|  */
 | |
| 
 | |
| void
 | |
| discardBuffer(Buffer *buf)
 | |
| {
 | |
|     int i;
 | |
|     Buffer *b;
 | |
| 
 | |
| #ifdef USE_IMAGE
 | |
|     deleteImage(buf);
 | |
| #endif
 | |
|     clearBuffer(buf);
 | |
|     for (i = 0; i < MAX_LB; i++) {
 | |
| 	b = buf->linkBuffer[i];
 | |
| 	if (b == NULL)
 | |
| 	    continue;
 | |
| 	b->linkBuffer[REV_LB[i]] = NULL;
 | |
|     }
 | |
|     if (buf->savecache)
 | |
| 	unlink(buf->savecache);
 | |
|     if (--(*buf->clone))
 | |
| 	return;
 | |
|     if (buf->pagerSource)
 | |
| 	ISclose(buf->pagerSource);
 | |
|     if (buf->sourcefile) {
 | |
| 	if (buf->real_scheme != SCM_LOCAL || buf->bufferprop & BP_FRAME)
 | |
| 	    unlink(buf->sourcefile);
 | |
|     }
 | |
|     if (buf->mailcap_source)
 | |
| 	unlink(buf->mailcap_source);
 | |
|     while (buf->frameset) {
 | |
| 	deleteFrameSet(buf->frameset);
 | |
| 	buf->frameset = popFrameTree(&(buf->frameQ));
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * namedBuffer: Select buffer which have specified name
 | |
|  */
 | |
| Buffer *
 | |
| namedBuffer(Buffer *first, char *name)
 | |
| {
 | |
|     Buffer *buf;
 | |
| 
 | |
|     if (!strcmp(first->buffername, name)) {
 | |
| 	return first;
 | |
|     }
 | |
|     for (buf = first; buf->nextBuffer != NULL; buf = buf->nextBuffer) {
 | |
| 	if (!strcmp(buf->nextBuffer->buffername, name)) {
 | |
| 	    return buf->nextBuffer;
 | |
| 	}
 | |
|     }
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * deleteBuffer: delete buffer
 | |
|  */
 | |
| Buffer *
 | |
| deleteBuffer(Buffer *first, Buffer *delbuf)
 | |
| {
 | |
|     Buffer *buf, *b;
 | |
| 
 | |
|     if (first == delbuf && first->nextBuffer != NULL) {
 | |
| 	buf = first->nextBuffer;
 | |
| 	discardBuffer(first);
 | |
| 	return buf;
 | |
|     }
 | |
|     if ((buf = prevBuffer(first, delbuf)) != NULL) {
 | |
| 	b = buf->nextBuffer;
 | |
| 	buf->nextBuffer = b->nextBuffer;
 | |
| 	discardBuffer(b);
 | |
|     }
 | |
|     return first;
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * replaceBuffer: replace buffer
 | |
|  */
 | |
| Buffer *
 | |
| replaceBuffer(Buffer *first, Buffer *delbuf, Buffer *newbuf)
 | |
| {
 | |
|     Buffer *buf;
 | |
| 
 | |
|     if (delbuf == NULL) {
 | |
| 	newbuf->nextBuffer = first;
 | |
| 	return newbuf;
 | |
|     }
 | |
|     if (first == delbuf) {
 | |
| 	newbuf->nextBuffer = delbuf->nextBuffer;
 | |
| 	discardBuffer(delbuf);
 | |
| 	return newbuf;
 | |
|     }
 | |
|     if (delbuf && (buf = prevBuffer(first, delbuf))) {
 | |
| 	buf->nextBuffer = newbuf;
 | |
| 	newbuf->nextBuffer = delbuf->nextBuffer;
 | |
| 	discardBuffer(delbuf);
 | |
| 	return first;
 | |
|     }
 | |
|     newbuf->nextBuffer = first;
 | |
|     return newbuf;
 | |
| }
 | |
| 
 | |
| Buffer *
 | |
| nthBuffer(Buffer *firstbuf, int n)
 | |
| {
 | |
|     int i;
 | |
|     Buffer *buf = firstbuf;
 | |
| 
 | |
|     if (n < 0)
 | |
| 	return firstbuf;
 | |
|     for (i = 0; i < n; i++) {
 | |
| 	if (buf == NULL)
 | |
| 	    return NULL;
 | |
| 	buf = buf->nextBuffer;
 | |
|     }
 | |
|     return buf;
 | |
| }
 | |
| 
 | |
| static void
 | |
| writeBufferName(Buffer *buf, int n)
 | |
| {
 | |
|     Str msg;
 | |
|     int all;
 | |
| 
 | |
|     all = buf->allLine;
 | |
|     if (all == 0 && buf->lastLine != NULL)
 | |
| 	all = buf->lastLine->linenumber;
 | |
|     move(n, 0);
 | |
|     msg = Sprintf("<%s> [%d lines]", buf->buffername, all);
 | |
|     if (buf->filename != NULL) {
 | |
| 	switch (buf->currentURL.scheme) {
 | |
| 	case SCM_LOCAL:
 | |
| 	case SCM_LOCAL_CGI:
 | |
| 	    if (strcmp(buf->currentURL.file, "-")) {
 | |
| 		Strcat_char(msg, ' ');
 | |
| 		Strcat_charp(msg, conv_from_system(buf->currentURL.real_file));
 | |
| 	    }
 | |
| 	    break;
 | |
| 	case SCM_UNKNOWN:
 | |
| 	case SCM_MISSING:
 | |
| 	    break;
 | |
| 	default:
 | |
| 	    Strcat_char(msg, ' ');
 | |
| 	    Strcat(msg, parsedURL2Str(&buf->currentURL));
 | |
| 	    break;
 | |
| 	}
 | |
|     }
 | |
|     addnstr_sup(msg->ptr, COLS - 1);
 | |
| }
 | |
| 
 | |
| 
 | |
| /* 
 | |
|  * gotoLine: go to line number
 | |
|  */
 | |
| void
 | |
| gotoLine(Buffer *buf, int n)
 | |
| {
 | |
|     char msg[32];
 | |
|     Line *l = buf->firstLine;
 | |
| 
 | |
|     if (l == NULL)
 | |
| 	return;
 | |
|     if (buf->pagerSource && !(buf->bufferprop & BP_CLOSE)) {
 | |
| 	if (buf->lastLine->linenumber < n)
 | |
| 	    getNextPage(buf, n - buf->lastLine->linenumber);
 | |
| 	while ((buf->lastLine->linenumber < n) &&
 | |
| 	       (getNextPage(buf, 1) != NULL)) ;
 | |
|     }
 | |
|     if (l->linenumber > n) {
 | |
| 	sprintf(msg, "First line is #%ld", l->linenumber);
 | |
| 	set_delayed_message(msg);
 | |
| 	buf->topLine = buf->currentLine = l;
 | |
| 	return;
 | |
|     }
 | |
|     if (buf->lastLine->linenumber < n) {
 | |
| 	l = buf->lastLine;
 | |
| 	sprintf(msg, "Last line is #%ld", buf->lastLine->linenumber);
 | |
| 	set_delayed_message(msg);
 | |
| 	buf->currentLine = l;
 | |
| 	buf->topLine = lineSkip(buf, buf->currentLine, -(LASTLINE - 1), FALSE);
 | |
| 	return;
 | |
|     }
 | |
|     for (; l != NULL; l = l->next) {
 | |
| 	if (l->linenumber >= n) {
 | |
| 	    buf->currentLine = l;
 | |
| 	    if (n < buf->topLine->linenumber ||
 | |
| 		buf->topLine->linenumber + LASTLINE <= n)
 | |
| 		buf->topLine = lineSkip(buf, l, -(LASTLINE + 1) / 2, FALSE);
 | |
| 	    break;
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * gotoRealLine: go to real line number
 | |
|  */
 | |
| void
 | |
| gotoRealLine(Buffer *buf, int n)
 | |
| {
 | |
|     char msg[32];
 | |
|     Line *l = buf->firstLine;
 | |
| 
 | |
|     if (l == NULL)
 | |
| 	return;
 | |
|     if (buf->pagerSource && !(buf->bufferprop & BP_CLOSE)) {
 | |
| 	if (buf->lastLine->real_linenumber < n)
 | |
| 	    getNextPage(buf, n - buf->lastLine->real_linenumber);
 | |
| 	while ((buf->lastLine->real_linenumber < n) &&
 | |
| 	       (getNextPage(buf, 1) != NULL)) ;
 | |
|     }
 | |
|     if (l->real_linenumber > n) {
 | |
| 	sprintf(msg, "First line is #%ld", l->real_linenumber);
 | |
| 	set_delayed_message(msg);
 | |
| 	buf->topLine = buf->currentLine = l;
 | |
| 	return;
 | |
|     }
 | |
|     if (buf->lastLine->real_linenumber < n) {
 | |
| 	l = buf->lastLine;
 | |
| 	sprintf(msg, "Last line is #%ld", buf->lastLine->real_linenumber);
 | |
| 	set_delayed_message(msg);
 | |
| 	buf->currentLine = l;
 | |
| 	buf->topLine = lineSkip(buf, buf->currentLine, -(LASTLINE - 1), FALSE);
 | |
| 	return;
 | |
|     }
 | |
|     for (; l != NULL; l = l->next) {
 | |
| 	if (l->real_linenumber >= n) {
 | |
| 	    buf->currentLine = l;
 | |
| 	    if (n < buf->topLine->real_linenumber ||
 | |
| 		buf->topLine->real_linenumber + LASTLINE <= n)
 | |
| 		buf->topLine = lineSkip(buf, l, -(LASTLINE + 1) / 2, FALSE);
 | |
| 	    break;
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| static Buffer *
 | |
| listBuffer(Buffer *top, Buffer *current)
 | |
| {
 | |
|     int i, c = 0;
 | |
|     Buffer *buf = top;
 | |
| 
 | |
|     move(0, 0);
 | |
| #ifdef USE_COLOR
 | |
|     if (useColor) {
 | |
| 	setfcolor(basic_color);
 | |
| #ifdef USE_BG_COLOR
 | |
| 	setbcolor(bg_color);
 | |
| #endif				/* USE_BG_COLOR */
 | |
|     }
 | |
| #endif				/* USE_COLOR */
 | |
|     clrtobotx();
 | |
|     for (i = 0; i < LASTLINE; i++) {
 | |
| 	if (buf == current) {
 | |
| 	    c = i;
 | |
| 	    standout();
 | |
| 	}
 | |
| 	writeBufferName(buf, i);
 | |
| 	if (buf == current) {
 | |
| 	    standend();
 | |
| 	    clrtoeolx();
 | |
| 	    move(i, 0);
 | |
| 	    toggle_stand();
 | |
| 	}
 | |
| 	else
 | |
| 	    clrtoeolx();
 | |
| 	if (buf->nextBuffer == NULL) {
 | |
| 	    move(i + 1, 0);
 | |
| 	    clrtobotx();
 | |
| 	    break;
 | |
| 	}
 | |
| 	buf = buf->nextBuffer;
 | |
|     }
 | |
|     standout();
 | |
|     message("Buffer selection mode: SPC for select / D for delete buffer", 0,
 | |
| 	    0);
 | |
|     standend();
 | |
|     /* 
 | |
|      * move(LASTLINE, COLS - 1); */
 | |
|     move(c, 0);
 | |
|     refresh();
 | |
|     return buf->nextBuffer;
 | |
| }
 | |
| 
 | |
| 
 | |
| /* 
 | |
|  * Select buffer visually
 | |
|  */
 | |
| Buffer *
 | |
| selectBuffer(Buffer *firstbuf, Buffer *currentbuf, char *selectchar)
 | |
| {
 | |
|     int i, cpoint,		/* Current Buffer Number */
 | |
|      spoint,			/* Current Line on Screen */
 | |
|      maxbuf, sclimit = LASTLINE;	/* Upper limit of line * number in 
 | |
| 					 * the * screen */
 | |
|     Buffer *buf, *topbuf;
 | |
|     char c;
 | |
| 
 | |
|     i = cpoint = 0;
 | |
|     for (buf = firstbuf; buf != NULL; buf = buf->nextBuffer) {
 | |
| 	if (buf == currentbuf)
 | |
| 	    cpoint = i;
 | |
| 	i++;
 | |
|     }
 | |
|     maxbuf = i;
 | |
| 
 | |
|     if (cpoint >= sclimit) {
 | |
| 	spoint = sclimit / 2;
 | |
| 	topbuf = nthBuffer(firstbuf, cpoint - spoint);
 | |
|     }
 | |
|     else {
 | |
| 	topbuf = firstbuf;
 | |
| 	spoint = cpoint;
 | |
|     }
 | |
|     listBuffer(topbuf, currentbuf);
 | |
| 
 | |
|     for (;;) {
 | |
| 	if ((c = getch()) == ESC_CODE) {
 | |
| 	    if ((c = getch()) == '[' || c == 'O') {
 | |
| 		switch (c = getch()) {
 | |
| 		case 'A':
 | |
| 		    c = 'k';
 | |
| 		    break;
 | |
| 		case 'B':
 | |
| 		    c = 'j';
 | |
| 		    break;
 | |
| 		case 'C':
 | |
| 		    c = ' ';
 | |
| 		    break;
 | |
| 		case 'D':
 | |
| 		    c = 'B';
 | |
| 		    break;
 | |
| 		}
 | |
| 	    }
 | |
| 	}
 | |
| #ifdef __EMX__
 | |
| 	else if (!c)
 | |
| 	    switch (getch()) {
 | |
| 	    case K_UP:
 | |
| 		c = 'k';
 | |
| 		break;
 | |
| 	    case K_DOWN:
 | |
| 		c = 'j';
 | |
| 		break;
 | |
| 	    case K_RIGHT:
 | |
| 		c = ' ';
 | |
| 		break;
 | |
| 	    case K_LEFT:
 | |
| 		c = 'B';
 | |
| 	    }
 | |
| #endif
 | |
| 	switch (c) {
 | |
| 	case CTRL_N:
 | |
| 	case 'j':
 | |
| 	    if (spoint < sclimit - 1) {
 | |
| 		if (currentbuf->nextBuffer == NULL)
 | |
| 		    continue;
 | |
| 		writeBufferName(currentbuf, spoint);
 | |
| 		currentbuf = currentbuf->nextBuffer;
 | |
| 		cpoint++;
 | |
| 		spoint++;
 | |
| 		standout();
 | |
| 		writeBufferName(currentbuf, spoint);
 | |
| 		standend();
 | |
| 		move(spoint, 0);
 | |
| 		toggle_stand();
 | |
| 	    }
 | |
| 	    else if (cpoint < maxbuf - 1) {
 | |
| 		topbuf = currentbuf;
 | |
| 		currentbuf = currentbuf->nextBuffer;
 | |
| 		cpoint++;
 | |
| 		spoint = 1;
 | |
| 		listBuffer(topbuf, currentbuf);
 | |
| 	    }
 | |
| 	    break;
 | |
| 	case CTRL_P:
 | |
| 	case 'k':
 | |
| 	    if (spoint > 0) {
 | |
| 		writeBufferName(currentbuf, spoint);
 | |
| 		currentbuf = nthBuffer(topbuf, --spoint);
 | |
| 		cpoint--;
 | |
| 		standout();
 | |
| 		writeBufferName(currentbuf, spoint);
 | |
| 		standend();
 | |
| 		move(spoint, 0);
 | |
| 		toggle_stand();
 | |
| 	    }
 | |
| 	    else if (cpoint > 0) {
 | |
| 		i = cpoint - sclimit;
 | |
| 		if (i < 0)
 | |
| 		    i = 0;
 | |
| 		cpoint--;
 | |
| 		spoint = cpoint - i;
 | |
| 		currentbuf = nthBuffer(firstbuf, cpoint);
 | |
| 		topbuf = nthBuffer(firstbuf, i);
 | |
| 		listBuffer(topbuf, currentbuf);
 | |
| 	    }
 | |
| 	    break;
 | |
| 	default:
 | |
| 	    *selectchar = c;
 | |
| 	    return currentbuf;
 | |
| 	}
 | |
| 	/* 
 | |
| 	 * move(LASTLINE, COLS - 1);
 | |
| 	 */
 | |
| 	move(spoint, 0);
 | |
| 	refresh();
 | |
|     }
 | |
| }
 | |
| 
 | |
| /* 
 | |
|  * Reshape HTML buffer
 | |
|  */
 | |
| void
 | |
| reshapeBuffer(Buffer *buf)
 | |
| {
 | |
|     URLFile f;
 | |
|     Buffer sbuf;
 | |
| 
 | |
|     if (!buf->need_reshape)
 | |
| 	return;
 | |
|     buf->need_reshape = FALSE;
 | |
|     if (buf->sourcefile == NULL)
 | |
| 	return;
 | |
|     init_stream(&f, SCM_LOCAL, NULL);
 | |
|     examineFile(buf->mailcap_source ? buf->mailcap_source : buf->sourcefile,
 | |
| 		&f);
 | |
|     if (f.stream == NULL)
 | |
| 	return;
 | |
| 
 | |
|     copyBuffer(&sbuf, buf);
 | |
|     clearBuffer(buf);
 | |
|     while (buf->frameset) {
 | |
| 	deleteFrameSet(buf->frameset);
 | |
| 	buf->frameset = popFrameTree(&(buf->frameQ));
 | |
|     }
 | |
| 
 | |
|     buf->href = NULL;
 | |
|     buf->name = NULL;
 | |
|     buf->img = NULL;
 | |
|     buf->formitem = NULL;
 | |
|     buf->width = INIT_BUFFER_WIDTH;
 | |
| 
 | |
| #ifdef JP_CHARSET
 | |
|     UseContentCharset = FALSE;
 | |
|     UseAutoDetect = FALSE;
 | |
| #endif
 | |
|     if (!strcasecmp(buf->type, "text/html"))
 | |
| 	loadHTMLBuffer(&f, buf);
 | |
|     else
 | |
| 	loadBuffer(&f, buf);
 | |
|     UFclose(&f);
 | |
| #ifdef JP_CHARSET
 | |
|     UseContentCharset = TRUE;
 | |
|     UseAutoDetect = TRUE;
 | |
| #endif
 | |
| 
 | |
|     buf->height = LASTLINE + 1;
 | |
|     if (buf->firstLine)
 | |
| 	restorePosition(buf, &sbuf);
 | |
|     if (buf->check_url & CHK_URL)
 | |
| 	chkURLBuffer(buf);
 | |
| #ifdef USE_NNTP
 | |
|     if (buf->check_url & CHK_NMID)
 | |
| 	chkNMIDBuffer(buf);
 | |
| #endif
 | |
|     formResetBuffer(buf, sbuf.formitem);
 | |
| }
 | |
| 
 | |
| /* shallow copy */
 | |
| void
 | |
| copyBuffer(Buffer *a, Buffer *b)
 | |
| {
 | |
|     readBufferCache(b);
 | |
|     bcopy((void *)b, (void *)a, sizeof(Buffer));
 | |
| }
 | |
| 
 | |
| Buffer *
 | |
| prevBuffer(Buffer *first, Buffer *buf)
 | |
| {
 | |
|     Buffer *b;
 | |
| 
 | |
|     for (b = first; b != NULL && b->nextBuffer != buf; b = b->nextBuffer) ;
 | |
|     return b;
 | |
| }
 | |
| 
 | |
| #define fwrite1(d, f) (fwrite(&d, sizeof(d), 1, f)==0)
 | |
| #define fread1(d, f) (fread(&d, sizeof(d), 1, f)==0)
 | |
| 
 | |
| int
 | |
| writeBufferCache(Buffer *buf)
 | |
| {
 | |
|     Str tmp;
 | |
|     FILE *cache = NULL;
 | |
|     Line *l;
 | |
| #ifdef USE_ANSI_COLOR
 | |
|     int colorflag;
 | |
| #endif
 | |
| 
 | |
|     if (buf->savecache)
 | |
| 	return -1;
 | |
| 
 | |
|     if (buf->firstLine == NULL)
 | |
| 	goto _error1;
 | |
| 
 | |
|     tmp = tmpfname(TMPF_CACHE, NULL);
 | |
|     buf->savecache = tmp->ptr;
 | |
|     cache = fopen(buf->savecache, "w");
 | |
|     if (!cache)
 | |
| 	goto _error1;
 | |
| 
 | |
|     if (fwrite1(buf->currentLine->linenumber, cache) ||
 | |
| 	fwrite1(buf->topLine->linenumber, cache))
 | |
| 	goto _error;
 | |
| 
 | |
|     for (l = buf->firstLine; l; l = l->next) {
 | |
| 	if (fwrite1(l->real_linenumber, cache) ||
 | |
| 	    fwrite1(l->usrflags, cache) ||
 | |
| 	    fwrite1(l->width, cache) ||
 | |
| 	    fwrite1(l->len, cache) ||
 | |
| 	    fwrite(l->lineBuf, 1, l->len, cache) < l->len ||
 | |
| 	    fwrite(l->propBuf, sizeof(Lineprop), l->len, cache) < l->len)
 | |
| 	    goto _error;
 | |
| #ifdef USE_ANSI_COLOR
 | |
| 	colorflag = l->colorBuf ? 1 : 0;
 | |
| 	if (fwrite1(colorflag, cache))
 | |
| 	    goto _error;
 | |
| 	if (colorflag) {
 | |
| 	    if (fwrite(l->colorBuf, sizeof(Linecolor), l->len, cache) < l->len)
 | |
| 		goto _error;
 | |
| 	}
 | |
| #endif
 | |
|     }
 | |
| 
 | |
|     fclose(cache);
 | |
|     return 0;
 | |
|   _error:
 | |
|     fclose(cache);
 | |
|     unlink(buf->savecache);
 | |
|   _error1:
 | |
|     buf->savecache = NULL;
 | |
|     return -1;
 | |
| }
 | |
| 
 | |
| int
 | |
| readBufferCache(Buffer *buf)
 | |
| {
 | |
|     FILE *cache;
 | |
|     Line *l = NULL, *prevl = NULL;
 | |
|     long lnum = 0, clnum, tlnum;
 | |
| #ifdef USE_ANSI_COLOR
 | |
|     int colorflag;
 | |
| #endif
 | |
| 
 | |
|     if (buf->savecache == NULL)
 | |
| 	return -1;
 | |
| 
 | |
|     cache = fopen(buf->savecache, "r");
 | |
|     if (cache == NULL || fread1(clnum, cache) || fread1(tlnum, cache)) {
 | |
| 	buf->savecache = NULL;
 | |
| 	return -1;
 | |
|     }
 | |
| 
 | |
|     while (!feof(cache)) {
 | |
| 	lnum++;
 | |
| 	prevl = l;
 | |
| 	l = New(Line);
 | |
| 	l->prev = prevl;
 | |
| 	if (prevl)
 | |
| 	    prevl->next = l;
 | |
| 	else
 | |
| 	    buf->firstLine = l;
 | |
| 	l->linenumber = lnum;
 | |
| 	if (lnum == clnum)
 | |
| 	    buf->currentLine = l;
 | |
| 	if (lnum == tlnum)
 | |
| 	    buf->topLine = l;
 | |
| 	if (fread1(l->real_linenumber, cache) ||
 | |
| 	    fread1(l->usrflags, cache) ||
 | |
| 	    fread1(l->width, cache) || fread1(l->len, cache))
 | |
| 	    break;
 | |
| 	l->lineBuf = NewAtom_N(char, l->len + 1);
 | |
| 	fread(l->lineBuf, 1, l->len, cache);
 | |
| 	l->lineBuf[l->len] = '\0';
 | |
| 	l->propBuf = NewAtom_N(Lineprop, l->len);
 | |
| 	fread(l->propBuf, sizeof(Lineprop), l->len, cache);
 | |
| #ifdef USE_ANSI_COLOR
 | |
| 	if (fread1(colorflag, cache))
 | |
| 	    break;
 | |
| 	if (colorflag) {
 | |
| 	    l->colorBuf = NewAtom_N(Linecolor, l->len);
 | |
| 	    fread(l->colorBuf, sizeof(Linecolor), l->len, cache);
 | |
| 	}
 | |
| 	else {
 | |
| 	    l->colorBuf = NULL;
 | |
| 	}
 | |
| #endif
 | |
|     }
 | |
|     buf->lastLine = prevl;
 | |
|     buf->lastLine->next = NULL;
 | |
|     fclose(cache);
 | |
|     unlink(buf->savecache);
 | |
|     buf->savecache = NULL;
 | |
|     return 0;
 | |
| }
 |