📄 terminal.c
字号:
/* terminal.c -- Terminal code 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 "terminal.h"#include "screen.h"#include "ansi.h"#include "avatar.h"#include "vt100.h"#include "config.h"#include "modem.h"#include "phone.h"#include "window.h"#include "menu.h"#include "log.h"#include "utils.h"#include "filemgr.h"#include "setup.h"#include "error.h"#include <fcntl.h>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <ctype.h>#include <signal.h>int Online, Offline;tTermPhoneRec CurrentTerm;time_t Starttime;char EMSI_CHT[16], EMSI_ACK[16], EMSI_TCH[16], RING[2], RingStr[20];WINDOW *Remote, *Local, *Chat;chtype *Scrl;char CommandKey, ClosePort, Warned, Device;tList TagList;int Tagged;char *NameOfDialEntry;int DialIndex = 0;pid_t pid;tTag::tTag(){ Tag = 0;}void SigInt(int sig){ kill(pid, SIGKILL);}void PrintStatus(){ char Temp[50]; int i; time_t t; tm *Time; textAttr(Status, Integers[cStatus]); werase(Status); for (i=0;i<COLS;i++) waddch(Status, ' '); switch(Online?Integers[StatusStartOn]:Integers[StatusStartOff]){ case 0: if (Integers[EscType] == 1) strcpy(Temp, "Ctrl-Alt-A for help"); else strcpy(Temp, "Alt-A for help"); break; case 1: linestatus(); if (DSR) strcpy(Temp, "DSR"); else strcpy(Temp, "dsr"); if (DTR) strcat(Temp, "DTR "); else strcat(Temp, "dtr "); if (CAR) strcat(Temp, "CD"); else strcat(Temp, "cd"); if (ST) strcat(Temp, "ST"); else strcat(Temp, "st"); if (SR) strcat(Temp, "SR "); else strcat(Temp, "sr "); if (CTS) strcat(Temp, "CTS "); else strcat(Temp, "cts "); if (RNG) strcat(Temp, "R"); else strcat(Temp, "r"); break; case 2: strncpy(Temp, CurrentTerm.Name+1, CurrentTerm.Name[0]); Temp[CurrentTerm.Name[0]]=0; Temp[20] = 0; break; default:break; } waddstr(Status, Temp); wmove(Status, 0, 20); /* NOTE: DefaultDevice */ if (CurrentTerm.Device == 0) i = Integers[DefaultDevice-1]; else i = CurrentTerm.Device-1; if (i > 4) i = CurrentTerm.Device-1; if (strlen(Strings[Device1+i])>17){ strncpy(Temp, Strings[Device1+i], 17); Temp[17] = 0; } else strcpy(Temp, Strings[Device1+i]); waddch(Status, SVLINE); waddstr(Status, Temp); sprintf(Temp, " %lu %d%c%d", CurrentTerm.Baud, CurrentTerm.Databits, CurrentTerm.Parity, CurrentTerm.Stopbits+1); wmove(Status, 0, 48-strlen(Temp)-1); waddstr(Status, Temp); wmove(Status, 0, 48); sprintf(Temp, "%c %s", SVLINE, TermEmu[CurrentTerm.Terminal]); waddstr(Status,Temp); wmove(Status, 0, 62); if (Offline) switch(Integers[StatusEndOff]){ case 0: time(&t); Time = localtime(&t); sprintf(Temp, "%c Time %02d:%02d:%02d",SVLINE, Time->tm_hour, Time->tm_min, Time->tm_sec); break; default:break; } if (Online) switch(Integers[StatusEndOn]){ case 0: time(&t); Time = localtime(&t); sprintf(Temp, "%c Time %02d:%02d:%02d",SVLINE, Time->tm_hour, Time->tm_min, Time->tm_sec); break; case 1: time(&t); t-=Starttime; sprintf(Temp, "%c Online %02lu:%02lu:%02lu",SVLINE, t / 3600, t / 60, t % 60); break; default:break; } waddstr(Status, Temp); wrefresh(Status); if (EMSI_CHT[0] != 15) wrefresh(Screen); else wrefresh(Local);}void GetFileName(WINDOW *Window, char *Str, char *Headline, char *Instr){ tWindow *Win; char Temp[40]; int Center, sx, sy; getyx(Window, sy, sx); Center = findCenter(0, COLS, 40); Win = new tWindow(Window, Center, LINES/2-1, Center+40, LINES/2+1, Integers[cMenu] >> 4, Integers[cMenu] % 16); Win->Frame(2, Integers[cMenu]); Win->Headline(Headline, Integers[cMenuTitle]); wrefresh(Window); if (getstring(Window, LINES/2, Center+1, Instr, FileEdit, "\n\e", 39, -1, Temp) == '\n') strcpy(Str, Temp); else strcpy(Str, ""); delete Win; wmove(Window, sy, sx);}void WarnOnline(){ tWindow *Win; int Center, Y, X, Attr; char Temp[10]; time_t Time; Warned = 1; time(&Time); Attr = Screen->_attrs; getyx(Screen, Y, X); Center = findCenter(0, COLS, 28); Win = new tWindow(Screen, Center-3, LINES/2-2, Center+31, LINES/2+2, Integers[cInfo] >> 4, Integers[cInfo] % 16); Win->Frame(2, Integers[cInfo]); textAttr(Screen, Integers[cInfoBold]); mvwaddstr(Screen, LINES/2, Center, "You have been online for"); sprintf(Temp, "%lu", (Time-Starttime) / 60); mvwaddstr(Screen, LINES/2, Center+24, Temp); wrefresh(Screen); sleep(1); delete Win; wmove(Screen, Y, X); Screen->_attrs = Attr; if (EMSI_CHT[0] == 15){ clearok(Remote, TRUE); clearok(Local, TRUE); redrawwin(Remote); redrawwin(Local); wrefresh(Remote); wrefresh(Local); }}void Hangup(){ tWindow *Win; int Center, Y, X; getyx(Screen, Y, X); Center = findCenter(0, COLS, 10); Win = new tWindow(Screen, Center-3, LINES/2-2, Center+13, LINES/2+2, Integers[cInfo] >> 4, Integers[cInfo] % 16); Win->Frame(2, Integers[cInfo]); textAttr(Screen, Integers[cInfoBold]); mvwaddstr(Screen, LINES/2, Center, "Hanging up"); wrefresh(Screen); hangup(); Printlogln("Manual hangup"); delete Win; wmove(Screen, Y, X);}void ShowEcho(){ tWindow *Win; int Center, Y, X; getyx(Screen, Y, X); Center = findCenter(0, COLS, 11); Win = new tWindow(Screen, Center-3, LINES/2-2, Center+14, LINES/2+2, Integers[cInfo] >> 4, Integers[cInfo] % 16); Win->Frame(2, Integers[cInfo]); textAttr(Screen, Integers[cInfoBold]); mvwaddstr(Screen, LINES/2, Center, "Local Echo"); if (Integers[GlobalLocalEcho]) mvwaddstr(Screen, LINES/2, Center+11, "On"); else mvwaddstr(Screen, LINES/2, Center+11, "Off"); wrefresh(Screen); sleep(1); delete Win; wmove(Screen, Y, X);}void ShowStrip(){ tWindow *Win; int Center, Y, X; getyx(Screen, Y, X); Center = findCenter(0, COLS, 11); Win = new tWindow(Screen, Center-3, LINES/2-2, Center+14, LINES/2+2, Integers[cInfo] >> 4, Integers[cInfo] % 16); Win->Frame(2, Integers[cInfo]); textAttr(Screen, Integers[cInfoBold]); mvwaddstr(Screen, LINES/2, Center, "Strip high"); if (Integers[GlobalStripHigh]) mvwaddstr(Screen, LINES/2, Center+11, "On"); else mvwaddstr(Screen, LINES/2, Center+11, "Off"); wrefresh(Screen); sleep(1); delete Win; wmove(Screen, Y, X);}void SendBreak(){ tWindow *Win; int Center, Y, X; getyx(Screen, Y, X); Center = findCenter(0, COLS, 13); Win = new tWindow(Screen, Center-3, LINES/2-2, Center+15, LINES/2+2, Integers[cInfo] >> 4, Integers[cInfo ]% 16); Win->Frame(2, Integers[cInfo]); textAttr(Screen, Integers[cInfoBold]); mvwaddstr(Screen, LINES/2, Center, "Sending break"); wrefresh(Screen); sbreak(); delete Win; wmove(Screen, Y, X);}void ImageSave(WINDOW *Window){ char Temp[40], Buffer[COLS*(LINES-1)]; int Handle, y, x, Y, X; getyx(Window, Y, X); GetFileName(Window, Temp, "Image file", "TERMITE.IMAGE"); if (strlen(Temp)>0){ if ((Handle = open(Temp, O_CREAT | O_RDWR)) > 0){ for (y=0;y<LINES-1;y++) for (x=0;x<COLS;x++) Buffer[y*COLS+x] = mvwinch(Window, y, x) & A_CHARTEXT; write(Handle, Buffer, sizeof(Buffer)); close(Handle); } else WindowError(Window, "Unable to open file"); } Printlog("Image save: "); Printlogln(Temp); curs_set(1); wmove(Window, Y, X);}void OpenCapture(WINDOW *Window){ char Temp[40], TempStr[255]; tWindow *Win; int Center, Y, X; int mode; if (!CaptureOn){ PasToChar(CurrentTerm.Capture, Temp); if (strlen(Temp) > 0) GetFileName(Window, Temp, "Capture file", Temp); else GetFileName(Window, Temp, "Capture file", "TERMITE.CAPTURE"); OpenCaptureFile(Window, &Temp[0]); curs_set(1); } else { getyx(Window, Y, X); Center = findCenter(0, COLS, 17); Win = new tWindow(Window, Center-3, LINES/2-2, Center+19, LINES/2+2, Integers[cInfo] >> 4, Integers[cInfo] % 16); Win->Frame(2, Integers[cInfo]); textAttr(Window, Integers[cInfoBold]); mvwaddstr(Window, LINES/2, Center, "Capture is closed"); wrefresh(Window); delete Win; wmove(Window, Y, X); Printlogln("Capture closed"); CaptureOn = 0; write(CaptureHandle, CaptureStart, CapturePtr-CaptureStart); close(CaptureHandle); }}void ChangeDevice(){ Device = CurrentTerm.Device = ChooseDevice(Screen, CurrentTerm.Device, 1); CurrentTerm.Parity = Integers[Parities1+CurrentTerm.Device-1]; CurrentTerm.Baud = Integers[Bauds1+CurrentTerm.Device-1]; CurrentTerm.Stopbits = Integers[Stopbits1+CurrentTerm.Device-1]; CurrentTerm.Databits = Integers[Databits1+CurrentTerm.Device-1]; resetModem(); closeModem(); unlock(Strings[Device1+Device-1]); initModem(Strings[Device1+Device-1], CurrentTerm.Baud); setparms(CurrentTerm.Baud, CurrentTerm.Parity, CurrentTerm.Databits, CurrentTerm.Stopbits, Integers[FlowCtrl1+Device-1]);}void Upload(){ tWindow *Win; tMenu *Menu; int i, y, x, Key, Attr, hangup; char Temp[256], TempStr[256], PWD[256]; char *FilesToUpload; nl(); getyx(Screen, y, x); Attr = Screen->_attrs; Win = new tWindow(Screen, COLS/2-15, LINES/3-3, COLS/2+35, LINES/3+3, Integers[cMenu] >> 4, Integers[cMenu] % 16); Win->Frame(2, Integers[cMenu]); Win->Headline("Upload", Integers[cMenuTitle]); Menu = new tMenu(Screen, Integers[cMenuText], Integers[cMenuHot], Integers[cMenuBar], Integers[cMenuText], ALIGNLEFT); for (i=0;i<5;i++){ Menu->Add(Strings[ProtocolName1+i], COLS/2-14, COLS/2, i+LINES/3-2); textAttr(Screen, Integers[cMenuText]); mvwaddstr(Screen, i+LINES/3-2, COLS/2+1, Strings[ProtocolInfo1+i]); } Menu->Show(); curs_set(0); wrefresh(Screen); Key = 0; while (Key != '\e' && Key != '\n'){ Key = getEscChar(); Menu->GetInput(Key); } if (Key == '\n'){ getcwd(PWD, 255); if (Integers[ChangeUl1+Menu->Focus]) if (chdir(Strings[UploadPath]) < 0) WindowError(Screen, "Unable to chdir"); FileMgr(&FilesToUpload, Strings[UploadPath], 1); clearok(Screen, TRUE); redrawwin(Screen); wrefresh(Screen); if (strlen(FilesToUpload) > 0){ nl(); hangup = ChooseYesno(Screen, "Hangup after transfer"); CurrentTerm.UploadKb += UploadSize / 1024; SavePhonebook(); strcpy(TempStr, "Uploading in "); strcat(TempStr, Strings[ProtocolName1+Menu->Focus]); Printlogln(TempStr); Printlogln(FilesToUpload); strcpy(TempStr, Strings[ProtocolUlExec1+Menu->Focus]); ProtocolParser(TempStr, Strings[UploadPath], Strings[Device1+CurrentTerm.Device-1], CurrentTerm.Baud, FilesToUpload); clear(); refresh(); signal(SIGINT, SigInt); system(TempStr); signal(SIGINT, SIG_DFL); chdir(PWD); redrawwin(Screen); clearok(Screen, TRUE); wrefresh(Status); wrefresh(Screen); if (hangup) Hangup(); } free(FilesToUpload); } delete Menu; delete Win; curs_set(1); nonl(); wmove(Screen, y, x); Screen->_attrs = Attr;}void Download(){ tWindow *Win; tMenu *Menu; int i, y, x, Key, Attr, hangup; char Temp[256], TempStr[256], PWD[256]; nl(); getyx(Screen, y, x); Attr = Screen->_attrs; Win = new tWindow(Screen, COLS/2-15, LINES/3-3, COLS/2+35, LINES/3+3, Integers[cMenu] >> 4, Integers[cMenu] % 16); Win->Frame(2, Integers[cMenu]); Win->Headline("Download", Integers[cMenuTitle]); Menu = new tMenu(Screen, Integers[cMenuText], Integers[cMenuHot], Integers[cMenuBar], Integers[cMenuText], ALIGNLEFT); for (i=0;i<5;i++){ Menu->Add(Strings[ProtocolName1+i], COLS/2-14, COLS/2, i+LINES/3-2); textAttr(Screen, Integers[cMenuText]); mvwaddstr(Screen, i+LINES/3-2, COLS/2+1, Strings[ProtocolInfo1+i]); } Menu->Show(); curs_set(0); wrefresh(Screen); Key = 0; while (Key != '\e' && Key != '\n'){ Key = getEscChar(); Menu->GetInput(Key); } if (Key == '\n'){ getcwd(PWD, 255); if (Integers[ChangeDl1+Menu->Focus]) if (chdir(Strings[DownloadPath]) < 0) WindowError(Screen, "Unable to chdir"); strcpy(TempStr, "Downloading in "); strcat(TempStr, Strings[ProtocolName1+Menu->Focus]); Printlogln(TempStr); if (Integers[ProtocolAsk1+Menu->Focus]) GetFileName(Screen, Temp, "Filename to download", ""); else strcpy(Temp, ""); Printlogln(Temp); nl(); hangup = ChooseYesno(Screen, "Hangup after transfer"); strcpy(TempStr, Strings[ProtocolDlExec1+Menu->Focus]); ProtocolParser(TempStr, Strings[DownloadPath], Strings[Device1+CurrentTerm.Device-1], CurrentTerm.Baud, Temp); clear(); refresh(); system(TempStr); chdir(PWD); clearok(Screen, TRUE); redrawwin(Screen); wrefresh(Status); wrefresh(Screen); if (hangup) Hangup(); } delete Menu; delete Win; curs_set(1); nonl(); wmove(Screen, y, x); Screen->_attrs = Attr;}void SetTerminal(){ switch(CurrentTerm.Terminal){ case 0: Ansi = 1; Avatar = 1; vt100 = 0; break; case 1: Ansi = 0; Avatar = 1; vt100 = 0; break; case 2: Ansi = 1; Avatar = 0; vt100 = 0; break; case 3: Ansi = 0; Avatar = 0; vt100 = 1; break; case 4: Ansi = 0; Avatar = 0; vt100 = 0; break; default:break; }}void AutoDownload(int Protocol){ char PWD[256], Temp[256], Filename[40]; Printlogln("Auto-download initiated"); clear(); refresh(); getcwd(PWD, 255); if (Integers[ChangeDl1+Protocol]) if(chdir(Strings[DownloadPath]) < 0) WindowError(Screen, "Unable to chdir"); if (!Integers[ProtocolAsk1+Protocol]) Filename[0]=0; else{ strcpy(Temp, Strings[ProtocolName1+Protocol]); strcat(Temp, ": Filename to download"); GetFileName(Screen, Filename, Temp, ""); } strcpy(Temp, Strings[ProtocolDlExec1+Protocol]); ProtocolParser(Temp, Strings[DownloadPath], Strings[Device1+CurrentTerm.Device-1], CurrentTerm.Baud,Filename); system(Temp); chdir(PWD); redrawwin(Screen); wrefresh(Status); wrefresh(Screen);}void Phone(){ int Key; ShowTerm(); ShowTermBook(1); curs_set(0); wrefresh(PhoneScreen); nl(); Key = 0; while (Key != 27 && !DialerConnect){ Key = getEscChar(); TermPhoneKey(Key); wrefresh(PhoneScreen); } DialerConnect = 0; curs_set(1); nonl(); redrawwin(Screen);}void DeleteTagList(){ tTag *Tmp, *Next; Tmp = (tTag *)TagList.Base; while (Tmp != NULL){ Next = (tTag *)Tmp->Next; delete Tmp; Tmp = Next; } TagList.Base = NULL;}void WipeLine(WINDOW *Window, WINDOW *Tag, int Y, int Line0, int Line1, int Line2){ chtype ch; int i, Color; Color = (int)(BLUE << 4) + YELLOW + 8; for (i=0;i<Line1;i++){ ch = mvwinch(Window, Y, i+Line0); if (Line2) textAttr(Tag, Color); else wattrset(Tag, ch & (A_COLOR | A_ATTRIBUTES)); ch &= A_CHARTEXT; mvwaddch(Tag, Y, i+Line0, ch);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -