// This may look like C code, but it is really -*- C++ -*- // ------------------------------------------------------------------ // The Goldware Library // Copyright (C) 1990-1999 Odinn Sorensen // Copyright (C) 1999-2000 Alexander S. Aganichev // Copyright (C) 2000 Jacobo Tarrio // ------------------------------------------------------------------ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this program; if not, write to the Free // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, // MA 02111-1307, USA // ------------------------------------------------------------------ // $Id$ // ------------------------------------------------------------------ // Device-independent video functions // ------------------------------------------------------------------ #include #include #include #include #include #include #if defined(__WATCOMC__) or defined(__DJGPP__) #include #endif #include #if defined(__OS2__) #define INCL_BASE #include #endif #if defined(__WIN32__) #include #endif #if not defined(__USE_NCURSES__) and defined(__UNIX__) #include #include #include #include #endif #if defined(__DJGPP__) #include #include #endif // ------------------------------------------------------------------ // Check if Borland C++ for OS/2 1.0 header has been fixed #if defined(__OS2__) and defined(__BORLANDC__) #if __BORLANDC__ <= 0x400 #ifndef BCOS2_BSESUB_FIXED #error There is a bug in the BSESUB.H header. Please fix it. // // Add/change the following in BSESUB.H: // // #define BCOS2_BSESUB_FIXED // APIRET16 APIENTRY16 VioGetState (PVOID16 pState, HVIO hvio); // APIRET16 APIENTRY16 VioSetState (PVOID16 pState, HVIO hvio); // // Borland forgot this (was only PVOID) ^^ // #endif #endif #endif // ------------------------------------------------------------------ // Global video data #ifdef __WIN32__ HANDLE gvid_hout; #endif GVid *gvid; int __gdvdetected = false; #if defined(__USE_NCURSES__) // add statics here #elif defined(__UNIX__) int gvid_stdout = -1; bool gvid_xterm = false; const char* gvid_acs_enable; const char* gvid_acs_disable; void _vputx(int row, int col, int atr, char chr, uint len); void gvid_printf(const char* fmt, ...) __attribute__ ((format (printf, 1, 2))); #endif // ------------------------------------------------------------------ // Video Class constructor GVid::GVid() { #ifdef __DJGPP__ dmaptr = dmadir = 0; #else dmaptr = dmadir = NULL; #endif bufchr = NULL; bufwrd = NULL; bufansi = NULL; init(); } // ------------------------------------------------------------------ // Video Class destructor GVid::~GVid() { #if defined(__USE_NCURSES__) attrset(A_NORMAL); if(not --curses_initialized) endwin(); #elif defined(__UNIX__) // "\033<" Enter ANSI mode // "\033[?5l" Normal screen // "\033[0m" Normal character attributes gvid_printf("\033<\033[?5l\033[0m"); #endif #ifndef __DJGPP__ if(dmaptr != dmadir) throw_xfree(dmaptr); #endif throw_xfree(bufwrd); throw_xfree(bufchr); throw_xfree(bufansi); } // ------------------------------------------------------------------ void GVid::init() { #if defined(__USE_NCURSES__) if(not curses_initialized++) initscr(); noecho(); nonl(); intrflush(stdscr, FALSE); #endif // Detect video adapter detectadapter(); // Detect original video information detectinfo(&orig); memcpy(&curr, &orig, sizeof(GVidInfo)); #if defined(__MSDOS__) device = GVID_DMA; #elif defined(__OS2__) device = GVID_OS2; #elif defined(__WIN32__) device = GVID_W32; #endif #if defined(__USE_NCURSES__) dmaptr = dmadir = NULL; #elif defined(__WATCOMC__) and defined(__386__) dmaptr = dmadir = (gdma)(videoseg << 4); #elif defined(__DJGPP__) dmaptr = dmadir = ScreenPrimary; #elif defined(__OS2__) or defined(__WIN32__) dmaptr = dmadir = NULL; #elif defined(__UNIX__) dmaptr = (gdma)throw_xcalloc((orig.screen.rows+1)*orig.screen.columns, sizeof(word)); dmadir = NULL; #else dmaptr = dmadir = (gdma)MK_FP(videoseg, 0); #endif bufchr = NULL; bufwrd = NULL; bufansi = NULL; resetcurr(); } // ------------------------------------------------------------------ // Video adapter detect int GVid::detectadapter() { // Initialize to a valid value adapter = GV_NONE; #if defined(__USE_NCURSES__) start_color(); /* init colors */ short mycolors[] = { COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE }; for(int i = 1; i < 64 and i < COLOR_PAIRS; i++) init_pair(i, mycolors[(~i)&0x07], mycolors[(i>>3)&0x07]); adapter = V_VGA; #elif defined(__MSDOS__) i86 cpu; // Get video mode cpu.ah(V_GET_MODE); cpu.genint(0x10); int _got_mode = cpu.al(); // Check for PS/2 compatible video BIOS by calling the get // video configuration function. If it exists, the video // configuration code will be returned in BL. cpu.ax(0x1A00); cpu.genint(0x10); if(cpu.al() == 0x1A) { switch(cpu.bl()) { case 0x00: adapter = GV_NONE; break; case 0x01: adapter = V_MDA; break; case 0x02: adapter = V_CGA; break; case 0x04: adapter = V_EGA; break; case 0x05: adapter = V_EGAMONO; break; case 0x07: adapter = (_got_mode == 7) ? V_VGAMONO : V_VGA; break; case 0x08: adapter = (_got_mode == 7) ? V_VGAMONO : V_VGA; break; case 0x0A: case 0x0C: adapter = V_MCGA; break; case 0x0B: adapter = V_MCGAMONO; break; default: adapter = V_VGA; // We hope it is VGA compatible! } } else { // OK, we know that it's not a PS/2 BIOS, so check for an EGA. // If an EGA is not present, BH will be unchanged on return. cpu.ah(0x12); cpu.bl(0x10); cpu.genint(0x10); if(cpu.bl() - 0x10) { adapter = cpu.bh() ? V_EGAMONO : V_EGA; } else { // Now we know it's not an EGA. Get the BIOS equipment // flag and test for CGA, MDA, or no video adapter. cpu.genint(0x11); switch(cpu.al() & 0x30) { case 0x00: adapter = (_got_mode == 7) ? V_VGAMONO : V_VGA; // EGA, VGA, or PGA break; case 0x10: adapter = GV_NONE; // 40x25 color break; case 0x20: adapter = V_CGA; // 80x25 color break; case 0x30: adapter = V_MDA; // 80x25 monochrome break; } } } #ifndef __DJGPP__ // Set video segment #if defined(__BORLANDC__) and defined(__DPMI32__) videoseg = (word)((adapter & V_MONO) ? __SegB000 : __SegB800); #else videoseg = (word)((adapter & V_MONO) ? 0xB000 : 0xB800); #endif // check for presence of DESQview by using the DOS Set // System Date function and trying to set an invalid date cpu.ax(0x2B01); // DOS Set System Date cpu.ch('D'); cpu.cl('E'); cpu.dh('S'); cpu.dl('Q'); cpu.genint(0x21); // if error, then DESQview not present if(cpu.al() != 0xFF) { __gdvdetected = true; #if defined(__WATCOMC__) and defined(__386__) memset(&RMI, 0, sizeof(RMI)); RMI.EAX = 0x0000FE00; RMI.ES = videoseg; cpu.ax(0x0300); cpu.bl(0x10); cpu.bh(0); cpu.cx(0); cpu.es(FP_SEG(&RMI)); cpu.edi(FP_OFF(&RMI)); cpu.genint(0x31); videoseg = RMI.ES; #else cpu.ah(0xFE); // DV get alternate video buffer cpu.es(videoseg); cpu.di(0x0000); cpu.genint(0x10); videoseg = cpu.es(); #endif } #endif // __DJGPP__ #elif defined(__OS2__) { VIOCONFIGINFO vioconfiginfo; memset(&vioconfiginfo, 0, sizeof(VIOCONFIGINFO)); vioconfiginfo.cb = sizeof(VIOCONFIGINFO); VioGetConfig(0, &vioconfiginfo, 0); switch(vioconfiginfo.adapter) { case DISPLAY_MONOCHROME: adapter = V_MDA; break; case DISPLAY_CGA: adapter = V_CGA; break; case DISPLAY_EGA: adapter = V_EGA; break; case DISPLAY_VGA: adapter = V_VGA; break; default: adapter = V_VGA; // We hope it is VGA compatible! } if(vioconfiginfo.display == DISPLAY_MONOCHROME) adapter |= V_MONO; } #elif defined(__WIN32__) gvid_hout = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING|FILE_FLAG_WRITE_THROUGH, NULL); SetFileApisToOEM(); adapter = V_VGA; #elif defined(__UNIX__) const char* term = getenv("TERM"); if(term and strneql(term, "xterm", 5)) { gvid_xterm = true; for(int n=0; n<8; n++) __box_table[n] = __box_table[8]; } gvid_acs_enable = gvid_xterm ? "\033)0\033(B\016" : "\033[11m"; gvid_acs_disable = gvid_xterm ? "\033(B\033)B\017" : "\033[10m"; gvid_stdout = fileno(stdout); adapter = V_VGA; #endif return adapter; } // ------------------------------------------------------------------ // Video info detect void GVid::detectinfo(GVidInfo* _info) { // Reset all original values memset(_info, 0, sizeof(GVidInfo)); #if defined(__USE_NCURSES__) _info->screen.mode = 0; _info->screen.rows = LINES; _info->screen.columns = COLS; getyx(stdscr, _info->cursor.row, _info->cursor.column); _info->color.textattr = 7; _info->cursor.start = 11; _info->cursor.end = 12; _info->cursor.attr = 7; _info->color.intensity = 1; _info->color.overscan = 0; #elif defined(__MSDOS__) i86 cpu; // Get video mode and number of columns cpu.ah(V_GET_MODE); cpu.genint(0x10); _info->screen.mode = cpu.al(); _info->screen.columns = cpu.ah(); // Get the number of screen rows if(adapter >= V_EGA) { cpu.ax(V_GET_FONT_INFO); cpu.dx(0); cpu.genint(0x10); _info->screen.rows = cpu.dl() + ((adapter & V_EGA) ? 0 : 1); if(_info->screen.rows == 24) // Normally nonsense _info->screen.rows++; //_info->screen.cheight = cpu.cx(); _info->screen.cheight = 8; _info->screen.cwidth = 8; } else { _info->screen.rows = 25; _info->screen.cheight = 8; _info->screen.cwidth = 8; } // Get character attribute under the cursor cpu.ah(V_RD_CHAR_ATTR); cpu.bh(0); cpu.genint(0x10); _info->color.textattr = cpu.ah(); // Get cursor position and form cpu.ah(V_GET_CURSOR_POS); cpu.bh(0); cpu.genint(0x10); _info->cursor.row = cpu.dh(); _info->cursor.column = cpu.dl(); _info->cursor.start = cpu.ch(); _info->cursor.end = cpu.cl(); _info->cursor.attr = (word)_info->color.textattr; // Get overscan color if(adapter & V_VGA) { cpu.ax(0x1008); cpu.bh(0xFF); cpu.genint(0x10); _info->color.overscan = cpu.bh(); } // Get intensity state { // Check bit 5 at 0000:0465 #if defined(__DJGPP__) _info->color.intensity = (_farpeekb (_dos_ds, 0x465) & 0x20) ? 0 : 1; #else byte* _bptr = (byte*)0x0465; _info->color.intensity = (*_bptr & 0x20) ? 0 : 1; #endif } #elif defined(__OS2__) // Get video mode and number of rows and columns { VIOMODEINFO viomodeinfo; memset(&viomodeinfo, 0, sizeof(VIOMODEINFO)); viomodeinfo.cb = sizeof(VIOMODEINFO); VioGetMode(&viomodeinfo, 0); _info->screen.mode = viomodeinfo.fbType; _info->screen.rows = viomodeinfo.row; _info->screen.columns = viomodeinfo.col; _info->screen.cheight = viomodeinfo.vres / viomodeinfo.row; _info->screen.cwidth = viomodeinfo.hres / viomodeinfo.col; } // Get cursor position and character attribute under the cursor { USHORT usRow, usColumn; VioGetCurPos(&usRow, &usColumn, 0); _info->cursor.row = usRow; _info->cursor.column = usColumn; BYTE chat[2]; USHORT len = 2; #if defined(__EMX__) VioReadCellStr((PCH)chat, &len, usRow, usColumn, 0); #else VioReadCellStr((CHAR*)chat, &len, usRow, usColumn, 0); #endif _info->color.textattr = chat[1]; } // Get cursor form { VIOCURSORINFO viocursorinfo; memset(&viocursorinfo, 0, sizeof(VIOCURSORINFO)); VioGetCurType(&viocursorinfo, 0); _info->cursor.start = viocursorinfo.yStart; _info->cursor.end = viocursorinfo.cEnd; _info->cursor.attr = viocursorinfo.attr; } // Get intensity state { VIOINTENSITY viointensity; memset(&viointensity, 0, sizeof(VIOINTENSITY)); viointensity.cb = sizeof(VIOINTENSITY); viointensity.type = 0x0002; VioGetState(&viointensity, 0); _info->color.intensity = viointensity.fs ? 1 : 0; } // Get overscan color { VIOOVERSCAN viooverscan; memset(&viooverscan, 0, sizeof(VIOOVERSCAN)); viooverscan.cb = sizeof(VIOOVERSCAN); viooverscan.type = 0x0001; VioGetState(&viooverscan, 0); _info->color.overscan = (int)viooverscan.color; } #elif defined(__WIN32__) // Get video mode and number of rows and columns CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo(gvid_hout, &csbi); _info->screen.mode = 0; _info->screen.rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; _info->screen.columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; // Get cursor position and character attribute under the cursor _info->cursor.row = csbi.dwCursorPosition.Y - csbi.srWindow.Top; _info->cursor.column = csbi.dwCursorPosition.X - csbi.srWindow.Left; _info->color.textattr = csbi.wAttributes; // Get cursor form CONSOLE_CURSOR_INFO cci; GetConsoleCursorInfo(gvid_hout, &cci); _info->cursor.start = (int) 1; _info->cursor.end = cci.bVisible ? (int) 15 : 0; _info->cursor.attr = (word)(cci.bVisible ? 7 : 0); // Get intensity state _info->color.intensity = 1; // Get overscan color _info->color.overscan = 0; #elif defined(__UNIX__) int r = 0, c = 0; if(r <= 0) { char *s = getenv("LINES"); if(s) { //printf("getenv(\"LINES\") = %s\n", s); r = atoi(s); } } if(c <= 0) { char *s = getenv("COLUMNS"); if(s) { //printf("getenv(\"COLUMNS\") = %s\n", s); c = atoi(s); } } //printf("init1: c=%i, r=%i\n", c, r); #if defined(TIOCGSIZE) if(r <= 0 or c <= 0) { struct ttysize sz; do { if((ioctl(1,TIOCGSIZE,&sz) == 0) or (ioctl(0, TIOCGSIZE, &sz) == 0) or (ioctl(2, TIOCGSIZE, &sz) == 0)) { c = (int)sz.ts_cols; r = (int)sz.ts_lines; break; } } while(errno == EINTR); } //printf("init2: c=%i, r=%i\n", c, r); #elif defined(TIOCGWINSZ) if(r <= 0 or c <= 0) { struct winsize wind_struct; do { if((ioctl(1,TIOCGWINSZ,&wind_struct) == 0) or (ioctl(0, TIOCGWINSZ, &wind_struct) == 0) or (ioctl(2, TIOCGWINSZ, &wind_struct) == 0)) { c = (int)wind_struct.ws_col; r = (int)wind_struct.ws_row; break; } } while(errno == EINTR); } //printf("init3: c=%i, r=%i\n", c, r); #endif if((r <= 0) or (r > 200)) r = 24; if((c <= 0) or (c > 250)) c = 80; //printf("init4: c=%i, r=%i\n", c, r); //*dmadir = 0; _info->screen.mode = 0; _info->screen.rows = r; _info->screen.columns = c; _info->cursor.row = 0; _info->cursor.column = 0; _info->color.textattr = 7; _info->cursor.start = 11; _info->cursor.end = 12; _info->cursor.attr = 7; _info->color.intensity = 1; _info->color.overscan = 0; #endif getpalette(_info->color.palette); } // ------------------------------------------------------------------ // Reset current video info void GVid::resetcurr() { currow = curr.cursor.row; curcol = curr.cursor.column; numrows = curr.screen.rows; numcols = curr.screen.columns; throw_xfree(bufchr); throw_xfree(bufwrd); throw_xfree(bufansi); bufchr = (vchar*)throw_xcalloc(sizeof(vchar), numcols+1); bufwrd = (vatch*)throw_xcalloc(sizeof(vatch), numcols+1); bufansi = (vchar*)throw_xcalloc(sizeof(vchar), (11*numcols)+1); setdevice(device); } // ------------------------------------------------------------------ // Sets video output device void GVid::setdevice(int _device) { device = _device; } // ------------------------------------------------------------------ // Sets video mode void GVid::setmode(int _mode) { if(_mode) { #if defined(__MSDOS__) i86 cpu; cpu.ah(0x00); cpu.al((byte)_mode); cpu.genint(0x10); #endif } detectinfo(&curr); resetcurr(); } // ------------------------------------------------------------------ // Sets screen rows void GVid::setrows(int _rows) { int origrows = curr.screen.rows; #if defined(__USE_NCURSES__) NW(_rows); #elif defined(__MSDOS__) i86 cpu; // Set video mode 3 (80xNN) if(curr.screen.mode != 3) { cpu.ax(0x0003); cpu.genint(0x10); } if(adapter >= V_EGA) { if(_rows == 28 and adapter >= V_VGA) { // vga-only cpu.ax(0x1202); cpu.bl(0x30); cpu.genint(0x10); cpu.ax(0x1111); cpu.bl(0); cpu.genint(0x10); } else if(_rows >= 43) { cpu.ax(0x1112); // Load 8x8 character set cpu.bl(0x00); cpu.genint(0x10); cpu.ax(0x1200); // Select alternate print-screen routine cpu.bl(0x20); cpu.genint(0x10); if(adapter & V_EGA) { // Disable cursor size emulation byte* _bptr = (byte*)0x0487; *_bptr |= (byte)0x01; // Set cursor size cpu.ah(0x01); cpu.al((byte)orig.screen.mode); cpu.cx(0x0600); cpu.genint(0x10); } } else { if(adapter & V_EGA) { // Enable cursor size emulation byte* _bptr = (byte*)0x0487; *_bptr &= (byte)0xFE; } // Set cursor size cpu.ah(0x01); cpu.al((byte)orig.screen.mode); cpu.cx(0x0607); cpu.genint(0x10); } } #elif defined(__OS2__) VIOMODEINFO viomodeinfo; memset(&viomodeinfo, 0, sizeof(VIOMODEINFO)); viomodeinfo.cb = sizeof(VIOMODEINFO); VioGetMode(&viomodeinfo, 0); viomodeinfo.row = (USHORT)_rows; VioSetMode(&viomodeinfo, 0); #elif defined(__WIN32__) or defined(__UNIX__) NW(_rows); #endif if(origrows < _rows) vfill(origrows, 0, _rows, 80, ' ', 7); detectinfo(&curr); resetcurr(); } // ------------------------------------------------------------------ // Set the screen border (overscan) color void GVid::setoverscan(int _overscan) { #if defined(__USE_NCURSES__) NW (_overscan); #elif defined(__MSDOS__) i86 cpu; cpu.ah(0x0B); cpu.bh(0x00); cpu.bl((byte)_overscan); cpu.genint(0x10); #elif defined(__OS2__) VIOOVERSCAN viooverscan; memset(&viooverscan, 0, sizeof(VIOOVERSCAN)); viooverscan.cb = sizeof(VIOOVERSCAN); viooverscan.type = 0x0001; VioGetState(&viooverscan, 0); viooverscan.color = (BYTE)_overscan; VioSetState(&viooverscan, 0); #elif defined(__WIN32__) or defined(__UNIX__) NW(_overscan); #endif } // ------------------------------------------------------------------ // Set intensity/blinking state void GVid::setintensity(int _intensity) { #if defined(__USE_NCURSES__) NW(_intensity); #elif defined(__MSDOS__) #ifdef __DJGPP__ if(_intensity) intensevideo(); else blinkvideo(); #else if(adapter & V_CGA) { word* _wptr = (word*)0x0463; byte* _bptr = (byte*)0x0465; uint port = *_wptr + 4; uint reg = *_bptr; if(_intensity) reg &= 0xDF; else reg |= 0x20; outp(port, reg); } else { i86 cpu; cpu.ax(0x1003); cpu.bh(0x00); cpu.bl((byte)(_intensity ? 0 : 1)); cpu.genint(0x10); } #endif // __DJGPP__ #elif defined(__OS2__) VIOINTENSITY viointensity; memset(&viointensity, 0, sizeof(VIOINTENSITY)); viointensity.cb = sizeof(VIOINTENSITY); viointensity.fs = (USHORT)(_intensity ? 1 : 0); viointensity.type = 0x0002; VioSetState(&viointensity, 0); #elif defined(__WIN32__) or defined(__UNIX__) NW(_intensity); #endif } // ------------------------------------------------------------------ void GVid::getpalette(int* _palette) { #if defined(__USE_NCURSES__) NW(_palette); #elif defined(__MSDOS__) // Get palette state if(adapter & V_VGA) { i86 cpu; for(byte n=0; n<16; n++) { cpu.ax(0x1007); // GET INDIVIDUAL PALETTE REGISTER cpu.bh(0xFF); cpu.bl(n); cpu.genint(0x10); _palette[n] = cpu.bh(); } } else { // Set to standard palette colors for(byte n=0; n<16; n++) _palette[n] = n + ((n > 7) ? 48 : 0); } #elif defined(__OS2__) // Get palette state BYTE viopalstate[38]; PVIOPALSTATE pviopalstate; memset(viopalstate, 0, sizeof(viopalstate)); pviopalstate = (PVIOPALSTATE)viopalstate; pviopalstate->cb = sizeof(viopalstate); pviopalstate->type = 0; pviopalstate->iFirst = 0; VioGetState(pviopalstate, 0); for(byte n=0; n<16; n++) _palette[n] = pviopalstate->acolor[n]; #elif defined(__WIN32__) or defined(__UNIX__) NW(_palette); #endif } // ------------------------------------------------------------------ void GVid::setpalette(int* _palette) { #if defined(__USE_NCURSES__) NW(_palette); #elif defined(__MSDOS__) if(adapter & (V_EGA|V_MCGA|V_VGA)) { i86 cpu; for(byte n=0; n<16; n++) { if(_palette[n] != -1) { cpu.ax(0x1000); cpu.bl(n); cpu.bh((byte)_palette[n]); cpu.genint(0x10); } } } #elif defined(__OS2__) BYTE viopalstate[38]; PVIOPALSTATE pviopalstate; memset(viopalstate, 0, sizeof(viopalstate)); pviopalstate = (PVIOPALSTATE)viopalstate; pviopalstate->cb = sizeof(viopalstate); pviopalstate->type = 0; pviopalstate->iFirst = 0; VioGetState(pviopalstate, 0); for(byte n=0; n<16; n++) if(_palette[n] != -1) pviopalstate->acolor[n] = (USHORT)_palette[n]; VioSetState(pviopalstate, 0); #elif defined(__WIN32__) or defined(__UNIX__) NW(_palette); #endif } // ------------------------------------------------------------------ void GVid::restore_cursor() { vcurset(orig.cursor.start, orig.cursor.end); vcurshow(); vposset(orig.cursor.row-1, 0); } // ------------------------------------------------------------------ void GVid::resize_screen(int columns, int rows) { numcols = curr.screen.columns = columns; numrows = curr.screen.rows = rows; bufchr = (vchar*)throw_xrealloc(bufchr, numcols); bufwrd = (vatch*)throw_xrealloc(bufwrd, numcols*2); bufansi = (vchar*)throw_xrealloc(bufansi, 1+(11*numcols)); #if defined(__UNIX__) and not defined(__USE_NCURSES__) dmaptr = (gdma)throw_xrealloc(dmaptr, (rows+1)*columns*sizeof(word)); #endif } // ------------------------------------------------------------------