1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65: #include <sys/cdefs.h>
66: #ifndef lint
67: __RCSID("$NetBSD: hack.termcap.c,v 1.12 2003/04/02 18:36:40 jsm Exp $");
68: #endif
69:
70: #include <string.h>
71: #include <termios.h>
72: #include <termcap.h>
73: #include <stdlib.h>
74: #include <unistd.h>
75: #include "hack.h"
76: #include "extern.h"
77: #include "def.flag.h"
78:
79: static char tbuf[512];
80: char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
81: static char *VS, *VE;
82: static int SG;
83: char PC = '\0';
84: char *CD;
85: int CO, LI;
86:
87: void
88: startup()
89: {
90: char *term;
91: char *tptr;
92: char *tbufptr, *pc;
93:
94: tptr = (char *) alloc(1024);
95:
96: tbufptr = tbuf;
97: if (!(term = getenv("TERM")))
98: error("Can't get TERM.");
99: if (!strncmp(term, "5620", 4))
100: flags.nonull = 1;
101: if (tgetent(tptr, term) < 1)
102: error("Unknown terminal type: %s.", term);
103: if ((pc = tgetstr("pc", &tbufptr)) != NULL)
104: PC = *pc;
105: if (!(BC = tgetstr("bc", &tbufptr))) {
106: if (!tgetflag("bs"))
107: error("Terminal must backspace.");
108: BC = tbufptr;
109: tbufptr += 2;
110: *BC = '\b';
111: }
112: HO = tgetstr("ho", &tbufptr);
113: CO = tgetnum("co");
114: LI = tgetnum("li");
115: if (CO < COLNO || LI < ROWNO + 2)
116: setclipped();
117: if (!(CL = tgetstr("cl", &tbufptr)))
118: error("Hack needs CL.");
119: ND = tgetstr("nd", &tbufptr);
120: if (tgetflag("os"))
121: error("Hack can't have OS.");
122: CE = tgetstr("ce", &tbufptr);
123: UP = tgetstr("up", &tbufptr);
124:
125:
126:
127:
128:
129:
130: XD = tgetstr("xd", &tbufptr);
131:
132: if (!(CM = tgetstr("cm", &tbufptr))) {
133: if (!UP && !HO)
134: error("Hack needs CM or UP or HO.");
135: printf("Playing hack on terminals without cm is suspect...\n");
136: getret();
137: }
138: SO = tgetstr("so", &tbufptr);
139: SE = tgetstr("se", &tbufptr);
140: SG = tgetnum("sg");
141: if (!SO || !SE || (SG > 0))
142: SO = SE = 0;
143: CD = tgetstr("cd", &tbufptr);
144: set_whole_screen();
145: if (tbufptr - tbuf > (int)sizeof(tbuf))
146: error("TERMCAP entry too big...\n");
147: free(tptr);
148: }
149:
150: void
151: start_screen()
152: {
153: xputs(TI);
154: xputs(VS);
155: }
156:
157: void
158: end_screen()
159: {
160: xputs(VE);
161: xputs(TE);
162: }
163:
164:
165: void
166: curs(x, y)
167: int x, y;
168:
169: {
170:
171: if (y == cury && x == curx)
172: return;
173: if (!ND && (curx != x || x <= 3)) {
174: cmov(x, y);
175: return;
176: }
177: if (abs(cury - y) <= 3 && abs(curx - x) <= 3)
178: nocmov(x, y);
179: else if ((x <= 3 && abs(cury - y) <= 3) || (!CM && x < abs(curx - x))) {
180: (void) putchar('\r');
181: curx = 1;
182: nocmov(x, y);
183: } else if (!CM) {
184: nocmov(x, y);
185: } else
186: cmov(x, y);
187: }
188:
189: void
190: nocmov(x, y)
191: int x, y;
192: {
193: if (cury > y) {
194: if (UP) {
195: while (cury > y) {
196: xputs(UP);
197: cury--;
198: }
199: } else if (CM) {
200: cmov(x, y);
201: } else if (HO) {
202: home();
203: curs(x, y);
204: }
205: } else if (cury < y) {
206: if (XD) {
207: while (cury < y) {
208: xputs(XD);
209: cury++;
210: }
211: } else if (CM) {
212: cmov(x, y);
213: } else {
214: while (cury < y) {
215: xputc('\n');
216: curx = 1;
217: cury++;
218: }
219: }
220: }
221: if (curx < x) {
222: if (!ND)
223: cmov(x, y);
224: else
225:
226: while (curx < x) {
227: xputs(ND);
228: curx++;
229: }
230: } else if (curx > x) {
231: while (curx > x) {
232: xputs(BC);
233: curx--;
234: }
235: }
236: }
237:
238: void
239: cmov(x, y)
240: int x, y;
241: {
242: xputs(tgoto(CM, x - 1, y - 1));
243: cury = y;
244: curx = x;
245: }
246:
247: int
248: xputc(c)
249: char c;
250: {
251: return (fputc(c, stdout));
252: }
253:
254: void
255: xputs(s)
256: char *s;
257: {
258: tputs(s, 1, xputc);
259: }
260:
261: void
262: cl_end()
263: {
264: if (CE)
265: xputs(CE);
266: else {
267:
268:
269:
270:
271: int cx = curx, cy = cury;
272:
273: while (curx < COLNO) {
274: xputc(' ');
275: curx++;
276: }
277: curs(cx, cy);
278: }
279: }
280:
281: void
282: clear_screen()
283: {
284: xputs(CL);
285: curx = cury = 1;
286: }
287:
288: void
289: home()
290: {
291: if (HO)
292: xputs(HO);
293: else if (CM)
294: xputs(tgoto(CM, 0, 0));
295: else
296: curs(1, 1);
297: curx = cury = 1;
298: }
299:
300: void
301: standoutbeg()
302: {
303: if (SO)
304: xputs(SO);
305: }
306:
307: void
308: standoutend()
309: {
310: if (SE)
311: xputs(SE);
312: }
313:
314: void
315: backsp()
316: {
317: xputs(BC);
318: curx--;
319: }
320:
321: void
322: bell()
323: {
324: (void) putchar('\007');
325: (void) fflush(stdout);
326: }
327:
328: void
329: delay_output()
330: {
331:
332:
333:
334: usleep(50000);
335: }
336:
337: void
338: cl_eos()
339: {
340:
341:
342: if (CD)
343: xputs(CD);
344: else {
345: int cx = curx, cy = cury;
346: while (cury <= LI - 2) {
347: cl_end();
348: xputc('\n');
349: curx = 1;
350: cury++;
351: }
352: cl_end();
353: curs(cx, cy);
354: }
355: }