775 lines · 16.1 KB · C
RawDownload
/* $Id: buffer.c,v 1.30 2010/07/18 14:10:09 htrb 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>#endifchar *NullLine = "";Lineprop NullProp[] = { 0 }; /*  * Buffer creation */Buffer *newBuffer(int width){    Buffer *n;     n = New(Buffer);    if (n == NULL)	exit(3);    bzero((void *)n, sizeof(Buffer));    n->width = width;    n->COLS = COLS;    n->LINES = LASTLINE;    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->trbyte = 0;#ifdef USE_SSL    n->ssl_certificate = NULL;#endif#ifdef USE_M17N    n->auto_detect = WcOption.auto_detect;#endif    n->check_url = MarkAllPages; /* use default from -o mark_all_pages */    n->need_reshape = 1;	 /* always reshape new buffers to mark URLs */    return n;} /*  * Create null buffer */Buffer *nullBuffer(void){    Buffer *b;     b = newBuffer(COLS);    b->buffername = "*Null*";    return b;} /*  * clearBuffer: clear buffer content */voidclearBuffer(Buffer *buf){    buf->firstLine = buf->topLine = buf->currentLine = buf->lastLine = NULL;    buf->allLine = 0;} /*  * discardBuffer: free buffer structure */ voiddiscardBuffer(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 &&	(!buf->real_type || strncasecmp(buf->real_type, "image/", 6))) {	if (buf->real_scheme != SCM_LOCAL || buf->bufferprop & BP_FRAME)	    unlink(buf->sourcefile);    }    if (buf->header_source)	unlink(buf->header_source);    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 voidwriteBufferName(Buffer *buf, int n){    Str msg;    int all;     all = buf->allLine;    if (all == 0 && buf->lastLine != NULL)	all = buf->lastLine->linenumber;    move(n, 0);    /* FIXME: gettextize? */    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 */voidgotoLine(Buffer *buf, int n){    char msg[36];    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) {	/* FIXME: gettextize? */	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;	/* FIXME: gettextize? */	sprintf(msg, "Last line is #%ld", buf->lastLine->linenumber);	set_delayed_message(msg);	buf->currentLine = l;	buf->topLine = lineSkip(buf, buf->currentLine, -(buf->LINES - 1),				FALSE);	return;    }    for (; l != NULL; l = l->next) {	if (l->linenumber >= n) {	    buf->currentLine = l;	    if (n < buf->topLine->linenumber ||		buf->topLine->linenumber + buf->LINES <= n)		buf->topLine = lineSkip(buf, l, -(buf->LINES + 1) / 2, FALSE);	    break;	}    }} /*  * gotoRealLine: go to real line number */voidgotoRealLine(Buffer *buf, int n){    char msg[36];    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) {	/* FIXME: gettextize? */	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;	/* FIXME: gettextize? */	sprintf(msg, "Last line is #%ld", buf->lastLine->real_linenumber);	set_delayed_message(msg);	buf->currentLine = l;	buf->topLine = lineSkip(buf, buf->currentLine, -(buf->LINES - 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 + buf->LINES <= n)		buf->topLine = lineSkip(buf, l, -(buf->LINES + 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();    /* FIXME: gettextize? */    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();    }}

Lines 1–500 of 775.