⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 window.c

📁 VT100终端程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * window.c	Very portable window routines. *		Currently this code is used in _both_ the BBS *		system and minicom. * *		This file is part of the minicom communications package, *		Copyright 1991-1996 Miquel van Smoorenburg. * *		This program is free software; you can redistribute it and/or *		modify it under the terms of the GNU General Public License *		as published by the Free Software Foundation; either version *		2 of the License, or (at your option) any later version. */#include "port.h"#include "window.h"#include "charmap.h"/* Status line code on/off. */#define ST_LINE 1/* fmg 2/20/94 macros - Length of Macros */#ifndef MAC_LEN#define MAC_LEN 257#endif/* Don't want to include all header stuff for three prototypes from sysdep.c */#if __STDC__  int setcbreak(int);  int wxgetch(void);  void getrowcols(int *rows, int *cols);#else  int setcbreak();  int wxgetch();  void getrowcols();#endif#ifndef BBS#include "config.h"#endif#define BUFFERSIZE 2048#define swap(x, y) { int d = (x); (x) = (y); (y) = d; }/* Terminal capabilities */static char *CM, *IS, *RS, *AC, *EA;static char *ME, *SE, *UE, *AE;static char *AS, *MB, *MD, *MR, *SO, *US;static char *CE, *Al, *Dl, *AL, *DL;static char *CS, *SF, *SR, *VB, *BL;static char *VE, *VI, *KS, *KE;static char *CD, *CL, *IC, *DC;static char *BC, *CR, *NL;#if ST_LINEstatic char *TS, *FS, *DS;#endif/* Special characters */static char D_UL;static char D_HOR;static char D_UR;static char D_LL;static char D_VER;static char D_LR;static char S_UL;static char S_HOR;static char S_UR;static char S_LL;static char S_VER;static char S_LR;static char _bufstart[BUFFERSIZE];static char *_bufpos = _bufstart;static char *_buffend;static ELM *gmap;static char curattr = -1;static char curcolor = -1;static int curx = -1;static int cury = -1;static int _intern = 0;static int _curstype = CNORMAL;static int _has_am = 0;static int _mv_standout = 0;static ELM oldc;static int sflag = 0;/* * Smooth is only defined for slow machines running Minicom. * With this defined, Minicom will buffer only per-line * and the output will look much less 'jerky'. (I hope :-) */#ifdef SMOOTHstatic WIN *curwin = NIL_WIN;extern WIN *us;#endifint useattr = 1;int dirflush = 1;int LINES, COLS;int usecolor = 0;WIN *stdwin;char *_tptr = CNULL;int screen_ibmpc = 0;int screen_iso = 0;int w_init = 0;#if ST_LINEint use_status = 0; /* Turned on in main() */#elseint use_status = 0;#endif/* Standard vt100 map (ac cpability) */static char *def_ac = "+\273,\253aaffggjjkkllmmnnooqqssttuuvvwwxx";#if DEBUG/* * Debug to stdout */int debug(s, a1, a2, a3, a4)char *s;int a1, a2, a3, a4;{  char lala[80];  sprintf(lala, s, a1, a2, a3, a4);  write(2, lala, strlen(lala));  return(0);}#endif/* ===== Low level routines ===== *//* * Flush the screen buffer */void wflush(){  int todo, done;  todo = _bufpos - _bufstart;  _bufpos = _bufstart;  while(todo > 0) {  	done = write(1, _bufpos, todo);  	if (done > 0) {  		todo -= done;  		_bufpos += done;  	}	if (done < 0 && errno != EINTR) break;  }  _bufpos = _bufstart;}/* * Output a raw character to the screen */static int outchar(c)int c;{  *_bufpos++ = c;  if (_bufpos >= _buffend) wflush();#if defined(SMOOTH)  if (curwin == us && (c == '\n' || c == '\r')) wflush();#endif  return(0);}/* * Output a raw string to the screen. */static void outstr(s)char *s;{  tputs(s, 1, outchar);}/* * Turn off all attributes */static void _attroff(){  if (ME != CNULL)  	outstr(ME);  else {  	if (SE != CNULL) outstr(SE);  	if (UE != CNULL) outstr(UE);  }  if (AE != CNULL) outstr(AE);}/* * Turn some attributes on */static void _attron(attr)char attr;{  if (!usecolor || (attr & XA_REVERSE) == 0) {	/* Reverse standout does not look too good.. */	if (attr & XA_BOLD	&& MD != CNULL)  outstr(MD);  	if (attr & XA_STANDOUT   && SO != CNULL)  outstr(SO);	if (attr & XA_UNDERLINE  && US != CNULL)  outstr(US);  }  if (attr & XA_REVERSE	  && MR != CNULL)  outstr(MR);  if (attr & XA_BLINK      && MB != CNULL)  outstr(MB);  if (attr & XA_ALTCHARSET && AS != CNULL)  outstr(AS);}/* * Set the colors */static void _colson(color)char color;{  char buf[12];  sprintf(buf, "\033[%d;%dm", COLFG(color) + 30, COLBG(color) + 40);  outstr(buf);}  /* * Set global attributes, if different. */static void _setattr(attr, color)char attr, color;{  if (!useattr) return;  if (!usecolor) {  	curcolor = color;  	if (attr == curattr) return;  	curattr = attr;  	_attroff();  	_attron(attr);  	return;  }  if (attr == curattr && color == curcolor) return;  _attroff();  _colson(color);  _attron(attr);  curattr = attr;  curcolor = color;}/* * Goto (x, y) in stdwin */static void _gotoxy(x, y)int x, y;{  int oldattr = -1;#if ST_LINE  int tmp;  /* Sanity check. */  if (x >= COLS || y > LINES || (x == curx && y == cury)) return;  if (use_status) {	/* Leaving status line? */	if (cury == LINES && y < cury) {		outstr(FS);		/* Re-set attributes. */		tmp = curattr;		curattr = -1;		_setattr(tmp, curcolor);		outstr(tgoto(CM, x, y));		curx = x; cury = y;		return;	}	/* Writing on status line? */	else if (y == LINES) {		/* From normal screen? */		if (cury < y) {			outstr(tgoto(TS, x, x));			curx = x;			cury = y;			/* Set the right attributes. */			tmp = curattr;			curattr = -1;			_setattr(tmp, curcolor);			return;		}	}  }#else  /* Sanity check. */  if (x >= COLS || y >= LINES || (x == curx && y == cury)) {#  if 0	if (x >= COLS || y >= LINES)		fprintf(stderr, "OOPS: (x, y) == (%d, %d)\n",			COLS, LINES);#  endif	return;  }#endif  if (!_mv_standout && curattr != XA_NORMAL) { 	oldattr = curattr;  	_setattr(XA_NORMAL, curcolor);  }  if (CR != CNULL && y == cury && x == 0)  	outstr(CR);#if 0 /* Hmm, sometimes NL only works in the first column */  else if (NL != CNULL && x == curx && y == cury + 1)	outstr(NL);#else  else if (NL != CNULL && x == 0 && x == curx && y == cury + 1)	outstr(NL);#endif  else if (BC != CNULL && y == cury && x == curx - 1)  	outstr(BC);  else	  	outstr(tgoto(CM, x, y));  curx = x;  cury = y;  if (oldattr != -1) _setattr(oldattr, curcolor);}/* * Write a character in stdwin at x, y with attr & color * 'doit' can be  -1: only write to screen, not to memory *                 0: only write to memory, not to screen *                 1: write to both screen and memory */static void _write(c, doit, x, y,attr, color)int c, doit;int x, y;char attr, color;{  ELM *e;  /* If the terminal has automatic margins, we can't write to the   * last line, last character. After scrolling, this "invisible"   * character is automatically restored.   */  if (_has_am && y >= LINES - 1 && x >= COLS - 1) {  	doit = 0;  	sflag = 1;  	oldc.value = c;  	oldc.attr = attr;  	oldc.color = color;  }#if ST_LINE  if (x < COLS && y <= LINES) {#else  if (x < COLS && y < LINES) {#endif     if (doit != 0) {  	_gotoxy(x, y);  	_setattr(attr, color);	(void) outchar((screen_ibmpc || (attr & XA_ALTCHARSET)) ? c : wcharmap[(unsigned char)c]);	curx++;     }     if (doit >= 0) {	e = &gmap[x + y * COLS];	e->value = c;	e->attr = attr;	e->color = color;     }  }}/* * Set cursor type. */static void _cursor(type)int type;{  _curstype = type;  if (type == CNORMAL && VE != CNULL) outstr(VE);  if (type == CNONE && VE != CNULL && VI != CNULL) outstr(VI);}/* ==== High level routines ==== */#if 0/* This code is functional, but not yet used. * It might be one day.... *//* * Resize a window */void wresize(win, lines, cols)WIN *win;int lines, cols;{  int x, y;  ELM *oldmap, *newmap, *e, *n;  if ((newmap = (ELM *)malloc((lines + 1) * cols * sizeof(ELM))) == (ELM *)NULL)	return;  if (win == stdwin)	oldmap = gmap;  else	oldmap = win->map;  for(y = 0; y < lines; y++)	for(x = 0; x < cols; x++) {		n = &newmap[y + x * cols];		if (x < win->xs && y < win->ys) {			e = &oldmap[y + x * COLS];			n->value = e->value;			n->color = e->color;			n->attr = e->attr;		} else {			n->value = ' ';			n->color = win->color;			n->attr = win->attr;		}	}  if (win->sy2 == win->y2) win->sy2 = win->y1 + lines - 1;  win->y2 = win->y1 + lines - 1;  win->ys = lines;  win->xs = cols;  free(oldmap);  if (win == stdwin) {	gmap = newmap;	LINES = lines;	COLS = cols;  } else	win->map = newmap;}#endif/* * Create a new window. *//*ARGSUSED*/WIN *wopen(x1, y1, x2, y2, border, attr, fg, bg, direct, histlines, doclr)int x1, y1, x2, y2;int border;int attr, fg, bg, direct;int histlines;int doclr;{  WIN *w;  ELM *e;  int bytes;  int x, y;  int color;  int offs;  int xattr;#ifdef SMOOTH  curwin = NIL_WIN;#endif  if ((w = (WIN *)malloc(sizeof(WIN))) == (WIN *)0) return(w);    offs = (border != BNONE);  if (!screen_ibmpc && AS)	xattr = attr | XA_ALTCHARSET;  else	xattr = attr;  if (x1 < offs) x1 = offs;  if (y1 < offs) y1 = offs;#if 0  if (x2 >= COLS - offs) x2 = COLS - offs - 1;  if (y2 >= LINES - offs) y2 = LINES - offs - 1;#endif  if (x1 > x2) swap(x1, x2);  if (y1 > y2) swap(y1, y2);  w->xs = x2 - x1 + 1;  w->ys = y2 - y1 + 1;  w->x1 = x1;  w->x2 = x2;  w->y1 = w->sy1 = y1;  w->y2 = w->sy2 = y2;  w->doscroll = 1;  w->border = border;  w->cursor = CNORMAL;  w->attr = attr;  w->autocr = 1;  w->wrap = 1;  color = w->color = COLATTR(fg, bg);  w->curx = 0;  w->cury = 0;  w->o_curx = curx;  w->o_cury = cury;  w->o_attr = curattr;  w->o_color = curcolor;  w->o_cursor = _curstype;  w->direct = direct;  if (border != BNONE) {  	x1--; x2++;  	y1--; y2++;  }  /* Store whatever we are overlapping */  bytes = (y2 - y1 + 1) * (x2 - x1 + 1) * sizeof(ELM) + 100;  if ((e = (ELM *)malloc(bytes)) == (ELM *)0) {  	free(w);  	return((WIN *)0);  }  w->map = e;  /* How many bytes is one line */  bytes = (x2 - x1 + 1) * sizeof(ELM);  /* Loop */  for(y = y1; y <= y2; y++) {  	memcpy(e, gmap + COLS * y + x1, bytes);  	e += (x2 - x1 + 1);  }  #if HISTORY  /* Do we want history? */  w->histline = w->histlines = 0;  w->histbuf = (ELM *)0;  if (histlines) {	/* Reserve some memory. */	bytes = w->xs * histlines * sizeof(ELM);	if ((w->histbuf = (ELM *)malloc(bytes)) == NULL) {		free(w->map);		free(w);		return((WIN *)0);	}	w->histlines = histlines;	/* Clear the history buf. */	e = w->histbuf;	for(y = 0; y < w->xs * histlines; y++) {		e->value = ' ';		e->attr = attr;		e->color = color;		e++;	}  }#endif  /* And draw the window */  if (border) {	_write(border == BSINGLE ? S_UL : D_UL, w->direct, x1, y1,					xattr, color);	for(x = x1 + 1; x < x2; x++)		_write(border == BSINGLE ? S_HOR : D_HOR, w->direct, x, y1,					xattr, color);	_write(border == BSINGLE ? S_UR : D_UR, w->direct, x2, y1,					xattr, color);	for(y = y1 + 1; y < y2; y++) {		_write(border == BSINGLE ? S_VER : D_VER, w->direct, x1, y,					xattr, color);		for(x = x1 + 1; x < x2; x++)			_write(' ', w->direct, x, y, attr, color);		_write(border == BSINGLE ? S_VER : D_VER, w->direct, x2, y,					xattr, color);	}	_write(border == BSINGLE ? S_LL : D_LL, w->direct, x1, y2,					xattr, color);	for(x = x1 + 1; x < x2; x++)		_write(border == BSINGLE ? S_HOR : D_HOR, w->direct,					x, y2, xattr, color);	_write(border == BSINGLE ? S_LR : D_LR, w->direct, x2, y2,					xattr, color);	if (w->direct) _gotoxy(x1 + 1, y1 + 1);  } else  	if (doclr) winclr(w);  wcursor(w, CNORMAL);	  if (w->direct) wflush();  return(w);}/* * Close a window. */void wclose(win, replace)WIN *win;int replace;{  ELM *e;  int x, y;#ifdef SMOOTH  curwin = NIL_WIN;#endif  if (!win) return;  if (win == stdwin) {  	win_end();  	return;  }  e = win->map;  if (win->border) {  	win->x1--; win->x2++;  	win->y1--; win->y2++;  }  wcursor(win, win->o_cursor);  if (replace) {	for(y = win->y1; y <= win->y2; y++) {  		for(x = win->x1; x <= win->x2; x++) {  			_write(e->value, 1, x, y, e->attr, e->color);  			e++;  		} 	}	_gotoxy(win->o_curx, win->o_cury);	_setattr(win->o_attr, win->o_color);  }  free(win->map);  free(win);#if HISTORY  if (win->histbuf) free(win->histbuf);#endif  wflush();}static int oldx, oldy;static int ocursor;/* * Clear screen & restore keyboard modes */void wleave(){  oldx = curx;  oldy = cury;  ocursor = _curstype;  (void) setcbreak(0); /* Normal */  _gotoxy(0, LINES - 1);  _setattr(XA_NORMAL, COLATTR(WHITE, BLACK));  _cursor(CNORMAL);  if (CL != CNULL)	outstr(CL);  else	outstr("\n");#if ST_LINE  if (DS) outstr(DS);#endif  if (KE != CNULL) outstr(KE);  if (RS != CNULL) outstr(RS);  wflush();}void wreturn(){  int x, y;  ELM *e;#ifdef SMOOTH  curwin = NIL_WIN;#endif  curattr = -1;  curcolor = -1;  (void) setcbreak(1); /* Cbreak, no echo */  if (IS != CNULL) outstr(IS); /* Initialization string */  if (EA != CNULL) outstr(EA); /* Graphics init. */  if (KS != CNULL) outstr(KS); /* Keypad mode */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -