📄 tscreen.cc
字号:
* Ps = 0 -> use string as a new icon name and title
* Ps = 1 -> use string is a new icon name only
* Ps = 2 -> use string is a new title only
* Ps = 46 -> use string as a new log file name
*/
// if (getenv("DISPLAY") != NULL) cout << "\033]2;TurboVision\007";
/*
* Environment variable support.
* Date: Wed, 29 Jan 1997 16:51:40 +0100 (MET)
*/
char env[PATH_MAX] = "", *p;
if ((p = getenv("TVOPT")) != NULL)
{
LOG("environment variable TVOPT=" << p);
for (char *d = env; *p != '\0'; p++)
*d++ = tolower(*p);
}
/* acquire screen size */
winsize win;
ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
if (win.ws_col > 0 && win.ws_row > 0)
{
screenWidth = win.ws_col;
screenHeight = win.ws_row;
}
else
{
LOG("unable to detect screen size");
screenWidth = 80;
screenHeight = 25;
}
#ifdef __FreeBSD__
/*
* Kludge: until we find a right way to fix the "last-line" display
* problem, this is a solution.
*/
screenHeight--;
#endif
LOG("screen size is " << (int) screenWidth << "x" <<
(int) screenHeight);
screenBuffer = (int) new ushort[screenWidth * screenHeight];
/* vcs stuff */
vcs_fd = -1;
if (strstr(env, "novcs") != NULL) LOG("vcs support disabled");
else
{
/*
* This approach was suggested by:
* Martynas Kunigelis <algikun@santaka.sc-uni.ktu.lt>
* Date: Mon, 20 Jan 1997 15:55:14 +0000 (EET)
*/
FILE *statfile;
char path[PATH_MAX];
sprintf(path, "/proc/%d/stat", getpid());
if ((statfile = fopen(path, "r")) != NULL)
{
int dev;
/* TTYs have 4 as major number */
/* virtual consoles have minor numbers <= 63 */
fscanf(statfile, "%*d %*s %*c %*d %*d %*d %d", &dev);
if ((dev & 0xff00) == 0x0400 && (dev & 0xff) <= 63)
{
LOG("virtual console detected");
sprintf(path, "/dev/vcsa%d", dev & 0xff);
if ((vcs_fd = open(path, O_RDWR)) < 0)
{
LOG("unable to open " << path <<
", running in stdout mode");
}
}
fclose(statfile);
}
}
port_access = !ioperm(0x3b4, 7, 1);
if (port_access)
{
unsigned char is_mda = (inb(0x3ba) & 0x70) >> 4;
is_mda = (is_mda == 0) || (is_mda == 1) || (is_mda == 5);
if (is_mda)
{
mono_mem_desc = open("/dev/mem",O_RDWR);
if (mono_mem_desc != -1)
{
mono_mem = (unsigned short *)mmap(NULL,80*25*2,PROT_READ|PROT_WRITE,
MAP_SHARED,mono_mem_desc,0xB0000);
}
}
}
/* Don't need special rights anymore */
seteuid(getuid());
setegid(getgid());
/* internal stuff */
// in = out = &queue[0];
// timeout_auto = -1;
// timeout_esc = -1;
timeout_wakeup = timer_value = 0;
if (vcs_fd < 0)
// Fill the screenBuffer with spaces
{
int i,len = screenWidth*screenHeight;
for (i=0;i<len;i++)
((ushort *)screenBuffer)[i] = 0x0720;
}
#if 0
resume();
#else
SaveScreen();
startcurses();
setVideoMode(screenMode);
TScreen_suspended = 0;
#endif
}
void TScreen::resume()
{
if (!TScreen_suspended) return;
if (!dual_display)
{
SaveScreen();
}
setVideoMode(screenMode);
/* Restore the terminal attributes. */
/* for our screen */
tcsetattr (tty_fd, TCSANOW, &new_term);
TScreen_suspended = 0;
}
TScreen::~TScreen()
{
#if 0
suspend();
#else
tcsetattr (STDOUT_FILENO, TCSANOW, &old_term);
// FIXME: When I know, how to get the cursor state
setCursorType(0x0607); // make the cursor visible
stopcurses();
if (!TScreen_suspended)
{
RestoreScreen();
}
TScreen_suspended = 1;
#endif
delete[] (ushort *)screenBuffer;
LOG("terminated");
if (vcs_fd >= 0) close(vcs_fd);
if (mono_mem)
{
munmap(mono_mem, 80*25*2);
mono_mem = NULL;
}
if (mono_mem_desc != -1)
{
close(mono_mem_desc);
mono_mem_desc = -1;
}
}
void TScreen::suspend()
{
if (TScreen_suspended) return;
old_col = old_back = old_fore = -1;
// FIXME: When I know, how to get the cursor state
setCursorType(0x0607); // make the cursor visible
/* Restore the terminal attributes. */
/* for the user screen */
tcsetattr (STDOUT_FILENO, TCSANOW, &old_term);
if (!dual_display)
{
RestoreScreen();
}
TScreen_suspended = 1;
}
ushort TScreen::fixCrtMode( ushort mode )
{
return mode;
}
void TScreen::setCrtData()
{
if (dual_display)
{
screenMode = 7;
screenWidth = 80;
screenHeight = 25;
cursorLines = 0x0b0c;
}
else
{
screenMode = getCrtMode();
screenWidth = getCols();
screenHeight = getRows();
hiResScreen = Boolean(screenHeight > 25);
if (screenMode == 7)
cursorLines = 0x0b0c;
else
cursorLines = 0x0607;
setCursorType( 0x2000 );
}
}
void TScreen::clearScreen()
{
TDisplay::clearScreen( screenWidth, screenHeight );
}
void TScreen::setVideoMode( ushort mode )
{
if (screenBuffer)
delete[] (ushort *)screenBuffer;
setCrtMode( fixCrtMode( mode ) );
setCrtData();
// allocating a zeroed screenBuffer, because this function
// is called in most cases (in RHIDE) after a SIGWINCH
screenBuffer = (int) new ushort[screenWidth * screenHeight];
memset((void *)screenBuffer,0,screenWidth*screenHeight*sizeof(ushort));
}
void TScreen::setCursorType(ushort ct)
{
if (dual_display || screenMode == 7)
{
if (ct == 0x2000) // cursor off
{
O(0x0a,0x01);
O(0x0b,0x00);
}
else
{
O(0x0a,ct >> 8);
O(0x0b,ct & 0xff);
}
}
else
TDisplay::setCursorType(ct);
}
ushort TScreen::getCursorType()
{
if (dual_display || screenMode == 7)
{
unsigned short ct;
ct = (I(0x0a) << 8) | I(0x0b);
if (!ct) ct = 0x2000;
return ct;
}
else
return TDisplay::getCursorType();
}
ushort TScreen::getRows()
{
return dual_display ? 25 : TDisplay::getRows();
}
ushort TScreen::getCols()
{
return dual_display ? 80 : TDisplay::getCols();
}
void TScreen::getCharacter(unsigned offset,ushort *buf,unsigned count)
{
if (dual_display)
{
memcpy(buf, mono_mem+offset, count*sizeof(ushort));
return;
}
if (vcs_fd >= 0) /* use vcs */
{
lseek(vcs_fd, offset * sizeof(ushort) + 4, SEEK_SET);
read(vcs_fd, buf, count*sizeof(ushort));
}
else /* standard out */
{
memcpy(buf,(ushort *)screenBuffer+offset,count*sizeof(ushort));
}
}
ushort TScreen::getCharacter(unsigned dst)
{
ushort src;
getCharacter(dst,&src,1);
return src;
}
void TScreen::setCharacter(unsigned offset,ushort value)
{
setCharacter(offset,&value,1);
}
/*
* Draws a line of text on the screen.
*/
void TScreen::setCharacter(unsigned dst,ushort *src,unsigned len)
{
if (dual_display)
{
memcpy(mono_mem+dst, src, len*sizeof(ushort));
return;
}
if (vcs_fd >= 0) /* use vcs */
{
lseek(vcs_fd, dst * sizeof(ushort) + 4, SEEK_SET);
write(vcs_fd, src, len * sizeof(ushort));
}
else /* standard out */
{
ushort *old = (ushort *)screenBuffer + dst;
ushort *old_right = old + len - 1;
ushort *src_right = src + len - 1;
/* remove unchanged characters from left to right */
if (!force_redraw)
{
while (len > 0 && *old == *src)
{
dst++;
len--;
old++;
src++;
}
/* remove unchanged characters from right to left */
while (len > 0 && *old_right == *src_right)
{
len--;
old_right--;
src_right--;
}
}
/* write only middle changed characters */
if (len > 0) writeBlock(dst, len, old, src);
}
}
#endif // __linux__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -