biosqnx.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 471 行

C
471
字号
/****************************************************************************
*
*                            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:  BIOS emulation routines for QNX.
*
****************************************************************************/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/seginfo.h>
#include <sys/console.h>
#include <sys/con_msg.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 "vi.h"
#include "dosx.h"
#include "pragmas.h"
#include "win.h"
#include "keys.h"

struct                  _console_ctrl *QNXCon;
int                     QNXConHandle;
unsigned int            QNXConsole;
struct termios          SaveTermSet;
int                     SaveTermProtocol;
pid_t                   Proxy;
extern pid_t            _my_pid;


struct map {
    char        qnx;
    char        event;
};

static struct map events[] = {
    { 0x80,     VI_KEY( SHIFT_TAB )     },
    { 0x81,     VI_KEY( F1 )            },
    { 0x82,     VI_KEY( F2 )            },
    { 0x83,     VI_KEY( F3 )            },
    { 0x84,     VI_KEY( F4 )            },
    { 0x85,     VI_KEY( F5 )            },
    { 0x86,     VI_KEY( F6 )            },
    { 0x87,     VI_KEY( F7 )            },
    { 0x88,     VI_KEY( F8 )            },
    { 0x89,     VI_KEY( F9 )            },
    { 0x8a,     VI_KEY( F10 )           },
    { 0x8b,     VI_KEY( SHIFT_F1 )      },
    { 0x8c,     VI_KEY( SHIFT_F2 )      },
    { 0x8d,     VI_KEY( SHIFT_F3 )      },
    { 0x8e,     VI_KEY( SHIFT_F4 )      },
    { 0x8f,     VI_KEY( SHIFT_F5 )      },
    { 0x90,     VI_KEY( SHIFT_F6 )      },
    { 0x91,     VI_KEY( SHIFT_F7 )      },
    { 0x92,     VI_KEY( SHIFT_F8 )      },
    { 0x93,     VI_KEY( SHIFT_F9 )      },
    { 0x94,     VI_KEY( SHIFT_F10 )     },
    { 0x95,     VI_KEY( CTRL_F1 )       },
    { 0x96,     VI_KEY( CTRL_F2 )       },
    { 0x97,     VI_KEY( CTRL_F3 )       },
    { 0x98,     VI_KEY( CTRL_F4 )       },
    { 0x99,     VI_KEY( CTRL_F5 )       },
    { 0x9a,     VI_KEY( CTRL_F6 )       },
    { 0x9b,     VI_KEY( CTRL_F7 )       },
    { 0x9c,     VI_KEY( CTRL_F8 )       },
    { 0x9d,     VI_KEY( CTRL_F9 )       },
    { 0x9e,     VI_KEY( CTRL_F10 )      },
    { 0x9f,     VI_KEY( CTRL_TAB )      },
    { 0xa0,     VI_KEY( HOME )          },
    { 0xa1,     VI_KEY( UP )            },
    { 0xa2,     VI_KEY( PAGEUP )        },
    { 0xa3,     '-'                     },
    { 0xa4,     VI_KEY( LEFT )          },
    { 0xa5,     '5'                     },
    { 0xa6,     VI_KEY( RIGHT )         },
    { 0xa7,     '+'                     },
    { 0xa8,     VI_KEY( END )           },
    { 0xa9,     VI_KEY( DOWN )          },
    { 0xaa,     VI_KEY( PAGEDOWN )      },
    { 0xab,     VI_KEY( INS )           },
    { 0xac,     VI_KEY( DEL )           },
//  { 0xad,     VI_KEY( prtscr )        },
    { 0xae,     VI_KEY( F11 )           },
    { 0xaf,     VI_KEY( F12 )           },
    { 0xb0,     VI_KEY( CTRL_HOME )     },
    { 0xb1,     VI_KEY( CTRL_UP )       },
    { 0xb2,     VI_KEY( CTRL_PAGEUP )   },
    { 0xb3,     '-'                     },
    { 0xb4,     VI_KEY( CTRL_LEFT )     },
    { 0xb5,     '5'                     },
    { 0xb6,     VI_KEY( CTRL_RIGHT )    },
    { 0xb7,     '+'                     },
    { 0xb8,     VI_KEY( CTRL_END )      },
    { 0xb9,     VI_KEY( CTRL_DOWN )     },
    { 0xba,     VI_KEY( CTRL_PAGEDOWN ) },
    { 0xbb,     VI_KEY( CTRL_INS )      },
    { 0xbc,     VI_KEY( CTRL_DEL )      },
//  { 0xbd,     VI_KEY( ctrl-prtscr )   },
    { 0xbe,     VI_KEY( CTRL_F11 )      },
    { 0xbf,     VI_KEY( CTRL_F12 )      },
    { 0xc0,     VI_KEY( ALT_HOME )      },
    { 0xc1,     VI_KEY( ALT_UP )        },
    { 0xc2,     VI_KEY( ALT_PAGEUP )    },
    { 0xc3,     '-'                     },
    { 0xc4,     VI_KEY( ALT_LEFT )      },
    { 0xc5,     '5'                     },
    { 0xc6,     VI_KEY( ALT_RIGHT )     },
    { 0xc7,     '+'                     },
    { 0xc8,     VI_KEY( ALT_END )       },
    { 0xc9,     VI_KEY( ALT_DOWN )      },
    { 0xca,     VI_KEY( ALT_PAGEDOWN )  },
    { 0xcb,     VI_KEY( ALT_INS )       },
    { 0xcc,     VI_KEY( ALT_DEL )       },
//    { 0xcd,   VI_KEY(   alt-prtscr )  },
    { 0xce,     VI_KEY( ALT_F11 )       },
    { 0xcf,     VI_KEY( ALT_F12 )       },
    { 0xd0,     0x0a                    },
    { 0xd1,     VI_KEY( ALT_F1 )        },
    { 0xd2,     VI_KEY( ALT_F2 )        },
    { 0xd3,     VI_KEY( ALT_F3 )        },
    { 0xd4,     VI_KEY( ALT_F4 )        },
    { 0xd5,     VI_KEY( ALT_F5 )        },
    { 0xd6,     VI_KEY( ALT_F6 )        },
    { 0xd7,     VI_KEY( ALT_F7 )        },
    { 0xd8,     VI_KEY( ALT_F8 )        },
    { 0xd9,     VI_KEY( ALT_F9 )        },
    { 0xda,     VI_KEY( ALT_F10 )       },
    { 0xdb,     VI_KEY( SHIFT_F11 )     },
    { 0xdc,     VI_KEY( SHIFT_F12 )     },
//  { 0xdd,     VI_KEY( sysrq )         },
    { 0xe1,     VI_KEY( ALT_A )         },
    { 0xe2,     VI_KEY( ALT_B )         },
    { 0xe3,     VI_KEY( ALT_C )         },
    { 0xe4,     VI_KEY( ALT_D )         },
    { 0xe5,     VI_KEY( ALT_E )         },
    { 0xe6,     VI_KEY( ALT_F )         },
    { 0xe7,     VI_KEY( ALT_G )         },
    { 0xe8,     VI_KEY( ALT_H )         },
    { 0xe9,     VI_KEY( ALT_I )         },
    { 0xea,     VI_KEY( ALT_J )         },
    { 0xeb,     VI_KEY( ALT_K )         },
    { 0xec,     VI_KEY( ALT_L )         },
    { 0xed,     VI_KEY( ALT_M )         },
    { 0xee,     VI_KEY( ALT_N )         },
    { 0xef,     VI_KEY( ALT_O )         },
    { 0xf0,     VI_KEY( ALT_P )         },
    { 0xf1,     VI_KEY( ALT_Q )         },
    { 0xf2,     VI_KEY( ALT_R )         },
    { 0xf3,     VI_KEY( ALT_S )         },
    { 0xf4,     VI_KEY( ALT_T )         },
    { 0xf5,     VI_KEY( ALT_U )         },
    { 0xf6,     VI_KEY( ALT_V )         },
    { 0xf7,     VI_KEY( ALT_W )         },
    { 0xf8,     VI_KEY( ALT_X )         },
    { 0xf9,     VI_KEY( ALT_Y )         },
    { 0xfa,     VI_KEY( ALT_Z )         },
};

