qnxscrn.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 402 行
C
402 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include "dbgdefn.h"
#include "dbgio.h"
#include "dbgmem.h"
#include <env.h>
#include <stdui.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/console.h>
#include <sys/dev.h>
#include <sys/psinfo.h>
#include <sys/sidinfo.h>
#include <sys/kernel.h>
#include <sys/vc.h>
#include <fcntl.h>
#include <process.h>
#include <signal.h>
#include <ctype.h>
#include <errno.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 unsigned UIConHandle;
extern char *UITermType;
extern char XConfig[];
extern char *TxtBuff;
char *DbgTerminal;
unsigned DbgConsole;
unsigned PrevConsole;
unsigned InitConsole;
int DbgConHandle;
int DbgLines;
int DbgColumns;
int PrevLines;
int PrevColumns;
struct _console_ctrl *ConCtrl;
pid_t XQshPid;
enum { C_XWIN, C_QCON, C_TTY } ConMode;
void RingBell()
{
write( DbgConHandle, "\a", 1 );
}
/*
* ConfigScreen -- figure out screen configuration we're going to use.
*/
unsigned ConfigScreen()
{
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()
{
char xqsh_name[CMD_LEN];
int pip[2];
char buff[64];
char **argv;
int len;
char *p;
char *end;
unsigned argc;
/* we're in the X Windows (or helper)environment */
if( pipe( pip ) != 0 ) {
StartupErr( "unable to create console control channel" );
}
fcntl( pip[0], F_SETFD, (int)FD_CLOEXEC );
searchenv( "qnxterm", "PATH", xqsh_name );
if( xqsh_name[0] == '\0' ) {
StartupErr( "qnxterm executable not in PATH" );
}
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 + 10) * sizeof( *argv ) );
argv[0] = xqsh_name;
argv[1] = "-T";
argv[2] = "WATCOM Debugger";
argc = 3;
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;
}
argv[argc++] = "-tty";
Format( p, "%u", pip[1] );
argv[argc++] = p;
argv[argc] = NULL;
XQshPid = qnx_spawn( 0, 0, 0, -1, -1, _SPAWN_NEWPGRP,
argv[0], argv, environ, NULL, 0 );
if( XQshPid == (pid_t)-1 ) {
StartupErr( "unable to create console helper process" );
}
/* close the write pipe here so that the read fails if xqsh aborts */
close( pip[1] );
len = read( pip[0], buff, sizeof( buff ) );
if( len == -1 ) {
StartupErr( "console helper process unable to initialize" );
}
close( pip[0] );
buff[len] = '\0';
DbgConHandle = open( buff, O_RDWR );
if( DbgConHandle == -1 ) {
StartupErr( "unable to open debugger console" );
}
UITermType = "qnx";
tcsetct( DbgConHandle, getpid() );
signal( SIGHUP, &HupHandler );
return( TRUE );
}
static bool TryQConsole()
{
struct _psinfo psinfo;
struct _sidinfo info;
struct _dev_info_entry dev;
char *ptr;
char *term;
if( qnx_psinfo( PROC_PID, getpid(), &psinfo, 0, 0 ) != getpid() ) {
StartupErr( "unable to obtain process information" );
}
if( qnx_sid_query( PROC_PID, psinfo.sid, &info ) != psinfo.sid ) {
StartupErr( "unable to obtain console name" );
}
ptr = &info.tty_name[ strlen( info.tty_name ) ];
for( ;; ) {
--ptr;
if( *ptr < '0' || *ptr > '9' ) break;
}
if( DbgConsole != 0 ) {
ptr[ 1 ] = '0' + DbgConsole / 10;
ptr[ 2 ] = '0' + DbgConsole % 10;
ptr += 2;
}
ptr[1] = NULLCHAR;
DbgConHandle = open( info.tty_name, O_RDWR );
if( DbgConHandle == -1 ) {
StartupErr( "unable to open system console" );
}
term = getenv( "TERM" );
if( term != NULL && strcmp( term, "qnxw" ) == 0 ) {
/* in QNX windows */
#define PROP_STRING "\033\"pwd\""
write( DbgConHandle, PROP_STRING, sizeof( PROP_STRING ) - 1 );
}
ConCtrl = console_open( DbgConHandle, O_WRONLY );
if( ConCtrl == NULL ) {
close( DbgConHandle );
return( FALSE );
}
if( dev_info( DbgConHandle, &dev ) == -1 ) {
StartupErr( "unable to obtain console information" );
}
DbgConsole = dev.unit;
console_size( ConCtrl, DbgConsole, 0, 0, &PrevLines, &PrevColumns );
console_size( ConCtrl, DbgConsole, DbgLines, DbgColumns, 0, 0 );
InitConsole = console_active( ConCtrl, -1 );
return( TRUE );
}
static bool TryTTY()
{
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()
{
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( TryQConsole() ) {
ConMode = C_QCON;
} else if( TryXWindows() ) {
ConMode = C_XWIN;
} else {
StartupErr( "unable to initialize debugger screen" );
}
_Free( DbgTerminal );
DbgTerminal = NULL;
fcntl( DbgConHandle, F_SETFD, (int)FD_CLOEXEC );
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()
{
switch( ConMode ) {
case C_TTY:
return( TRUE );
}
return( FALSE );
}
void DbgScrnMode()
{
}
/*
* DebugScreen -- swap/page to debugger screen
*/
bool DebugScreen()
{
switch( ConMode ) {
case C_TTY:
return( TRUE );
case C_QCON:
PrevConsole = console_active( ConCtrl, DbgConsole );
break;
}
return( FALSE );
}
bool DebugScreenRecover()
{
return( TRUE );
}
/*
* UserScreen -- swap/page to user screen
*/
bool UserScreen()
{
switch( ConMode ) {
case C_TTY:
return( TRUE );
case C_QCON:
console_active( ConCtrl, PrevConsole );
break;
}
return( FALSE );
}
void SaveMainWindowPos()
{
}
void FiniScreen()
{
if( _IsOn( SW_USE_MOUSE ) ) GUIFiniMouse();
uistop();
switch( ConMode ) {
case C_QCON:
console_active( ConCtrl, InitConsole );
console_size( ConCtrl, DbgConsole, PrevLines, PrevColumns, NULL, NULL );
console_close( ConCtrl );
break;
case C_XWIN:
signal( SIGHUP, SIG_IGN );
kill( XQshPid, SIGTERM );
break;
}
}
void ScrnSpawnStart( void )
{
char *term;
if( ConCtrl == NULL && UITermType != NULL ) {
term = getenv( "TERM" );
if( term == NULL ) term = "";
strcpy( TxtBuff, term );
setenv( "TERM", UITermType, 1 );
}
}
void ScrnSpawnEnd( void )
{
if( ConCtrl == NULL && 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 + -
显示快捷键?