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

📄 window.c

📁 minicom的源码,linux下常用的串口程序.
💻 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. * * 01.01.98 dickey@clark.net: fix for a history window closing bug * fmg 8/20/97: Added support for Search of History Buffer */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include "rcsid.h"RCSID("$Id: window.c,v 1.18 2005/11/06 19:20:57 al-guest Exp $")#include <limits.h>#include <stdarg.h>#include <wchar.h>#include "port.h"#include "minicom.h"#include "intl.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 */#ifdef __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 const char *CM, *IS, *RS, *AC, *EA;static const char *ME, *SE, *UE, *AE;static const char *AS, *MB, *MD, *MR, *SO, *US;static const char *CE, *Al, *Dl, *AL, *DL;static const char *CS, *SF, *SR, *VB, *BL;static const char *VE, *VI, *KS, *KE;static const char *CD, *CL, *IC, *DC;static const char *CR, *NL;#ifdef ST_LINEstatic const 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 = NULL;WIN *us;#endifint useattr = 1;int dirflush = 1;int LINES, COLS;int usecolor = 0;WIN *stdwin;/* * The following is an external pointer to the termcap info. * If it's NOT zero then the main program has already * read the termcap for us. No sense in doing it twice. */char *_tptr = NULL;int screen_ibmpc = 0;int screen_iso = 0;int w_init = 0;int use_status = 0; /* Turned on in main() *//* Standard vt100 map (ac cpability) */static const char *def_ac = "+\273,\253aaffggjjkkllmmnnooqqssttuuvvwwxx";#ifdef DEBUG/* * Debug to stdout */int debug(char *s, ...){  char lala[80];  va_list ap;  va_start(ap, s);  vsnprintf(lala, sizeof(lala), s, ap);  va_end(ap);  write(2, lala, strlen(lala));  return 0;}#endif/* ===== Low level routines ===== *//* * Flush the screen buffer */void wflush(void){  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(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(const char *s){  tputs(s, 1, outchar);}/* * Turn off all attributes */static void _attroff(void){  if (ME != NULL)    outstr(ME);  else {    if (SE != NULL)      outstr(SE);    if (UE != NULL)      outstr(UE);  }  if (AE != NULL)    outstr(AE);}/* * Turn some attributes on */static void _attron(char attr){  if (!usecolor || (attr & XA_REVERSE) == 0) {    /* Reverse standout does not look too good.. */    if (attr & XA_BOLD	&& MD != NULL)      outstr(MD);    if (attr & XA_STANDOUT && SO != NULL)      outstr(SO);    if (attr & XA_UNDERLINE && US != NULL)      outstr(US);  }  if (attr & XA_REVERSE	&& MR != NULL)    outstr(MR);  if (attr & XA_BLINK && MB != NULL)    outstr(MB);  if (attr & XA_ALTCHARSET && AS != NULL)    outstr(AS);}/* * Set the colors */static void _colson(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(char attr, char 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(int x, int y){  int oldattr = -1;#ifdef 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 != NULL && y == cury && x == 0)    outstr(CR);#if 0 /* Hmm, sometimes NL only works in the first column */  else if (NL != NULL && x == curx && y == cury + 1)    outstr(NL);#else  else if (NL != NULL && x == 0 && x == curx && y == cury + 1)    outstr(NL);#endif  else if (BC != NULL && 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(wchar_t c, int doit, int x, int y, char attr, char 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;  }#ifdef ST_LINE  if (x < COLS && y <= LINES)#else  if (x < COLS && y < LINES)#endif  {    if (doit != 0) {      static int x0 = -1, y0 = -1, c0 = 0;      static char attr0, color0;      if (x!=x0+1 || y!=y0 || attr!=attr0 || color!=color0 || !(c0&128)) {        _gotoxy(x, y);        _setattr(attr, color);      }      x0 = x; y0 = y; attr0 = attr; color0 = color; c0 = c;      if ((attr & XA_ALTCHARSET) != 0)	outchar((char)c);      else {	char buf[MB_LEN_MAX];	size_t i, len;        len = one_wctomb(buf, c);        for (i = 0; i < (size_t)len; i++)        outchar(buf[i]);      }      curx++;    }    if (doit >= 0) {      e = &gmap[x + y * COLS];      e->value = c;      e->attr = attr;      e->color = color;    }  }}/* * Set cursor type. */static void _cursor(int type){  _curstype = type;  if (type == CNORMAL && VE != NULL)    outstr(VE);  if (type == CNONE && VE != NULL && VI != NULL)    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 *win, int lines, int cols){  int x, y;  ELM *oldmap, *newmap, *e, *n;  if ((newmap = malloc((lines + 1) * cols * sizeof(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. */WIN *wopen(int x1, int y1, int x2, int y2, int border, int attr,           int fg, int bg, int direct, int histlines, int doclr){  WIN *w;  ELM *e;  int bytes;  int x, y;  int color;  int offs;  int xattr;#ifdef SMOOTH  curwin = NULL;#endif  if ((w = malloc(sizeof(WIN))) == NULL)    return w;  offs = (border != BNONE);  if (!screen_ibmpc && AS)    xattr = attr | XA_ALTCHARSET;  else    xattr = attr;  if (x1 > x2)    swap(x1, x2);  if (y1 > y2)    swap(y1, y2);  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  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 = malloc(bytes)) == NULL) {	free(w);	return NULL;  }  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);  }  /* Do we want history? */  w->histline = w->histlines = 0;  w->histbuf = NULL;  if (histlines) {    /* Reserve some memory. */    bytes = w->xs * histlines * sizeof(ELM);    if ((w->histbuf = malloc(bytes)) == NULL) {      free(w->map);      free(w);      return NULL;    }    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++;    }  }  /* 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 *win, int replace){  ELM *e;  int x, y;#ifdef SMOOTH  curwin = NULL;#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++) {      /* temporal way to avoid 'half-character' problem */      /* in multibyte characters such as Japanese -- from here */      ELM *g;      g = gmap + (y * stdwin->xs);      for (x = 0 ; x < win->x1; x++) {        _write(g->value, 1, x, y, g->attr, g->color);        g++;      }      /* to here */      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);  if (win->histbuf)    free(win->histbuf);  free(win);	/* 1.1.98 dickey@clark.net  */  wflush();}static int oldx, oldy;static int ocursor;/* * Clear screen & restore keyboard modes */void wleave(void){  oldx = curx;  oldy = cury;  ocursor = _curstype;  setcbreak(0); /* Normal */  _gotoxy(0, LINES - 1);  _setattr(XA_NORMAL, COLATTR(WHITE, BLACK));  _cursor(CNORMAL);  if (CL != NULL)    outstr(CL);  else    outstr("\n");#ifdef ST_LINE  if (DS)    outstr(DS);#endif  if (KE != NULL)    outstr(KE);  if (RS != NULL)    outstr(RS);  wflush();}void wreturn(void){  int x, y;  ELM *e;#ifdef SMOOTH  curwin = NULL;#endif  curattr = -1;  curcolor = -1;  setcbreak(1); /* Cbreak, no echo */  if (IS != NULL)    outstr(IS); /* Initialization string */  if (EA != NULL)    outstr(EA); /* Graphics init. */  if (KS != NULL)    outstr(KS); /* Keypad mode */  _gotoxy(0, 0);  _cursor(ocursor);  e = gmap;  for (y = 0; y <LINES; y++) {    for(x = 0; x < COLS; x++) {      _write(e->value, -1, x, y, e->attr, e->color);      e++;    }  }  _gotoxy(oldx, oldy);

⌨️ 快捷键说明

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