📄 screen.c
字号:
/* screen.c -- Screen and output routines Copyright (C) 1996 Nadav Cohen 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. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "screen.h"#include <string.h>#include "config.h"#include <ctype.h>#include <unistd.h>#include <signal.h>#include <stdlib.h>WINDOW *Screen;WINDOW *Status;WINDOW *PhoneScreen;WINDOW *FileScreen;WINDOW *ScrollScreen;//bool hasColor;int hasColor;int blinkAttr, lightAttr;int fgCol, bgCol, GlobalAttr;int LastKey;char ValidEdit[47] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9','^','!','~',' ','.',',','-','&','=','\0'};char FileEdit[46] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z', '0','1','2','3','4','5','6','7','8','9','.','/','!','@','^','-','+','~','\0'};char NumberEdit[16] = {'0','1','2','3','4','5','6','7','8','9','-',',','+','#',':','\0'};char HexEdit[17] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','\0'};chtype *ScrollBuffer, *ScrollPtr, *ScrollStart;int ScrollY, ScrollX, ScrollBackLength;int CaptureHandle, CaptureOn, CaptureX, CaptureY;char *CapturePtr, *CaptureStart;char *XCursesProgramName = "firework";/* colortoattr() - this function accepts a "DOS-mode" color, and returns its value according to the ncurses colors table (check the manual.doc) */int colortoattr(int color){ switch (color) { case 0: return(COLOR_BLACK); case 1: return(COLOR_BLUE); case 2: return(COLOR_GREEN); case 3: return(COLOR_CYAN); case 4: return(COLOR_RED); case 5: return(COLOR_MAGENTA); case 6: return(COLOR_YELLOW); case 7: return(COLOR_WHITE); default: return(COLOR_BLACK); }}/* init_pairs() - Inits the 64 color pairs to be like in "DOS-mode", meaning: pair 0 = BLACK-BLACK, pair 1 = BLACK-BLUE, etc */void initPairs(){ int i,j; for (j=0;j<8;j++) for (i=0;i<8;i++) { init_pair(j+(8*i),colortoattr(j),colortoattr(i)); }}/* textcolor() - changes the color of the current forgeground. color is a "DOS-mode" color */void textColor(WINDOW *Win, int color){ if (hasColor){ fgCol = color; if (color > 128) { color-=128; blinkAttr = A_BLINK; } else blinkAttr = 0; if (color > 7) { color-=8; lightAttr = A_BOLD; } else lightAttr = A_NORMAL; GlobalAttr = lightAttr | blinkAttr | A_ALTCHARSET; wattrset(Win,COLOR_PAIR(fgCol+(bgCol*8)) | lightAttr | blinkAttr | A_ALTCHARSET); }}/* textbackground() - changes the color of the current background. color is a "DOS-mode" color */void textBkgd(WINDOW *Win, int color){ int col; if (hasColor){ col = fgCol; if (col > 128) { col-=128; blinkAttr = A_BLINK; } else blinkAttr = 0; if (col > 7) { col-=8; lightAttr = A_BOLD; } else lightAttr = A_NORMAL; if (color > 7) { blinkAttr = A_BLINK; color-=8; } bgCol = color; GlobalAttr = lightAttr | blinkAttr | A_ALTCHARSET; wattrset(Win,COLOR_PAIR(col+(bgCol*8))| lightAttr | blinkAttr | A_ALTCHARSET); }}void textAttr(WINDOW *Win, int color){ if (hasColor){ textColor(Win, color % 16); textBkgd(Win, color >> 4); }}void swaddch(WINDOW *Window, chtype Ch){ int i; char c; if (Window == Screen){ c = Ch & A_CHARTEXT; if (c != '\n' && c != '\r'){ *ScrollPtr++ = Ch | Screen->_attrs; if (CaptureOn) *CapturePtr++ = Ch & A_CHARTEXT; } else { for (i=ScrollX;i<COLS;i++){ *ScrollPtr++ = ' ' | Screen->_bkgd; if (CaptureOn) *CapturePtr++ = ' '; } } ScrollY = (ScrollPtr-ScrollStart) / COLS; ScrollX = (ScrollPtr-ScrollStart) % COLS; if (CaptureOn){ CaptureY = (CapturePtr-CaptureStart) / COLS; CaptureX = (CapturePtr-CaptureStart) % COLS; if (CaptureY == LINES-1){ if (!Integers[SaveControl]) write(CaptureHandle, CaptureStart, COLS); memcpy(CaptureStart, CaptureStart+COLS, (LINES-1-1)*COLS); CapturePtr = CaptureStart+(LINES-1-1)*COLS; for (i=0;i<COLS;i++) *(CapturePtr+i) = ' '; } } if (ScrollY == LINES-1) ScrollStart+=COLS; if (ScrollPtr >= ScrollBuffer+ScrollBackLength){ memmove(ScrollBuffer, ScrollBuffer+COLS, (ScrollBackLength-COLS)*sizeof(chtype)); ScrollPtr -= COLS; for (i=0;i<COLS;i++) *(ScrollPtr+i)= ' ' | Screen->_bkgd; ScrollStart -= COLS; } } if (Ch > 31 || Ch == '\n' || Ch == '\r') waddch(Window, Ch);}void swaddstr(WINDOW *Window, char *Str){ waddstr(Window, Str);}void swmove(WINDOW *Window, int y, int x){ int i; if (Window == Screen){ ScrollY = y; ScrollX = x; ScrollPtr = ScrollStart + y*COLS + x; if (CaptureOn){ CaptureY = y; CaptureX = x; CapturePtr = CaptureStart + y*COLS + x; } if (ScrollY == LINES-1) ScrollStart+=COLS; if (ScrollPtr >= ScrollBuffer+ScrollBackLength){ if (ScrollStart+(LINES-1)*COLS>ScrollBuffer+ScrollBackLength){ memmove(ScrollBuffer, ScrollBuffer+(ScrollStart+(LINES-1)*COLS-ScrollBuffer-ScrollBackLength), ScrollBackLength-(ScrollStart+(LINES-1)*COLS-ScrollBuffer-ScrollBackLength)); ScrollStart = ScrollBuffer+ScrollBackLength-(LINES)*COLS; ScrollPtr = ScrollStart; } for (i=0;i<COLS*(LINES-1);i++) *(ScrollPtr+i)= ' ' | Screen->_bkgd; } } wmove(Window, y, x);}void smvwaddch(WINDOW *Window, int y, int x, chtype Ch){ chtype *Save; char *SaveCapture; if (Window == Screen){ Save = ScrollPtr; ScrollPtr = y*COLS+x+ScrollStart; *ScrollPtr = Ch | Screen->_attrs; ScrollPtr = Save; if (CaptureOn){ SaveCapture = CapturePtr; CapturePtr = y*COLS+x+CaptureStart; *CapturePtr = Ch & A_CHARTEXT; CapturePtr = SaveCapture; } } mvwaddch(Window, y, x, Ch);}void smvwaddstr(WINDOW *Window, int y, int x, char *Str){ mvwaddstr(Window, y, x, Str);}void swclear(WINDOW *Window){ int i; if (Window == Screen){ for (i=ScrollX;i<COLS;i++){ *ScrollPtr++ = ' ' | Screen->_bkgd; } if (!Integers[SaveControl] && CaptureOn) write(CaptureHandle, CaptureStart, CapturePtr-CaptureStart); if (CaptureOn){ CapturePtr = CaptureStart; for (i=0;i<(LINES-1)*COLS;i++) *(CapturePtr+i) = ' '; CaptureY = 0; CaptureX = 0; } ScrollStart = ScrollPtr; if (ScrollStart+(LINES-1)*COLS>ScrollBuffer+ScrollBackLength){ memmove(ScrollBuffer, ScrollBuffer+(ScrollStart+(LINES-1)*COLS-ScrollBuffer-ScrollBackLength), ScrollBackLength-(ScrollStart+(LINES-1)*COLS-ScrollBuffer-ScrollBackLength)); ScrollStart -= (ScrollStart+(LINES-1)*COLS-ScrollBuffer-ScrollBackLength); ScrollPtr = ScrollStart; for (i=0;i<COLS*(LINES-1);i++) *(ScrollPtr+i)= ' ' | Screen->_bkgd; } ScrollY = (ScrollPtr-ScrollStart) / COLS; ScrollX = (ScrollPtr-ScrollStart) % COLS; if (ScrollY == LINES-1) ScrollStart+=COLS; if (ScrollPtr >= ScrollBuffer+ScrollBackLength){ memmove(ScrollBuffer, ScrollBuffer+COLS, (ScrollBackLength-COLS)*sizeof(chtype)); ScrollPtr -= COLS; for (i=0;i<COLS;i++) *(ScrollPtr+i)= ' ' | Screen->_bkgd; ScrollStart -= COLS; } } wclear(Window);}void swclrtoeol(WINDOW *Window){ int i; if (Window == Screen){ for (i=0;i<COLS-ScrollX;i++){ *(ScrollPtr+i) = ' ' | Screen->_bkgd; if (CaptureOn) *(CapturePtr+i) = ' '; } } wclrtoeol(Window);}void swclrtobot(WINDOW *Window){ int i; if (Window == Screen){ for (i=ScrollX;i>0;i--){ *(ScrollPtr-i) = ' ' | Screen->_bkgd; if (CaptureOn) *(CapturePtr-i) = ' '; } } wclrtobot(Window);}void initScreen(){ int i; // signal(SIGTTOU, SIG_IGN); initscr(); noecho(); raw(); keypad(stdscr, TRUE); nonl(); hasColor = has_colors(); if (hasColor == FALSE) fprintf(stderr, "Warning: This terminal does not support colors."); else start_color(); initPairs(); Screen = newwin(LINES-1,COLS,0,0); scrollok(Screen, TRUE); Status = newwin(1, COLS, LINES-1, 0); scrollok(Status, FALSE); PhoneScreen = newwin(LINES-1,COLS,0,0); scrollok(PhoneScreen, FALSE); FileScreen = newwin(LINES-1,COLS,0,0); scrollok(FileScreen, FALSE); ScrollScreen = newwin(LINES-1,COLS,0,0); scrollok(ScrollScreen, FALSE); ScrollBackLength = Integers[ScrollBackSize]*COLS; ScrollStart = ScrollPtr = ScrollBuffer = (chtype *)malloc(ScrollBackLength*sizeof(chtype)); ScrollY = ScrollX = 0; for (i=0;i<COLS*Integers[ScrollBackSize];i++) *(ScrollBuffer+i) = ' ' | Screen->_attrs; CaptureStart = CapturePtr = (char *)malloc(COLS*(LINES)); for (i=0;i<COLS*(LINES-1);i++) *(CapturePtr+i) = ' '; textColor(Screen, WHITE); textBkgd(Screen, BLACK);}void closeScreen(){ delwin(Screen); delwin(PhoneScreen); delwin(Status); delwin(FileScreen); endwin(); curs_set(1);}int findCenter(int X1, int X2, int Len){ return ((X2-X1+1)/2-Len/2+X1);}void insertchar(char *s,char ch,int place,int insertmode){ char dummy[255]; int i; if (!insertmode) { strcpy(dummy,s); if (dummy[place] == '\0') dummy[place+1] = '\0'; dummy[place] = ch; strcpy(s,dummy); return; } strncpy(dummy,s,place+1); dummy[place] = ch; for (i=0;i<place;i++,s++); strcpy(&dummy[place+1],s); for (i=0;i<place;i++,s--); strcpy(s,dummy);}void deletechar(char *s,int place){ int i; char dummy[255]; strncpy(dummy,s,place); for (i=0;i<=place;i++,s++); strcpy(&dummy[place],s); for (i=0;i<=place;i++,s--); strcpy(s,dummy);}char getstring(WINDOW *Win, int y,int x, char *instr,char *usestr,char *exitstr,int len,int pl,char *putin){ int ch,pos=pl,tailpos; int insertmode=1; char dummy[255]; int fcol, bcol; fcol = fgCol; bcol = bgCol; textColor(Win, Integers[cEdit] % 16); textBkgd(Win, Integers[cEdit] >> 4); strcpy(dummy,instr); if (pos==-1) pos=strlen(dummy); tailpos=strlen(dummy); wmove(Win, y, x); whline(Win, Integers[EditBack],len); mvwaddstr(Win, y, x, dummy); wmove(Win, y, x+pos); curs_set(1); wrefresh(Win); do { ch = getEscChar(); switch (ch) { case '\b': case KEY_BACKSPACE: if (pos>0) { tailpos--; deletechar(dummy,--pos); } break; case KEY_LEFT : if (pos > 0) pos--; break; case KEY_RIGHT : if (pos < tailpos) pos++; break; case KEY_DC : if (pos < tailpos) { deletechar(dummy,pos); tailpos--; } break; case KEY_IC : insertmode = 1; break; case KEY_EIC : insertmode = 0; break; case KEY_HOME : pos = 0; break; case KEY_END: if (strlen(dummy) < len) pos = strlen(dummy); else pos = strlen(dummy)-1; break; default : if (index(exitstr,ch)!=NULL) break; if ((pos<len) && (index(usestr,ch) != NULL || index(usestr,tolower(ch)) != NULL)) { if (insertmode) tailpos++; else if (tailpos==pos) tailpos++; insertchar(dummy,ch,pos++,insertmode); } break; } if (dummy[len] != '\0') dummy[len]='\0'; wmove(Win, y, x); whline(Win, Integers[EditBack] ,len); mvwaddstr(Win, y, x, dummy); wmove(Win, y, x+pos); wrefresh(Win); } while (index(exitstr,ch)==NULL); if (ch == '\e') strcpy(dummy,instr); wmove(Win, y, x); textColor(Win, fcol); textBkgd(Win, bcol); whline(Win,' ',len); mvwaddstr(Win,y,x,dummy); strcpy(putin,dummy); curs_set(0); return ch;}int getEscChar(){ int c; c = getch(); if (Integers[EscType] == 1) { if (LastKey == 27 && c == 27) { c = getch(); } }// else if (LastKey == 27) c = getch(); LastKey = c; return c;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -