tdisp.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,614 行 · 第 1/4 页
C
1,614 行
/****************************************************************************
*
* 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 <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/seginfo.h>
#include <sys/dev.h>
#include <sys/osinfo.h>
#include <sys/sidinfo.h>
#include <sys/psinfo.h>
#include <sys/kernel.h>
#include <sys/sendmx.h>
#include <sys/proxy.h>
#include <sys/vc.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <i86.h>
#include <assert.h>
#include <ctype.h>
#include <sys/qnx_glob.h>
#include <process.h>
#include <term.h>
#define tparm __tparm
#include "uidef.h"
#include "uiattrs.h"
#include "qdebug.h"
#include "uivirt.h"
#include "qnxuiext.h"
#include "tixparse.h"
#ifdef __386__
#define _fmemcpy memcpy
#endif
extern char *GetTermType(void);
// this is handy for those functions that do *almost* the same thing
// for the two terminal types
static bool TermIsQNXTerm;
bool UserForcedTermRefresh= FALSE;
bool TermCheck()
/***************/
{
extern unsigned UIDisableShiftChanges;
char *term;
term = GetTermType();
if( strstr( term, "qnx" ) == 0 ) return( FALSE );
UIDisableShiftChanges = TRUE;
TermIsQNXTerm = TRUE;
return( TRUE );
}
bool TInfCheck()
/***************/
{
extern unsigned UIDisableShiftChanges;
// Check to see if the term variable is set
if( GetTermType()[0]!='\0' ){
UIDisableShiftChanges= TRUE;
TermIsQNXTerm= FALSE;
return( TRUE );
}
return( FALSE );
}
/*-
* Mini buffered IO code...
*/
struct ostream {
char *sbuf, *ebuf;
char *curp;
int fd;
};
static struct ostream _con_out;
static ostream_init(int f)
{
if ((_con_out.sbuf = malloc(2048)) == 0) {
return( FALSE );
}
_con_out.ebuf = _con_out.sbuf + 2048;
_con_out.curp = _con_out.sbuf;
_con_out.fd = f;
return TRUE;
}
#define __putchar(_c) ((_con_out.curp < _con_out.ebuf) ? \
(*_con_out.curp++ = (_c)) : __oflush(_c))
static __flush(void)
{
int len = _con_out.curp - _con_out.sbuf;
int offs = 0;
while (len > 0) {
int n = write(_con_out.fd, _con_out.sbuf+offs, len);
if (n < 0) {
break;
}
offs += n;
len -= n;
}
_con_out.curp = _con_out.sbuf;
}
static __oflush(int c)
{
__flush();
//assert( _con_out.curp < _con_out.ebuf );
return __putchar(c);
}
static __puts(char *s)
{
int c;
if( s==NULL )return;
while ((c=*s++)) __putchar(c);
}
/*-
* Qnx terminal codes
*/
#define _ESC "\033"
#define QNX_CURSOR_OFF() __puts(_ESC "y0")
#define QNX_CURSOR_NORMAL() __puts(_ESC "y1")
#define QNX_CURSOR_BOLD() __puts(_ESC "y2")
#define QNX_BOLD() __puts(_ESC "<")
#define QNX_NOBOLD() __puts(_ESC ">")
#define QNX_BLINK() __puts(_ESC "{")
#define QNX_NOBLINK() __puts(_ESC "}")
#define QNX_ULINE() __puts(_ESC "[")
#define QNX_WRAP() __puts(_ESC "h")
#define QNX_NOWRAP() __puts(_ESC "i")
#define QNX_RESTORE_ATTR() __puts(_ESC "R")
#define QNX_NOULINE() __puts(_ESC "]")
#define QNX_HOME() __puts(_ESC "H")
#define QNX_CLS() __puts("\f")
/*-
* set initial mode of term
*/
static QNX_CURSOR_MOVE(register int c, register int r)
{
__putchar(033); __putchar('=');
__putchar(r+' ');
__putchar(c+' ');
}
static QNX_SETCOLOUR(register int f, register int b)
{
__putchar(033); __putchar('@');
__putchar('0' + f);
__putchar('0' + b);
}
// This is basically a rewrite of the putp that's supposed to appear in
// term.h, except it uses our "mini buffered IO code" from above
static void putp( char *s )
{
int c;
int pad;
int mand= FALSE;
int i;
char *bbuf;
if( s==NULL )return;
while( c= *s++ ){
// check and see if we're at the start of a padding sequence
if( c=='$' && *s=='<' ){
bbuf= s;
s++;
pad= 0;
// read until the end of the sequence or the end of the string
while( ( c= *s++ )&&( c!='>' ) ){
// suck up digits
if( c>= '0' && c<= '9' ){
pad*= 10;
pad+= c;
} else if( c=='.' ){
// Skip tenth's
if( ( c= *s )>= '0' && c<= '9' ){
s++;
// cheap rounding
if( c>= '5' ){
pad++;
}
}
// Pay attention to the mandatory flag
} else if( c=='/' ){
mand= TRUE;
}
// Note that I'm completely ignoring the * flag( proportional
// to number of lines padding ). I'm just assuming 1 line
// always. This should work virtually all of the time because
// we don't do anything excessively weird. ( like insert over
// multiple lines )
// Actually, we ignore any extra chars that end up in here.
}
if( c=='>' ){
// output padding only if required
if( !xon_xoff || mand ){
mand= FALSE;
for( i= 0; i<pad; i++ ){
__putchar( pad_char[0] );
}
}
} else {
__putchar( '$' );
__puts( bbuf );
return;
}
} else {
__putchar( c );
}
}
}
// Whether to use code-changing optimizations in ti
static bool OptimizeTerminfo= TRUE;
/* TermInfo terminal codes
*/
// The following are used to remember which attrs we want
static bool TIABold= 0; // bold
static bool TIABlink= 0; // blinking
static bool TIAULine= 0; // underline
static bool TIARev= 0; // inverted (reverse)
static bool TIAACS= 0; // alternate character set
// True if clearing/filling operations will use the current back colour
static TI_FillColourSet= FALSE;
// Macros for various terminfo capabilities
#define TI_CURSOR_OFF() putp( cursor_invisible )
#define TI_CURSOR_NORMAL() putp( cursor_normal )
#define TI_CURSOR_BOLD() putp( cursor_visible )
#define TI_BOLD() ( TIABold= 1, putp( enter_bold_mode ) )
#define TI_NOBOLD() ( TIABold= 0, TI_SETATTR() )
#define TI_REVERSE() ( TIARev= 1, TI_SETATTR() )
#define TI_NOREVERSE() ( TIARev= 0, TI_SETATTR() )
#define TI_BLINK() ( TIABlink= 1, putp( enter_blink_mode ) )
#define TI_NOBLINK() ( TIABlink= 0, TI_SETATTR() )
#define TI_ULINE() ( TIAULine= 1, putp( enter_underline_mode ) )
#define TI_NOULINE() ( TIAULine= 0, putp( exit_underline_mode ) )
#define TI_ACS_ON() ( TIAACS= 1, putp( enter_alt_charset_mode ) )
#define TI_ACS_OFF() ( TIAACS= 0, \
((exit_alt_charset_mode[0]!='\0')\
?(void)(putp( exit_alt_charset_mode ) )\
:(void)(TI_SETATTR()) ))
#define TI_WRAP() putp( enter_am_mode )
#define TI_NOWRAP() putp( exit_am_mode )
#define TI_CA_ENABLE() putp( enter_ca_mode )
#define TI_CA_DISABLE() putp( exit_ca_mode )
#define TI_RESTORE_ATTR() ( TIAACS= TIABold= TIABlink= TIAULine= 0, \
putp( exit_attribute_mode ) )
#define TI_RESTORE_COLOUR() ( putp( ( orig_pair[0]=='\0' )\
?orig_colors:orig_pair ) )
#define TI_ENABLE_ACS() putp( ena_acs )
#define TI_HOME() TI_CURSOR_MOVE( 0, 0 );
// This weird "do...while" thing is so that TI_CLS acts like a statement
#define TI_CLS() do{ \
if( clear_screen[0]!='\0' ){ \
putp( clear_screen ); \
OldRow= OldCol= 0; \
} else { \
TI_HOME(); \
putp( clr_eos ); \
} \
} while(0)
#define TI_INIT1_STRING() putp( init_1string )
#define TI_INIT2_STRING() putp( init_2string )
#define TI_INIT3_STRING() putp( init_3string )
#define TI_RESET1_STRING() putp( reset_1string )
#define TI_RESET2_STRING() putp( reset_2string )
#define TI_RESET3_STRING() putp( reset_3string )
#define TI_CLEAR_MARGINS() putp( clear_margins )
/* Terminal Capabilities
*/
// True if terminal is monochrome
#define TCAP_MONOCHROME ( set_color_pair[0]=='\0' && set_background[0]=='\0' )
// True if terminal won't scroll on us
#define TCAP_NOSCROLL ( !auto_right_margin || \
(exit_am_mode[0]!='\0') )
// True if terminal can clear screen fast
#define TCAP_CLS ( clear_screen[0]!='\0' || \
clr_eos[0]!='\0' )
static unsigned TI_repeat_cutoff = ~0;
static bool TI_ignore_bottom_right= TRUE;
/* Find out where using the repeat_char code becomes efficient if we
* are going to be doing optimizations.
*/
static void ti_find_cutoff( void )
{
if( repeat_char[0]!='\0' && OptimizeTerminfo ){
int i;
for( i=2; i<80; i++ ){
if( strlen( tparm( repeat_char, 'X', i ) )<i ){
TI_repeat_cutoff= i;
break;
}
}
}
}
/* Repeat character c, n times. "a" indicates alternate character set.
* x is the first column that we should be printing on. (used for a little
* optimization)
*/
static void TI_REPEAT_CHAR( char c, int n, int a, ORD x )
{
bool blank;
int len;
char *cparm_right;
if(n==0)return;
blank= OptimizeTerminfo && (TI_FillColourSet) && c==' ' && !a;
if( blank
&& x==(UIData->width-n)
&& (len=strlen(clr_eol))>0
&& n>len ){
putp( clr_eol );
} else if( blank
&& x==0
&& clr_bol[0]!='\0'
&& n>(len=(strlen( cparm_right=tparm( parm_right_cursor, n ))+strlen(clr_bol)))
&& len>0 ){
putp( cparm_right );
putp( clr_bol );
} else {
if(a){
TI_ACS_ON();
}
if( n>=TI_repeat_cutoff ){
putp( tparm( repeat_char, c, n ) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?