#pragma off (unreferenced);
void BIOSGetColorPalette( void far *a ) {}
long BIOSGetColorRegister( short a ) { return( 0 ); }
void BIOSSetNoBlinkAttr() {}
void BIOSSetBlinkAttr() {}
void BIOSSetColorRegister( short reg, char r, char g, char b ) {}
#pragma on (unreferenced);

static unsigned short _crow, _ccol, _ctype;

void BIOSSetCursor( char page, char row, char col )
{
    struct _mxfer_entry sx[2];
    struct _mxfer_entry rx;

    union _console_msg {
            struct _console_write       write;
            struct _console_write_reply write_reply;
    } msg;

    page = page;
    _crow = row;
    _ccol = col;

    if( QNXCon == NULL ) return;
    msg.write.type = _CONSOLE_WRITE;
    msg.write.handle = QNXCon->handle;
    msg.write.console = QNXConsole;
    msg.write.curs_row = row;
    msg.write.curs_col = col;
    msg.write.curs_type = _ctype;
    msg.write.offset = 0;
    msg.write.nbytes = 0;

    _setmx( &sx[1], 0, 0 );
    _setmx( &sx[0], &msg.write, sizeof(msg.write)-sizeof(msg.write.data) );

    _setmx( &rx, &msg.write_reply, sizeof( msg.write_reply ) );

    Sendmx(QNXCon->driver, 2, 1, &sx, &rx );

} /* BIOSSetCursor */

