/* * Screen I/O interface library -- allows DECUSC programs to * call the scr$... routines. */ #include globalvalue int SS$_NORMAL; globalvalue int RMS$_EOF; static int _err; /* Directive error code */ static int paranoid = 0; /* When to force buffer flush */ static int stored = 0; /* How much in scr$ buffers */ typedef struct _descriptor { int size; char *loc; } _DESCRIPTOR; static _DESCRIPTOR _newbuf_; /* From scset() */ static char *_oldbuf_; /* From lib$set_buffer */ char ** scset(_buffer, _buffer_size, _old_buffer) char *_buffer; /* New buffer */ int _buffer_size; /* New buffer size */ char **_old_buffer; /* Old buffer */ { extern lib$set_buffer(); _newbuf_.loc = _buffer; _newbuf_.size = _buffer_size; paranoid = (_buffer_size * 3) / 4; /* Buffer flush forcer */ stored = 0; if ((_err = lib$set_buffer(&_newbuf_, &_oldbuf_)) != SS$_NORMAL) _trouble("scset -> lib$set_buffer"); *_old_buffer = _oldbuf_; } scput(_old) char *_old; { extern lib$put_buffer(); if ((_err = lib$put_buffer(&_old)) != SS$_NORMAL) _trouble("scput -> lib$put_buffer"); paranoid = 0; } int sctype() /* * Return screen type */ { long int flags; char dev_type; short int line_width; short int lines_per_page; extern lib$screen_info(); if ((_err = lib$screen_info(&flags, &dev_type, &line_width, &lines_per_page)) != SS$_NORMAL) _trouble("sctype -> lib$screen_info"); if ((flags & 02) != 0) { dev_type = 96; /* VT100 compatible terminal */ } flags &= 01; /* Other bits meaningless */ return (dev_type + flags); } int scerln(_row, _col) int _row; int _col; /* * Erase line */ { extern scr$erase_line(); if (_row == 0 || _col == 0) _err = scr$erase_line(); else _err = scr$erase_line(_row, _col); if (_err != SS$_NORMAL) _trouble("scerln -> scr$erase_line()"); } int scerpg(_row, _col) int _row; int _col; /* * Erase page */ { extern scr$erase_page(); if (_row == 0 || _col == 0) _err = scr$erase_page(); else _err = scr$erase_page(_row, _col); if (_err != SS$_NORMAL) _trouble("scerpg -> scr$erase_page()"); } int scout(_row, _col, _text) int _row; int _col; char *_text; /* * Output text */ { extern scr$put_screen(); extern scr$set_cursor(); extern lib$set_buffer(); extern lib$put_buffer(); int errcode; _DESCRIPTOR textp; if (_row != 0 && _col != 0) { if ((_err = scr$set_cursor(_row, _col)) != SS$_NORMAL) _trouble("scout -> scr$set_cursor"); } if (_text != NULL) { textp.loc = _text; textp.size = strlen(_text); if (stored + textp.size >= paranoid) flush_buffer(); if ((_err = scr$put_screen(&textp)) != SS$_NORMAL) _trouble("scout -> scr$put_screen"); stored += textp.size; } else { /* * Flush current buffer */ flush_buffer(); } } static flush_buffer() /* * Flush current buffer */ { if ((_err = lib$put_buffer(&NULL)) != SS$_NORMAL) _trouble("flush_buffer -> lib$putbuffer()"); if ((_err = lib$set_buffer(&_newbuf_)) != SS$_NORMAL) _trouble("flush_buffer -> lib$set_buffer(&_newbuf_)"); stored = 0; } scget(_text, _textsize, _prompt) char *_text; int _textsize; char *_prompt; /* * Get from the screen */ { _DESCRIPTOR _textp; _DESCRIPTOR _promptp; short int _bytes_gotten; extern int lib$get_screen(); _textp.loc = _text; _textp.size = _textsize; if (_prompt == NULL) { _promptp.loc = ""; _promptp.size = 0; } else { _promptp.loc = _prompt; _promptp.size = strlen(_prompt); } flush_buffer(); /* Why is this needed? */ if ((_err = lib$get_screen(&_textp, &_promptp, &_bytes_gotten)) != SS$_NORMAL) { if (_err != RMS$_EOF) { fprintf(stderr, "scget -> lib$get_screen code %08x\n", _err); sleep(3); } _text[0] = '\0'; return(NULL); } else { _text[_bytes_gotten] = '\0'; /* Terminate string */ return (_text); } } static _trouble(where) char *where; { fprintf(stderr, "\nscreen error %x %d. from %s\n", _err, _err, where); /* * exit(_err); */ lib$stop(_err); }