1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2 /* hack.termcap.c - version 1.0.3 */ 3 4 #include <stdio.h> 5 #include "config.h" /* for ROWNO and COLNO */ 6 #include "def.flag.h" /* for flags.nonull */ 7 extern char *tgetstr(), *tgoto(), *getenv(); 8 extern long *alloc(); 9 10 #ifndef lint 11 extern /* it is defined in libtermlib (libtermcap) */ 12 #endif lint 13 short ospeed; /* terminal baudrate; used by tputs */ 14 static char tbuf[512]; 15 static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE; 16 static char *VS, *VE; 17 static int SG; 18 static char PC = '\0'; 19 char *CD; /* tested in pri.c: docorner() */ 20 int CO, LI; /* used in pri.c and whatis.c */ 21 22 startup() 23 { 24 register char *term; 25 register char *tptr; 26 char *tbufptr, *pc; 27 28 tptr = (char *) alloc(1024); 29 30 tbufptr = tbuf; 31 if(!(term = getenv("TERM"))) 32 error("Can't get TERM."); 33 if(!strncmp(term, "5620", 4)) 34 flags.nonull = 1; /* this should be a termcap flag */ 35 if(tgetent(tptr, term) < 1) 36 error("Unknown terminal type: %s.", term); 37 if(pc = tgetstr("pc", &tbufptr)) 38 PC = *pc; 39 if(!(BC = tgetstr("bc", &tbufptr))) { 40 if(!tgetflag("bs")) 41 error("Terminal must backspace."); 42 BC = tbufptr; 43 tbufptr += 2; 44 *BC = '\b'; 45 } 46 HO = tgetstr("ho", &tbufptr); 47 CO = tgetnum("co"); 48 LI = tgetnum("li"); 49 if(CO < COLNO || LI < ROWNO+2) 50 setclipped(); 51 if(!(CL = tgetstr("cl", &tbufptr))) 52 error("Hack needs CL."); 53 ND = tgetstr("nd", &tbufptr); 54 if(tgetflag("os")) 55 error("Hack can't have OS."); 56 CE = tgetstr("ce", &tbufptr); 57 UP = tgetstr("up", &tbufptr); 58 /* It seems that xd is no longer supported, and we should use 59 a linefeed instead; unfortunately this requires resetting 60 CRMOD, and many output routines will have to be modified 61 slightly. Let's leave that till the next release. */ 62 XD = tgetstr("xd", &tbufptr); 63 /* not: XD = tgetstr("do", &tbufptr); */ 64 if(!(CM = tgetstr("cm", &tbufptr))) { 65 if(!UP && !HO) 66 error("Hack needs CM or UP or HO."); 67 printf("Playing hack on terminals without cm is suspect...\n"); 68 getret(); 69 } 70 SO = tgetstr("so", &tbufptr); 71 SE = tgetstr("se", &tbufptr); 72 SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */ 73 if(!SO || !SE || (SG > 0)) SO = SE = 0; 74 CD = tgetstr("cd", &tbufptr); 75 set_whole_screen(); /* uses LI and CD */ 76 if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n"); 77 free(tptr); 78 } 79 80 start_screen() 81 { 82 xputs(TI); 83 xputs(VS); 84 } 85 86 end_screen() 87 { 88 xputs(VE); 89 xputs(TE); 90 } 91 92 /* Cursor movements */ 93 extern xchar curx, cury; 94 95 curs(x, y) 96 register int x, y; /* not xchar: perhaps xchar is unsigned and 97 curx-x would be unsigned as well */ 98 { 99 100 if (y == cury && x == curx) 101 return; 102 if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */ 103 cmov(x, y); /* bunker!wtm */ 104 return; 105 } 106 if(abs(cury-y) <= 3 && abs(curx-x) <= 3) 107 nocmov(x, y); 108 else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) { 109 (void) putchar('\r'); 110 curx = 1; 111 nocmov(x, y); 112 } else if(!CM) { 113 nocmov(x, y); 114 } else 115 cmov(x, y); 116 } 117 118 nocmov(x, y) 119 { 120 if (cury > y) { 121 if(UP) { 122 while (cury > y) { /* Go up. */ 123 xputs(UP); 124 cury--; 125 } 126 } else if(CM) { 127 cmov(x, y); 128 } else if(HO) { 129 home(); 130 curs(x, y); 131 } /* else impossible("..."); */ 132 } else if (cury < y) { 133 if(XD) { 134 while(cury < y) { 135 xputs(XD); 136 cury++; 137 } 138 } else if(CM) { 139 cmov(x, y); 140 } else { 141 while(cury < y) { 142 xputc('\n'); 143 curx = 1; 144 cury++; 145 } 146 } 147 } 148 if (curx < x) { /* Go to the right. */ 149 if(!ND) cmov(x, y); else /* bah */ 150 /* should instead print what is there already */ 151 while (curx < x) { 152 xputs(ND); 153 curx++; 154 } 155 } else if (curx > x) { 156 while (curx > x) { /* Go to the left. */ 157 xputs(BC); 158 curx--; 159 } 160 } 161 } 162 163 cmov(x, y) 164 register x, y; 165 { 166 xputs(tgoto(CM, x-1, y-1)); 167 cury = y; 168 curx = x; 169 } 170 171 xputc(c) char c; { 172 (void) fputc(c, stdout); 173 } 174 175 xputs(s) char *s; { 176 tputs(s, 1, xputc); 177 } 178 179 cl_end() { 180 if(CE) 181 xputs(CE); 182 else { /* no-CE fix - free after Harold Rynes */ 183 /* this looks terrible, especially on a slow terminal 184 but is better than nothing */ 185 register cx = curx, cy = cury; 186 187 while(curx < COLNO) { 188 xputc(' '); 189 curx++; 190 } 191 curs(cx, cy); 192 } 193 } 194 195 clear_screen() { 196 xputs(CL); 197 curx = cury = 1; 198 } 199 200 home() 201 { 202 if(HO) 203 xputs(HO); 204 else if(CM) 205 xputs(tgoto(CM, 0, 0)); 206 else 207 curs(1, 1); /* using UP ... */ 208 curx = cury = 1; 209 } 210 211 standoutbeg() 212 { 213 if(SO) xputs(SO); 214 } 215 216 standoutend() 217 { 218 if(SE) xputs(SE); 219 } 220 221 backsp() 222 { 223 xputs(BC); 224 curx--; 225 } 226 227 bell() 228 { 229 (void) putchar('\007'); /* curx does not change */ 230 (void) fflush(stdout); 231 } 232 233 static short tmspc10[] = { /* from termcap */ 234 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5 235 }; 236 237 delay_output() { 238 /* delay 50 ms - could also use a 'nap'-system call */ 239 /* BUG: if the padding character is visible, as it is on the 5620 240 then this looks terrible. */ 241 if(!flags.nonull) 242 tputs("50", 1, xputc); 243 244 /* cbosgd!cbcephus!pds for SYS V R2 */ 245 /* is this terminfo, or what? */ 246 /* tputs("$<50>", 1, xputc); */ 247 248 else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) { 249 /* delay by sending cm(here) an appropriate number of times */ 250 register int cmlen = strlen(tgoto(CM, curx-1, cury-1)); 251 register int i = 500 + tmspc10[ospeed]/2; 252 253 while(i > 0) { 254 cmov(curx, cury); 255 i -= cmlen*tmspc10[ospeed]; 256 } 257 } 258 } 259 260 cl_eos() /* free after Robert Viduya */ 261 { /* must only be called with curx = 1 */ 262 263 if(CD) 264 xputs(CD); 265 else { 266 register int cx = curx, cy = cury; 267 while(cury <= LI-2) { 268 cl_end(); 269 xputc('\n'); 270 curx = 1; 271 cury++; 272 } 273 cl_end(); 274 curs(cx, cy); 275 } 276 } 277