short BIOSGetCursor( char page )
{
    page = page;
    return( (short)((unsigned short)_crow * 256 + _crow ) );

} /* BIOSGetCursor */

void BIOSNewCursor( char top, char bottom )
{
    if( bottom-top > 5 ) {
        _ctype = CURSOR_BLOCK;
    } else {
        _ctype = CURSOR_UNDERLINE;
    }

} /* BIOSNewCursor */

static int CompareEvents( const void *d1, const void *d2 )
{
    const struct map *p1 = d1;
    const struct map *p2 = d2;

    return( p1->qnx - p2->qnx );
}

extern short BIOSGetKeyboard( char y)
{
    char        ch;
    struct map  what;
    struct map  *ev;

    y = y;
    while( dev_read( QNXConHandle, &ch, 1, 0, 0, 0, Proxy, 0 ) <= 0 ) {
        WaitForProxy();
    };
    if( ch == 0xff ) {
        if( dev_read( QNXConHandle, &ch, 1, 0, 0, 0, Proxy, 0 ) <= 0 ) {
            return( 0x80 );
        }
        what.qnx = ch;
        ev = bsearch( &what, events, sizeof( events )/sizeof( struct map ),
                        sizeof( what ), CompareEvents );
        if( ev != NULL ) {
            return( ev->event );
        }
        return( 0x80 );
    } else {
        if( ch == 127 ) {
            ch = 8; /* KLUDGE - bs comes through as del */
        }
    }
    return( ch );

} /* BIOSGetKeyboard */

extern short BIOSKeyboardHit( char x )
{
    x = x;
    return( dev_ischars( QNXConHandle ) != 0 );

} /* BIOSKeyboardHit */

void WaitForProxy( void )
{
    dev_arm( QNXConHandle, Proxy, _DEV_EVENT_INPUT );
    Receive( Proxy, 0, 0 );

} /* WaitForProxy */

extern long DosGetFullPath( char *old, char *full )
{
    strcpy( full, old );        /* for now */
    return( 0L );

} /* DosGetFullPath */


static void addConsoleNumber( char * ptr, unsigned number )
{
    ptr[0] = (number / 10) + '0';
    ptr[1] = (number % 10) + '0';
    ptr[2] = 0;

} /* addConsoleNumber */

/*
 * KeyboardInit
 */
