/* * OS2IO.C: Terminal IO for OS/2 * J Burnell 3/92 Public Domain */ /* * The functions in this file negotiate with the operating system for * characters, and write characters in a barely buffered fashion on the * display. */ #include #define INCL_BASE #define INCL_NOPM #define INCL_VIO #define INCL_KBD #include #include #include "ed.h" #include "term.h" #include "me2.h" #include "config.h" #define MAXCOLS 120 KBDINFO initialKbdInfo; /* keyboard info */ void t_eeol (); /* * This function is called once to set up the terminal device streams. */ void ttopen() { PFNSIGHANDLER oldhandler; USHORT oldact; KBDINFO kbdInfo; /* turn off control C checking */ DosSetSigHandler((PFNSIGHANDLER) NULL, &oldhandler, &oldact, SIGA_IGNORE, SIG_CTRLBREAK); DosSetSigHandler((PFNSIGHANDLER) NULL, &oldhandler, &oldact, SIGA_IGNORE, SIG_CTRLC); /* set up the keyboard */ initialKbdInfo.cb = sizeof(initialKbdInfo); KbdGetStatus(&initialKbdInfo, 0); kbdInfo = initialKbdInfo; kbdInfo.fsMask &= ~0x0001; /* not echo on */ kbdInfo.fsMask |= 0x0002; /* echo off */ kbdInfo.fsMask &= ~0x0008; /* cooked mode off */ kbdInfo.fsMask |= 0x0004; /* raw mode */ kbdInfo.fsMask &= ~0x0100; /* shift report off */ KbdSetStatus(&kbdInfo, 0); } /* * This function gets called just before we go back home to the command * interpreter. */ void t_close() { /* close the keyboard */ KbdSetStatus(&initialKbdInfo, 0); /* restore original state */ } /* * Write a character to the display. * Use the rawest console output routine that handles backspace, \r and \n. * On MS-DOS terminal I/O is unbuffered, so we just write the byte out. */ void t_putchar(c) unsigned char c; { VioWrtTTY ((PCH)&c, 1, 0); } /* * Flush terminal buffer. Does real work where the terminal output is * buffered up. A no-operation on systems where byte-at-a-time terminal * I/O is done. */ void t_flush() {} /* * Read a character from the terminal, performing no editing and doing no * echo at all. * Map terminal softkeys, etc to ME keys. Do *NOT* map control keys. */ KeyCode t_getchar() { KeyCode keycode; KBDKEYINFO keyInfo; KbdCharIn(&keyInfo, IO_WAIT, 0); /* get a character */ if (keyInfo.chChar == 0 || (keyInfo.chChar == 0xE0 && keyInfo.chChar != 0)) { if (map_key(keyInfo.chScan | (keyInfo.chChar << 8),&keycode)) return keycode; } else return (KeyCode)keyInfo.chChar; } /* * Check to see is a key is waiting. * Used to interrupt processing if input is pending or to detect if a soft * key has been hit (the terminal sends multiple characters for each * softkey). * Don't use function B because it checks for ^C. */ int keywaiting() { return kbhit(); } static long int get_time(init) { time_t t; t = time (0); return t; } /* Wait for a key to be pressed for no more than sec seconds. * Use 0 seconds to check to see if a key is in the input que. * Warning: This rouine is only good for 32K seconds (about 9 hours). * If sec is a long the limit is still 24 hours. */ wait_for_key(sec) { long int times_up; if (sec == 0) return keywaiting(); times_up = get_time(TRUE) +sec; do { if (keywaiting()) return TRUE; } while (get_time(FALSE) < times_up); return FALSE; } #if FASTVIDEO /* Things to note about FastVideo: * putline() will do all of the writing to the text area (except for * help messages). * t_eeol() will only be called for the message line or for help * messages. * t_eeop() need only clear the message line. It should use t_eeol() to * do this. * t_putchar() will only write to the message line, help messages or * (puts "message"). * So, this means that the message line is really seprate from the text * areas and t_putchar() and t_eeol() should use the same color (others * will use tcolor and mcolor). Default for the message line would be * tcolor. Help and (puts ...) messages will be written in message * color (which is (I hope) reasonable). * PC note: Due to the way the BIOS is done, it is easier to have * t_putchar() and t_eeol() use the BIOS character attribute as the * color. */ int t_nrow = 24, t_ncol = 0; int tcolor = 7, mcolor = 96; /* text, modeline color defaults */ int zcolor = 7; /* * Called to set up the terminal. Also called after a spawn. */ void t_open() { VIOCURSORINFO cursorInfo, OldcursorInfo; ttopen(); if (t_ncol == 0) fv_init(); /* only call fv_init() once */ /* set the cursor to a block */ VioGetCurType (&OldcursorInfo, 0); cursorInfo.yStart = 1; cursorInfo.cEnd = 15; cursorInfo.cx = 1; cursorInfo.attr = 1; if (VioSetCurType (&cursorInfo, 0)) VioSetCurType (&OldcursorInfo, 0); /* reset to previous value */ } int fv_init () { VIOMODEINFO vioModeInfo; vioModeInfo.cb = sizeof(vioModeInfo); VioGetMode (&vioModeInfo, 0); t_ncol = vioModeInfo.col; t_nrow = vioModeInfo.row - 1; /* leave room for the message line */ } void putline(row, buf, attr) /* note: row is 0 relative */ int row,attr; char *buf; { VioWrtCharStrAtt ((PCH) buf, t_ncol, row, 0, (PBYTE) &attr, 0); } /* Erase to end of page or screen. * For fast video, each line of the screen (except for the message line) * will be completely filled by putline() so all this routine needs to * clear is the message (last) line of the screen. */ void t_eeop() { movecursor(t_nrow,0,TRUE); t_eeol(); } /* Ring the bell. beeper controls the volume: 0 (don't beep), n (some * volume value). */ void t_beep() { extern int beeper; if (beeper) DosBeep(1200, 175); } void t_move(row,col) int row, col; /* move cursor to (row,col) */ { VioSetCurPos(row, col, 0); } char LineOfSpaces [MAXCOLS]; void t_eeol() /* erase from cursor to end of line */ { register int n; USHORT CurCol, CurRow; /* find the current cursor position */ VioGetCurPos ((PUSHORT) &CurRow, (PUSHORT) &CurCol, 0); n = t_ncol - CurCol; memset (LineOfSpaces, ' ', n); VioWrtCharStrAtt ((PCH) &LineOfSpaces [0], t_ncol - CurCol, CurRow, CurCol, (PBYTE) &zcolor, 0); } #endif /* FASTVIDEO */