lnxscrn.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 467 行
C
467 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Screen support functions for the Linux debug client.
*
****************************************************************************/
#include "curses.h"
#define BOOL_DEFINED // curses.h typedefs 'bool'
#include "dbgdefn.h"
#include "dbgio.h"
#include "dbgmem.h"
#include <string.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#ifdef __WATCOMC__
#include <env.h>
#endif
#include <unistd.h>
#if 0
#include <sys/vt.h>
#endif
#include <sys/ioctl.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#include <errno.h>
#include "term.h"
#include "stdui.h"
#include "../unix/h/ctkeyb.h"
#include "dbgtoggl.h"
extern void StartupErr( char * );
extern int GUIInitMouse( int );
extern void GUIFiniMouse( void );
extern char *Format(char *,char *,... );
extern void ReleaseProgOvlay( bool );
extern void KillDebugger( int );
extern char *UITermType;
extern char XConfig[];
extern char *TxtBuff;
char *DbgTerminal;
unsigned DbgConsole;
unsigned PrevConsole;
unsigned InitConsole = -1;
int DbgConHandle;
int DbgLines;
int DbgColumns;
int PrevLines;
int PrevColumns;
pid_t XTermPid;
/* definitions which should be in sys/vt.h */
#define VT_OPENQRY 0x5600 /* find available vt */
#define VT_GETSTATE 0x5603 /* get global vt state info */
#define VT_ACTIVATE 0x5606 /* make vt active */
#define VT_WAITACTIVE 0x5607 /* wait for vt active */
#define VT_DISALLOCATE 0x5608 /* free memory associated to vt */
#define VT_RESIZE 0x5609 /* set kernel's idea of screensize */
struct vt_sizes {
unsigned short v_rows; /* number of rows */
unsigned short v_cols; /* number of columns */
unsigned short v_scrollsize; /* number of lines of scrollback */
};
struct vt_stat {
unsigned short v_active; /* active vt */
unsigned short v_signal; /* signal to send */
unsigned short v_state; /* vt bitmask */
};
/* ... */
enum { C_XWIN, C_VC, C_TTY, C_CURTTY } ConMode;
void RingBell( void )
{
write( DbgConHandle, "\a", 1 );
}
/*
* ConfigScreen -- figure out screen configuration we're going to use.
*/
unsigned ConfigScreen( void )
{
return( 0 );
}
/*
* InitScreen
*/
static void HupHandler( int signo )
{
/* Xqsh has gone away -- nothing to do except die */
signo = signo;
ReleaseProgOvlay( TRUE );
KillDebugger( 0 );
}
static bool TryXWindows( void )
{
int slavefd;
int masterfd;
char buff[64];
char **argv;
char *p;
char *end;
unsigned argc;
char slavename[] = "/dev/pts/xxxxxx";
int unlock = 0;
char buf;
int res;
struct termios termio;
/* we're in the X (or helper)environment */
if ( getenv("DISPLAY") == NULL )
return( FALSE );
masterfd = open("/dev/ptmx", O_RDWR);
if ( masterfd < 0 )
return( FALSE );
fcntl( masterfd, F_SETFD, 0 );
ioctl( masterfd, TIOCGPTN, &slavefd ); /* slavefd = ptsname(masterfd); */
ioctl( masterfd, TIOCSPTLCK, &unlock ); /* unlockpt(masterfd); */
sprintf(slavename + 9, "%d", slavefd);
slavefd = open(slavename, O_RDWR);
DbgConHandle = slavefd;
if( DbgConHandle == -1 ) {
StartupErr( "unable to open debugger console" );
return( FALSE );
}
tcgetattr(slavefd, &termio);
termio.c_lflag &= ~ECHO;
tcsetattr(slavefd, TCSANOW, &termio);
argc = 0;
p = XConfig;
for( ;; ) {
while( isspace( *p ) ) ++p;
while( !isspace( *p ) && *p != '\0' ) ++p;
if( *p == '\0' ) break;
++argc;
*p++ = '\0';
}
end = p;
_AllocA( argv, (argc + 16) * sizeof( *argv ) );
argv[0] = "xterm";
argv[1] = "-title";
argv[2] = "Open Watcom Debugger";
argv[3] = "-ut";
argc = 4;
if( DbgLines != 0 || DbgColumns != 0 ) {
argv[argc++] = "-geometry";
if( DbgLines == 0 ) DbgLines = 25;
if( DbgColumns == 0 ) DbgColumns = 80;
p = Format( buff, "%ux%u+0+0", DbgColumns, DbgLines ) + 1;
argv[argc++] = buff;
}
for( p = XConfig; p < end; p += strlen( p ) + 1 ) {
while( isspace( *p ) ) ++p;
argv[argc++] = p;
}
Format( p, "-SXX%u", masterfd );
argv[argc++] = p;
argv[argc] = NULL;
fcntl( slavefd, F_SETFD, FD_CLOEXEC );
XTermPid = fork();
if (XTermPid == 0) { /* child */
setpgid( 0, 0 );
execvp( argv[0], (const char **)argv );
exit( 1 );
}
if( XTermPid == (pid_t)-1 ) {
StartupErr( "unable to create console helper process" );
}
do { /* xterm transmits a window ID -- ignore */
res = read(slavefd, &buf, 1);
} while ( res != -1 && buf != '\n' );
termio.c_lflag |= ECHO;
tcsetattr(slavefd, TCSANOW, &termio);
/* make slavefd a controlling tty */
setpgid( 0, XTermPid );
setsid();
ioctl( slavefd, TIOCSCTTY, 1 );
signal( SIGHUP, &HupHandler );
return( TRUE );
}
static bool TryVC( void )
{
char *ptr;
struct vt_stat vt_state;
struct winsize winsize;
struct vt_sizes vt_sizes;
char tty_name[20];
int len;
len = readlink( "/proc/self/fd/0", tty_name, sizeof( tty_name ) - 1 );
if ( len < 0 )
return( FALSE );
tty_name[ len ] = '\0';
if( DbgConsole == 0 ) {
DbgConHandle = open( tty_name, O_RDWR );
if( DbgConHandle == -1 )
return( FALSE );
if( ioctl( DbgConHandle, VT_OPENQRY, &DbgConsole ) )
return( FALSE );
close( DbgConHandle );
}
ptr = &tty_name[ len ];
for( ;; ) {
--ptr;
if( *ptr < '0' || *ptr > '9' ) break;
}
sprintf ( ptr + 1, "%d", DbgConsole );
DbgConHandle = open( tty_name, O_RDWR );
if ( DbgConHandle == -1 )
return( FALSE );
if( ioctl( DbgConHandle, VT_GETSTATE, &vt_state ) )
return( FALSE );
InitConsole = vt_state.v_active;
ioctl( DbgConHandle, TIOCGWINSZ, &winsize );
PrevLines = winsize.ws_row;
PrevColumns = winsize.ws_col;
vt_sizes.v_rows = DbgLines;
vt_sizes.v_cols = DbgColumns;
ioctl( DbgConHandle, VT_RESIZE, &vt_sizes );
return( TRUE );
}
static bool TryTTY( void )
{
unsigned long num;
char *end;
if( DbgTerminal == NULL ) return( FALSE );
num = strtoul( DbgTerminal, &end, 10 );
if( *end == NULLCHAR && num < 100 ) {
DbgConsole = num;
return( FALSE );
}
/* guy gave an explicit terminal name */
end = strchr( DbgTerminal, ':' );
if( end != NULL ) {
/* and also told us the terminal type */
*end = NULLCHAR;
UITermType = strdup( end + 1 );
}
DbgConHandle = open( DbgTerminal, O_RDWR );
if( DbgConHandle == -1 ) {
StartupErr( "unable to open system console" );
}
return( TRUE );
}
void InitScreen( void )
{
extern bool DebugScreen( void );
if( setpgid( 0, 0 ) != 0 && errno != EPERM ) {
StartupErr( "unable to create new process group" );
}
if( TryTTY() ) {
ConMode = C_TTY;
} else if( TryVC() ) {
ConMode = C_VC;
} else if( TryXWindows() ) {
ConMode = C_XWIN;
} else {
/* backup: just use the current terminal */
ConMode = C_CURTTY;
DbgConHandle = -1;
}
_Free( DbgTerminal );
DbgTerminal = NULL;
if ( DbgConHandle != -1 ) {
fcntl( DbgConHandle, F_SETFD, (int)FD_CLOEXEC );
UIConFile = fdopen( DbgConHandle, "w+" );
UIConHandle = DbgConHandle;
}
if( !uistart() ) {
StartupErr( "unable to initialize user interface" );
}
if( _IsOn( SW_USE_MOUSE ) ) GUIInitMouse( 1 );
DebugScreen();
}
/*
* UsrScrnMode -- setup the user screen mode
*/
bool UsrScrnMode( void )
{
switch( ConMode ) {
case C_TTY:
return( TRUE );
default:
break;
}
return( FALSE );
}
void DbgScrnMode( void )
{
}
static int DebugPutc( int c )
{
return fputc( c, UIConFile );
}
/*
* DebugScreen -- swap/page to debugger screen
*/
bool DebugScreen( void )
{
extern bool UserForcedTermRefresh;
struct vt_stat vt_state;
switch( ConMode ) {
case C_TTY:
return( TRUE );
case C_CURTTY:
_physupdate( NULL );
UserForcedTermRefresh = TRUE;
tputs( enter_ca_mode, 1, DebugPutc );
break;
case C_VC:
ioctl( 0, VT_GETSTATE, &vt_state );
PrevConsole = vt_state.v_active;
ioctl( 0, VT_ACTIVATE, DbgConsole );
ioctl( 0, VT_WAITACTIVE, DbgConsole );
break;
default:
break;
}
return( FALSE );
}
bool DebugScreenRecover( void )
{
return( TRUE );
}
/*
* UserScreen -- swap/page to user screen
*/
bool UserScreen( void )
{
switch( ConMode ) {
case C_TTY:
return( TRUE );
case C_CURTTY:
tputs( exit_ca_mode, 1, DebugPutc );
break;
case C_VC:
ioctl( 0, VT_ACTIVATE, PrevConsole );
ioctl( 0, VT_WAITACTIVE, PrevConsole );
break;
default:
break;
}
return( FALSE );
}
void SaveMainWindowPos( void )
{
}
void FiniScreen( void )
{
struct vt_sizes vt_sizes;
if( _IsOn( SW_USE_MOUSE ) ) GUIFiniMouse();
uistop();
switch( ConMode ) {
case C_VC:
ioctl( 0, VT_ACTIVATE, InitConsole );
ioctl( 0, VT_WAITACTIVE, InitConsole );
vt_sizes.v_rows = PrevLines;
vt_sizes.v_cols = PrevColumns;
ioctl( 0, VT_RESIZE, &vt_sizes );
ioctl( 0, VT_DISALLOCATE, DbgConsole );
break;
case C_XWIN:
signal( SIGHUP, SIG_IGN );
kill( XTermPid, SIGTERM );
break;
default:
break;
}
}
void ScrnSpawnStart( void )
{
char *term;
if( InitConsole == -1 && UITermType != NULL ) {
term = getenv( "TERM" );
if( term == NULL ) term = "";
strcpy( TxtBuff, term );
setenv( "TERM", UITermType, 1 );
}
}
void ScrnSpawnEnd( void )
{
if( InitConsole == -1 && UITermType != NULL ) {
setenv( "TERM", TxtBuff, 1 );
}
}
/*****************************************************************************\
* *
* Replacement routines for User Interface library *
* *
\*****************************************************************************/
void PopErrBox( char *buff )
{
WriteText( STD_ERR, buff, strlen( buff ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?