/************************************************************************ * * * copyright Richard Bornat 1979 * * * ************************************************************************/ /************************************************************************ * * * This file specifies the terminal interface. There are three * * example terminal files distributed with ded - itt.c, hazeltine.c * * and systime.c, which between them show many of the ways in which * * the terminal interface can be set up. * * * * The terminal structure contains single characters and * * character sequences, each of which corresponds to a single * * terminal function. If a character or sequence is zero, the * * terminal doesn't have that function. If the first character * * of a sequence is zero, then the terminal must have time to * * execute that function and the terminal-specific function 'padout' * * is called - typically it sends lots of zeroes to waste some * * time. * * * ************************************************************************/ struct TERMINAL { int nrows, ncols; /* size of the screen */ struct { char up, left, /* not interested unless these are single chars */ c_MODIFY, c_CONTROL, c_BLOB; } onechar; /* Sequences used in scrolling - see scrollup, scrolldown. * These sequences are assumed to operate when positioned at line * N as follows: */ struct { char *rollup, /* rollup 0-last one position: last now blank */ *pushdown, /* scroll N-last down one position: N now blank */ *pushup, /* scroll 0-N up one position: N now blank */ *pulldown, /* scroll 0-N down one position: 0 now blank */ *pullup; /* scroll N-last up one position: last now blank */ int hardscroll; /* true if it has a pair of these functions */ } scrseq; /* procedures which use the scrolling sequences - there are * mutual recursion problems without this technique */ int (*scrollup)(), (*scrolldown)(); /* Sequences used in splitting and joining lines. These functions * might well need padding. Only the QMC terminal has them at the * moment - see the code of split_row and join_rows for clarification. * Also note that split and join are no use unless you have insert * and delete character hardware (see those procedures again for * more clarification). */ /* Only the QMC 1510 (so far as I know) has hardware split/join. I * designed it and split is OK, but join is a disaster. It OUGHT to * have been the inverse of split, but at present it sticks one * line to the tail of the one above. This makes it hard to * implement efficiently and the code very hard to understand. * Mea culpa. Sorry, folks. */ struct { char *splitdown, /* scroll N+1:last down one position, move to N+1 */ *splitup, /* scroll 0:N-1 up one position, move to N-1 */ *joindown, /* scroll 0:N+1 down one position */ *joinup; /* scroll N:last up one position */ int hardsplit; } splitseq; /* procedures to do line splitting and joining */ int (*split_row)(), (*join_rows)(); /* Sequences used in clearing screens, lines etc. These functions * often need padding - check your terminal empirically. It is assumed * that clearscreen moves the cursor to <0,0>, that clearhead moves * it to column 0 and that no other clear function moves the cursor * at all. */ #ifdef CHARED struct { char *clearscreen, *clearhead, *cleartail; } clrseq; int (*clr_screen)(), (*clr_head)(), (*clr_tail)(); #endif #ifndef CHARED struct { char *clearscreen; } clrseq; int (*clr_screen)(); #endif #ifdef CHARED /* Sequences used in inserting and deleting characters. These also may * need padding - beware! */ struct { char *inspace, /* put a space in and move the cursor */ *makespace, /* put a space but don't move */ *rubout, /* rubout the char behind the cursor */ *erase; /* rubout the char under the cursor */ } charseq; /* procedures to do the inserting and deleting */ int (*ins_char)(), (*del_char)(); /* Sequences used to change to bright/normal display, used to * accentuate ranges and (possibly) c_CONTROL characters */ struct { char *bright, *normal; } vidseq; #endif /* procedures used to translate double characters * (class TWO) on input or output. If there are no such * characters, these procedures need not be supplied */ char (*in_two)(), (*out_two)(); #ifdef CHARED /* procedure used to move the cursor, and number of characters sent */ int (*move)(), nmove; /* Procedure used to handle characters of type TRANSLATE or LEADIN when * typed or read in. See hazeltine.c and systime.c for * examples of what to do, and try NEVER again to use such a silly * terminal. The 'translate' procedure gives a new character, the 'leadin' * procedure gives a new character type (i.e. an action). */ int (*translate)(), (*leadin)(); #endif /* procedure used to do things which ter_setup doesn't - * in particular to set class TRANSLATE and LEADIN characters */ int (*setup)(); /* Procedure used to pad out difficult sequences */ int (*pad)(); }; extern struct TERMINAL ter; extern int no_int(); extern char no_char(); extern int scr0_up(), scr0_down(), scr1_up(), scr1_down(), scr2_up(), scr2_down(), scr3_up(), scr3_down(); extern int split0(), split1(), split2(), split3(), join0(), join1(), join2(), join3(); #ifdef CHARED extern int insc0(), insc1(), insc2(), delc0(), delc1(), delc2(); #endif extern int clrs0(), clrs1(), clrh0(), clrh1(), clrt0(), clrt1(); /* useful macros */ #define HARDSCROLL (ter.scrseq.hardscroll)