1 /* $Id: tty.c,v 1.2 2001/01/20 15:48:46 amura Exp $ */
2 /*
3 * Name: MG 2a
4 * Amiga console device virtual terminal display
5 * Last Edit: 29-Nov-87 mic@emx.cc.utexas.edu
6 * Created: 19-Apr-86 mic@emx.cc.utexas.edu
7 *
8 * Drives the Amiga console device display. The code is basically
9 * like the termcap driver in that it uses the console device
10 * scrolling region. It also has some hacks to manage the console
11 * device colors. The latest hack is to inform the terminal I/O
12 * driver when we intend to do an escape sequence; this allows the
13 * terminal I/O driver to turn off the cursor without breaking up
14 * the sequences, leading to a garbled screen.
15 */
16
17 /*
18 * $Log: tty.c,v $
19 * Revision 1.2 2001/01/20 15:48:46 amura
20 * very big terminal supported
21 *
22 * Revision 1.1.1.1 2000/06/27 01:48:01 amura
23 * import to CVS
24 *
25 */
26
27 #include <exec/types.h>
28 #include <exec/nodes.h>
29 #include <exec/lists.h>
30 #include <exec/tasks.h>
31 #include <exec/ports.h>
32 #include <exec/io.h>
33 #include <devices/console.h>
34 #include <libraries/dos.h>
35 #include <graphics/clip.h>
36 #include <graphics/view.h>
37 #include <graphics/rastport.h>
38 #include <graphics/layers.h>
39 #include <graphics/text.h>
40 #include <graphics/gfxbase.h>
41 #ifndef MANX
42 #include <intuition/intuitionbase.h>
43 #endif
44 #include <intuition/intuition.h>
45
46 #undef TRUE
47 #undef FALSE
48 #include "config.h" /* Dec. 15, 1992 by H.Ohkubo */
49 #include "def.h"
50
51 #define BEL 0x07 /* BEL character. */
52 #define ESC 0x1B /* ESC character. */
53 #define LF 0x0A /* Linefeed character */
54 #define CSI 0x9B /* Command Sequence Introducer */
55
56 extern int ttrow;
57 extern int ttcol;
58 extern int tttop;
59 extern int ttbot;
60 extern int tthue;
61
62 int tceeol = 3; /* Costs, ANSI display. */
63 int tcinsl = 17;
64 int tcdell = 16;
65
66
67 #ifdef CHANGE_COLOR
68 short mode_rendition = MODE_RENDITION, /* set standard colors */
69 text_rendition = TEXT_RENDITION,
70 text_fg = TEXT_FG + 30,
71 text_bg = TEXT_BG + 40,
72 mode_fg = MODE_FG + 30,
73 mode_bg = MODE_BG + 40;
74 #else /* colors are hard-coded */
75 #define mode_rendition MODE_RENDITION
76 #define text_rendition TEXT_RENDITION
77 #define text_fg (TEXT_FG + 30)
78 #define text_bg (TEXT_BG + 40)
79 #define mode_fg (MODE_FG + 30)
80 #define mode_bg (MODE_BG + 40)
81 #endif
82
83 #ifdef SUPPORT_ANSI
84 VOID asciiparm(int) ;
85 #else
86 VOID asciiparm() ;
87 #endif
88 /* VOID ttnowindow() ; */
89 VOID ttwindow() ;
90
91 extern struct Screen WBInfo; /* For Font Sensitive by H.Konishi */
92
93 /*
94 * Initialize the terminal when the editor
95 * Initialize the virtual terminal.
96 * Set the console device's top edge below
97 * the front-to-back gadgets, to avoid
98 * garbage when scrolling.
99 */
100 /* VOID */
ttinit()101 ttinit()
102 {
103 ttputc(CSI);
104 asciiparm(TOP_OFFSET);
105 ttputc('y');
106 }
107
108 /*
109 * Clean up the terminal, in anticipation of
110 * a return to the command interpreter. This
111 * is a no-op on the Amiga, since the window
112 * is deleted anyway.
113 */
114 /* VOID */
tttidy()115 tttidy()
116 {
117 }
118
119 /*
120 * Move the cursor to the specified origin 0 row and column position. Try to
121 * optimize out extra moves; redisplay may have left the cursor in the right
122 * location last time!
123 */
124 /* VOID */
ttmove(row,col)125 ttmove(row, col)
126 {
127 if (ttrow!=row || ttcol!=col) {
128 ttnflush(8); /* flush if buffer too full */
129 ttputc(CSI);
130 asciiparm(row+1);
131 ttputc(';');
132 asciiparm(col+1);
133 ttputc('H');
134 ttrow = row;
135 ttcol = col;
136 }
137 }
138
139 /*
140 * Erase to end of line.
141 */
142 /* VOID */
tteeol()143 tteeol()
144 {
145 ttnflush(2); /* flush if not enough room to fit in buffer */
146 ttputc(CSI);
147 ttputc('K');
148 }
149
150 /*
151 * Erase to end of page.
152 */
153 /* VOID */
tteeop()154 tteeop()
155 {
156 ttnflush(12); /* flush (but only if not enough room for seq */
157 ttputc(CSI);
158 asciiparm((tthue == CTEXT) ? text_rendition : mode_rendition);
159 ttputc(';');
160 asciiparm(text_fg);
161 ttputc(';');
162 asciiparm(text_bg);
163 ttputc('m');
164 ttputc(CSI); /* clear to end of display */
165 ttputc('J');
166 }
167
168 /*
169 * Make a noise.
170 */
171 /* VOID */
ttbeep()172 ttbeep()
173 {
174 ttputc(BEL);
175 ttflush();
176 }
177
178 /*
179 * Convert a number to decimal
180 * ascii, and write it out. Used to
181 * deal with numeric arguments.
182 */
183 VOID
asciiparm(n)184 asciiparm(n)
185 register int n;
186 {
187 if (n > 9)
188 asciiparm(n/10);
189 #ifdef BUGFIX /* Jan.4,1993 by H.Ohkubo */
190 ttputc((unsigned char)((n%10) + '0'));
191 #else /* Original code */
192 ttputc((n%10) + '0');
193 #endif
194 }
195
196 /*
197 * Insert a block of blank lines onto the
198 * screen, using a scrolling region that starts at row
199 * "row" and extends down to row "bot". Deal with the one
200 * line case, which is a little bit special, with special
201 * case code.
202 */
203 /* VOID */
ttinsl(row,bot,nchunk)204 ttinsl(row, bot, nchunk)
205 {
206 if (row == bot) { /* Funny case. */
207 if (nchunk != 1)
208 panic("ttinsl: nchunk != 1");
209 ttmove(row, 0);
210 tteeol();
211 return;
212 }
213 ttmove(1+bot-nchunk, 0);
214 if (nchunk > 0) {
215 ttwindow(row, bot);
216 ttnflush(4); /* don't break the sequence */
217 ttputc(CSI);
218 asciiparm(nchunk);
219 ttputc('T'); /* Scroll scrolling region down */
220 ttnowindow();
221 }
222 }
223
224 /*
225 * Delete a block of lines, with the uppermost
226 * line at row "row", in a screen slice that extends to
227 * row "bot". The "nchunk" is the number of lines that have
228 * to be deleted. It's really easy with the console
229 * device scrolling region.
230 */
231 /* VOID */
ttdell(row,bot,nchunk)232 ttdell(row, bot, nchunk)
233 {
234 if (row == bot) { /* One line special case */
235 ttmove(row, 0);
236 tteeol();
237 return;
238 }
239 if (nchunk > 0) {
240 ttwindow(row, bot);
241 ttnflush(4); /* don't break esc. sequence */
242 ttputc(CSI);
243 asciiparm(nchunk);
244 ttputc('S'); /* Scroll scrolling region up */
245 ttnowindow();
246 }
247 ttrow = HUGE;
248 ttcol = HUGE;
249 ttmove(bot-nchunk,0);
250 }
251
252 /*
253 * This routine sets the scrolling window on the display to go from line
254 * "top" to line "bot" (origin 0, inclusive). The caller checks for the
255 * pathalogical 1 line scroll window that doesn't work right on all
256 * systems, and avoids it. The "ttrow" and "ttcol" variables are set
257 * to a crazy value to ensure that ttmove() actually does something.
258 */
259
260 extern struct Window *EmW; /* The window MG uses */
261
262 VOID
ttwindow(top,bot)263 ttwindow(top,bot)
264 {
265 if (tttop != top || ttbot != bot) {
266 ttnflush(10); /* Flush if necessary */
267 ttputc(CSI); /* Home cursor */
268 ttputc('H');
269
270 ttputc(CSI); /* Set top offset */
271 asciiparm(TOP_OFFSET + top * FontHeight(EmW));
272 ttputc('y');
273
274 ttputc(CSI);
275 asciiparm(bot - top + 1); /* Set page length */
276 ttputc('t');
277
278 ttrow = HUGE; /* Force cursor reset */
279 ttcol = HUGE;
280 tttop = top; /* Save region state */
281 ttbot = bot;
282 }
283 }
284
285 /*
286 * Switch to full screen scrolling
287 */
288 /* VOID */
ttnowindow()289 ttnowindow()
290 {
291 ttnflush(10); /* Flush if necessary */
292 ttputc(CSI); /* Home cursor */
293 ttputc('H');
294
295 ttputc(CSI); /* Set top offset to normal */
296 asciiparm(TOP_OFFSET);
297 ttputc('y');
298
299 ttputc(CSI); /* Set page length to nrow */
300 asciiparm(nrow);
301 ttputc('t');
302
303 ttrow = HUGE; /* Make cursor unknown. */
304 ttcol = HUGE;
305 tttop = HUGE;
306 ttbot = HUGE;
307 }
308
309 #ifdef CHANGE_COLOR
310 /*
311 * Set the rendition of the mode line by
312 * selecting colors from the following:
313 * 0 -- plain text
314 * 1 -- bold-face
315 * 3 -- italic
316 * 4 -- underscore
317 * 7 -- inverse video
318 * Certain of these selections may be less than
319 * appealing :-)
320 */
321
ttmode(f,n)322 ttmode(f, n)
323 {
324 register int s;
325 char buf[2];
326
327 if (!(f & FFARG)) {
328 if ((s = ereply("Set mode line rendition (0-7): ",
329 buf, sizeof(buf))) != TRUE)
330 return (s);
331 n = atoi(buf);
332 }
333 if (n < 0 || n > 7)
334 return (FALSE);
335
336 mode_rendition = n; /* store the color */
337 sgarbf = TRUE;
338 return (TRUE);
339 }
340
341 /*
342 * Set the rendition of the text area.
343 * Most of these selections will be
344 * less than appealing :-]
345 */
346
tttext(f,n)347 tttext(f, n)
348 {
349 register int s;
350 char buf[2];
351
352 if (!(f & FFARG)) {
353 if ((s = ereply("Set text rendition (0-7): ",
354 buf, sizeof(buf))) != TRUE)
355 return (s);
356 n = atoi(buf);
357 }
358 if (n < 0 || n > 7)
359 return (FALSE);
360
361 text_rendition = n; /* store the color */
362 sgarbf = TRUE;
363 return (TRUE);
364 }
365
366 /*
367 * Set foreground color for entire window
368 * to a value between 30 and 37, which
369 * corresponds to the arguments 0-7.
370 * This requires a total refresh, which
371 * sets up the screen.
372 */
373
textforeground(f,n)374 textforeground(f, n)
375 {
376 register int s;
377 char buf[2];
378
379 if (!(f & FFARG)) {
380 if ((s = ereply("Text foreground color (0-7): ",
381 buf, sizeof(buf))) != TRUE)
382 return (s);
383 n = atoi(buf);
384 }
385 if (n < 0 || n > 7)
386 return (FALSE);
387
388 text_fg = n + 30;
389 sgarbf = TRUE;
390 return (TRUE);
391 }
392
393 /*
394 * Set background color for entire window
395 * to a value between 40 and 47 inclusive.
396 */
397
textbackground(f,n)398 textbackground(f, n)
399 {
400 register int s;
401 char buf[2];
402
403 if (!(f & FFARG)) {
404 if ((s = ereply("Text background color (0-7): ",
405 buf, sizeof(buf))) != TRUE)
406 return (s);
407 n = atoi(buf);
408 }
409 if (n < 0 || n > 7)
410 return (FALSE);
411
412 text_bg = n + 40;
413 sgarbf = TRUE;
414 return (TRUE);
415 }
416
417 /*
418 * Set foreground color for entire the mode line
419 */
420
modeforeground(f,n)421 modeforeground(f, n)
422 {
423 register int s;
424 char buf[2];
425
426 if (!(f & FFARG)) {
427 if ((s = ereply("Mode line foreground color (0-7): ",
428 buf, sizeof(buf))) != TRUE)
429 return (s);
430 n = atoi(buf);
431 }
432 if (n < 0 || n > 7)
433 return (FALSE);
434
435 mode_fg = n + 30;
436 sgarbf = TRUE;
437 return (TRUE);
438 }
439
440 /*
441 * Set background color for the mode line
442 */
443
modebackground(f,n)444 modebackground(f, n)
445 {
446 register int s;
447 char buf[2];
448
449 if (!(f & FFARG)) {
450 if ((s = ereply("Mode line background color (0-7): ",
451 buf, sizeof(buf))) != TRUE)
452 return (s);
453 n = atoi(buf);
454 }
455 if (n < 0 || n > 7)
456 return (FALSE);
457
458 mode_bg = n + 40;
459 sgarbf = TRUE;
460 return (TRUE);
461 }
462 #endif
463
464 /*
465 * Set the current writing color to the
466 * specified color. Watch for color changes that are
467 * not going to do anything (the color is already right)
468 * and don't send anything to the display.
469 */
470
471 /* VOID */
ttcolor(color)472 ttcolor(color)
473 register int color;
474 {
475 if (color != tthue) {
476 ttnflush(12); /* Flush if necessary */
477 if (color == CTEXT) { /* Normal video. */
478 ttputc(CSI); /* Reset to 0 */
479 ttputc('m');
480 ttputc(CSI); /* Set text style */
481 asciiparm(text_rendition);
482 ttputc(';');
483 asciiparm(text_fg);
484 ttputc(';');
485 asciiparm(text_bg);
486 ttputc('m');
487 } else if (color == CMODE) { /* Standout mode */
488 ttputc(CSI); /* Reset to 0 */
489 ttputc('m');
490 ttputc(CSI); /* Set standout mode */
491 asciiparm(mode_rendition);
492 ttputc(';');
493 asciiparm(mode_fg); /* Use mode line colors */
494 ttputc(';');
495 asciiparm(mode_bg);
496 ttputc('m');
497 }
498 tthue = color; /* Save the color. */
499 }
500 }
501
502 /*
503 * This routine is called by the "refresh the screen" command to try and resize
504 * the display. The new size, which must be deadstopped to not exceed the NROW
505 * and NCOL limits, is stored back into "nrow" and "ncol". Display can always
506 * deal with a screen NROW by NCOL. Look in "window.c" to see how the caller
507 * deals with a change. On the Amiga, we make the Intuition terminal driver
508 * do all the work.
509 */
510
511 /* VOID */
ttresize()512 ttresize()
513 {
514 setttysize();
515 vtsetsize(ncol, nrow);
516 }
517