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 + -
显示快捷键?