int KeyboardInit( void )
{
    struct _dev_info_entry      dev;
    char                        *ptr;
    char                        *digits;
    struct _psinfo              psinfo;
    struct _sidinfo             sidinfo;
    pid_t                       proc;
    unsigned                    console;

    Proxy = qnx_proxy_attach( 0, 0, 0, -1 );
    if( Proxy == -1 ) {
        FatalError( ERR_WIND_NO_MORE_WINDOWS );
    }
    if( strcmp( getenv( "TERM" ), "qnxw" ) == 0 ) {
//      EditFlags.IsWindowedConsole = TRUE;
    }

    if( qnx_psinfo( PROC_PID, _my_pid, &psinfo, 0, 0 ) != _my_pid ) {
        return( ERR_WIND_NO_MORE_WINDOWS );
    }
    proc = qnx_vc_attach( psinfo.sid_nid, PROC_PID, sizeof( sidinfo ), 0 );
    if( proc == -1 ) {
        return( ERR_WIND_NO_MORE_WINDOWS );
    }
    if( qnx_sid_query( proc, psinfo.sid, &sidinfo )!= psinfo.sid ) {
        return( ERR_WIND_NO_MORE_WINDOWS );
    }
    qnx_vc_detach( proc );

    ptr = &sidinfo.tty_name[ strlen( sidinfo.tty_name ) ];
    while( 1 ) {
        if( ptr[-1] < '0' || ptr[-1] > '9' ) {
            break;
        }
        ptr--;
    }
    digits = ptr;
    console = 0;
    while( *ptr != '\0' ) {
        console = (console * 10) + (*ptr - '0');
        ++ptr;
    }
    if( QNXConsole == 0 ) {             // open the current console
        QNXConsole = console;
    } else if( QNXConsole == -1 ) {     // open any available console
        digits[0] = '\0';
    } else {                            // open a specific console
        addConsoleNumber( digits, QNXConsole );
    }

    QNXConHandle = open( sidinfo.tty_name, O_RDWR );
    if( QNXConHandle == -1 ) {
        if( QNXConsole != -1 ) {
            FatalError( ERR_WIND_NO_MORE_WINDOWS );
        }
        addConsoleNumber( digits, console );
        QNXConHandle = open( sidinfo.tty_name, O_RDWR );
        if( QNXConHandle == -1 ) {
            FatalError( ERR_WIND_NO_MORE_WINDOWS );
        }
    }

    if( QNXConsole == -1 ) {
        if( dev_info( QNXConHandle, &dev ) == -1 ) {
            return( ERR_WIND_NO_MORE_WINDOWS );
        }
        QNXConsole = dev.unit;
    }

    fcntl( QNXConHandle, F_SETFD, (int) FD_CLOEXEC );
    if( tcsetpgrp( QNXConHandle, psinfo.pid_group ) != 0 ) {
        return( ERR_WIND_NO_MORE_WINDOWS );
    }
    tcgetattr( QNXConHandle, &SaveTermSet );
    SaveTermProtocol = console_protocol( QNXCon, QNXConsole, -1 );
    RestoreKeyboard();
//    StopKeyboard();
    return( ERR_NO_ERR );

} /* KeyboardInit */

void RestoreKeyboard( void )
{
    struct termios  new;

    new = SaveTermSet;
    new.c_iflag &= ~(IXOFF | IXON | ICRNL | INLCR);
    new.c_oflag &= ~OPOST;
    new.c_lflag &= ~(ECHO | ICANON | NOFLSH | ECHOE);
    new.c_lflag |= ISIG;
    new.c_cc[VINTR] = '\0';
    new.c_cc[VMIN] = 1;
    new.c_cc[VTIME] = 0;
    tcsetattr( QNXConHandle, TCSADRAIN, &new );
    console_protocol( QNXCon, QNXConsole, _CON_PROT_QNX4 );

} /* RestoreKeyboard */

void KeyboardFini( void )
{
    tcsetattr( QNXConHandle, TCSADRAIN, &SaveTermSet );
    console_protocol( QNXCon, QNXConsole, SaveTermProtocol );

} /* KeyboardFini */


void StopKeyboard( void )
{
    dev_read( QNXConHandle, NULL, 0, 0, 0, 0, 0, 0 );
    while( Creceive( Proxy, 0, 0 ) > 0 );

} /* StopKeyboard */

/*
 * MyVioShowBuf - update the screen
 */
void MyVioShowBuf( unsigned offset, int nbytes )
{
    struct _mxfer_entry sx[2];
    struct _mxfer_entry rx;
    union _console_msg {
            struct _console_write       write;
            struct _console_write_reply write_reply;
    }                   msg;
    extern int          PageCnt;


    if( PageCnt > 0 ) {
        return;
    }

    msg.write.type = _CONSOLE_WRITE;
    msg.write.handle = QNXCon->handle;
    msg.write.console = QNXConsole;
    msg.write.curs_row = _crow;
    msg.write.curs_col = _ccol;
    msg.write.curs_type = _ctype;
    msg.write.offset = offset;
    msg.write.nbytes = nbytes*2;

    _setmx( &sx[1], &(Scrn[offset]), nbytes*2 );
    _setmx( &sx[0], &msg.write, sizeof(msg.write)-sizeof(msg.write.data) );

    _setmx( &rx, &msg.write_reply, sizeof( msg.write_reply ) );

    Sendmx(QNXCon->driver, 2, 1, &sx, &rx );

} /* MyVioShowBuf */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?