~ubuntu-branches/ubuntu/wily/splitvt/wily

« back to all changes in this revision

Viewing changes to .pc/old.changes.patch/vt100.c

  • Committer: Bazaar Package Importer
  • Author(s): Mònica Ramírez Arceda
  • Date: 2011-02-13 00:21:26 UTC
  • Revision ID: james.westby@ubuntu.com-20110213002126-dl9ggx3zwvpu0awj
Tags: 1.6.6-8
* Adopt the package. (Closes: #489450)
* Switch to quilt format: add old.changes.patch.
* Tidy up debian/copyright: organize it in sections, add copyright
  notice, add GPL version and add myself as a Debian mantainer.
* Manpage:
  - Change - by \- to use minus sign instead of hyphen in manpage 
    (fix.man.minus.sign.patch).
  - Add .TB macro (fix.man.macro.not.defined.patch).
* Override lintian warning (setgid-binary): splitvt needs write 
  access to /var/run/utmp file.
* Add debian/install, debian/docs, debian/examples and
  debian/splitvt.manpages in order to minimize debian/rules.
* Update debian/rules to use overrides of dh_*.
* Delete Homepage field in debian/control and debian/watch: 
  upstream site doesn't exist any more.
* Bump to Standards-Version 3.9.1. No changes required.
* Add Vcs-Git, Vcs-Browser fields in debian/control.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* This file contains the terminal "driver" code for splitsh.
 
3
   It is designed to keep track of the position of the cursor
 
4
   while handling a split window of vt100 emulation.
 
5
   All of the routines assume that there is no other output 
 
6
   going onto the standard output screen, to mess it up.
 
7
 
 
8
   Many thanks to Matt Ostanik who wrote the ANSI Handbook.
 
9
*/
 
10
 
 
11
#include        <sys/types.h>
 
12
#ifdef HAVE_TERMIO_H
 
13
#include        <termio.h>              /* Used only for TIOCGWINSZ */
 
14
#else
 
15
#include        <sys/ioctl.h>           /* Used only for TIOCGWINSZ */
 
16
#endif
 
17
#include        <errno.h>
 
18
#include        <stdio.h>
 
19
#include        <stdlib.h>
 
20
#include        <string.h>
 
21
#include        <ctype.h>
 
22
#include        "vt100.h"
 
23
#include        "video.h"
 
24
#include        "terminal.h"
 
25
 
 
26
#define SEP_CHAR        ' '             /* Separator bar character */
 
27
 
 
28
int TABSTOP=8;                          /* The default tabstop value */
 
29
 
 
30
/* Two virtual windows + a pointer to the current one */
 
31
static window upper, lower;
 
32
window *curwin;
 
33
 
 
34
/* One physical window */
 
35
struct physical physical;
 
36
 
 
37
static char terminal_type[BUFSIZ];      /* Our terminal type */
 
38
static char *sep;                       /* The window separator string */
 
39
 
 
40
/* The various output processing functions, based on state */
 
41
void scan_for_esc();
 
42
void E_(), E_brac(), E_brac_Q(), E_lparen(), E_rparen(), E_pound();
 
43
 
 
44
/* Make these four variables accessable to the calling program */
 
45
int UU_lines=0;         /* The user requested lines for the upper window */
 
46
int WU_lines=0;         /* The number of lines for the upper window */
 
47
int WL_lines=0;         /* The number of lines for the lower window */
 
48
int W_columns=0;        /* The number of columns per window */
 
49
 
 
50
static int LU_lines;    /* A local copy of UU_lines that is modified */
 
51
 
 
52
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
53
/* Reset the escape scanning sequence: */
 
54
static void reset_escape(win)
 
55
window *win;
 
56
{
 
57
        int i;
 
58
 
 
59
        win->process_char=scan_for_esc;
 
60
        for ( i=0; i<MAX_PARAMS; ++i )
 
61
                win->esc_param[i]=0;
 
62
        win->param_idx=0;
 
63
        win->cur_param=(&win->esc_param[win->param_idx]);
 
64
}
 
65
static void reset_esc()
 
66
{
 
67
        reset_escape(curwin);
 
68
}
 
69
/* Initialize a window structure: */
 
70
static void vt_resetwin(win)
 
71
window *win;
 
72
{
 
73
        win->cursor.x=1;
 
74
        win->cursor.y=1;
 
75
        win->saved_cursor.x=1;
 
76
        win->saved_cursor.y=1;
 
77
        win->cols=physical.cols;
 
78
        win->scr_upper=1;
 
79
        win->scr_lower=win->rows;
 
80
        win->saved_cursor.x=0;
 
81
        win->saved_cursor.y=0;
 
82
        win->key_state=normal;
 
83
        win->textattr=NORMAL;
 
84
        win->saved_textattr=NORMAL;
 
85
        win->charset[G0]=US_CHARSET;
 
86
        win->charset[G1]=US_CHARSET;
 
87
        reset_escape(win);
 
88
}
 
89
/* Check to make sure the window cursor values are sane. */
 
90
static void vt_checkwin(win)
 
91
window *win;
 
92
{
 
93
        if ( win->cursor.x > win->rows )
 
94
                win->cursor.x=win->rows;
 
95
        if ( win->cursor.y > win->cols )
 
96
                win->cursor.y=win->cols;
 
97
        if ( win->scr_lower > win->rows )
 
98
                win->scr_lower=win->rows;
 
99
}
 
100
/* Set the current window: */
 
101
static int lastwin = (-1);
 
102
void set_win(which)
 
103
int which;
 
104
{
 
105
        window *other;
 
106
        int i;
 
107
 
 
108
        /* Are we already in position? */
 
109
        if ( which == lastwin )
 
110
                return;
 
111
 
 
112
        /* Set the current window and move the cursor into position */
 
113
        curwin = physical.subwins[which];
 
114
        other = physical.subwins[!which];
 
115
        vt_setscroll(curwin->scr_upper+curwin->row_offset, 
 
116
                                        curwin->scr_lower+curwin->row_offset);
 
117
        vt_goto(curwin->cursor.x+curwin->row_offset, curwin->cursor.y);
 
118
 
 
119
        /* Make sure the terminal is in the current window's state */
 
120
        for ( i=0; i<NCHARSETS; ++i ) {
 
121
                if ( curwin->charset[i] != other->charset[i] )
 
122
                        vt_altcharset(i, curwin->charset[i]);
 
123
        }
 
124
        if ( curwin->key_state != other->key_state )
 
125
                vt_keystate(curwin->key_state);
 
126
        if ( curwin->textattr != other->textattr )
 
127
                vt_setattr((int)curwin->textattr);
 
128
        vt_update();
 
129
        lastwin=which;
 
130
}
 
131
 
 
132
/* Set the terminal attributes to those of the specified window */
 
133
/* This must be called _after_ vt_restcursor(), or it won't work */
 
134
static void set_attr(win)
 
135
window *win;
 
136
{
 
137
        unsigned char on=NORMAL;
 
138
 
 
139
        vt_resetattr();
 
140
        (void) check_attr(0, win->textattr, &on);
 
141
}
 
142
 
 
143
/* Process the ^[[X;Xm escape.  Made into a separate routine to support
 
144
   ansi color. */
 
145
static void process_m(win, n)
 
146
window *win;
 
147
int n;
 
148
{
 
149
        switch (n) {
 
150
                case 0: /* Turn all attributes off */
 
151
                        win->textattr=NORMAL;
 
152
                        vt_resetattr();
 
153
                        break;
 
154
                case 1: /* Turn on bold */
 
155
                        win->textattr |= BOLD;
 
156
                        vt_bold(1);
 
157
                        break;
 
158
                case 2: /* Half brightness */
 
159
                        /* UNSUPPORTED */
 
160
                        break;
 
161
                case 4: /* Turn on underlining */
 
162
                        win->textattr |= UNDERLINE;
 
163
                        vt_underline(1);
 
164
                        break;
 
165
                case 5: /* Turn on blinking */
 
166
                        win->textattr |= BLINK;
 
167
                        vt_blink(1);
 
168
                        break;
 
169
                case 7: /* Turn on reverse */
 
170
                        win->textattr |= REVERSE;
 
171
                        vt_reverse(1);
 
172
                        break;
 
173
                case 21: /* Normal brightness */
 
174
                        /* UNSUPPORTED */
 
175
                        break;
 
176
                case 22: /* Turn off bold */
 
177
                        win->textattr &= ~BOLD;
 
178
                        vt_bold(0);
 
179
                        break;
 
180
                case 24: /* Turn off underlining */
 
181
                        win->textattr &= ~UNDERLINE;
 
182
                        vt_underline(0);
 
183
                        break;
 
184
                case 25: /* Turn off blinking */
 
185
                        win->textattr &= ~BLINK;
 
186
                        vt_blink(0);
 
187
                        break;
 
188
                case 27: /* Turn off reverse */
 
189
                        win->textattr &= ~REVERSE;
 
190
                        vt_reverse(0);
 
191
                        break;
 
192
                case 30:
 
193
                case 31:
 
194
                case 32:
 
195
                case 33:
 
196
                case 34:
 
197
                case 35:
 
198
                case 36:
 
199
                case 37: /* Set foreground color */
 
200
                        vt_setfg(n-30);
 
201
                        break;
 
202
                case 40:
 
203
                case 41:
 
204
                case 42:
 
205
                case 43:
 
206
                case 44:
 
207
                case 45:
 
208
                case 46:
 
209
                case 47: /* Set background color */
 
210
                        vt_setbg(n-40);
 
211
                        break;
 
212
                default: /* Unknown escape */
 
213
                        break;
 
214
        }
 
215
}
 
216
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
217
void scan_for_esc(c, source)
 
218
int c;
 
219
int *source;
 
220
{
 
221
        int i;
 
222
 
 
223
        switch (c) {
 
224
                /* Taken from vt102.codes */
 
225
                case '\000':    /* NULL (fill character) */
 
226
                case '\003':    /* EXT  (half duplex turnaround) */
 
227
                case '\004':    /* EOT  (can be disconnect char) */
 
228
                case '\005':    /* ENQ  (generate answerback) */
 
229
                                printf("%c", c);
 
230
                                break;
 
231
                case '\007':    /* BEL  (sound terminal bell) */
 
232
                                vt_bell();
 
233
                                break;
 
234
                case '\b':      /* Backspace; move left one character */
 
235
                                if ( curwin->cursor.y != 1 ) {
 
236
                                        --curwin->cursor.y;
 
237
                                        vt_left(curwin->esc_param[0]);
 
238
                                }
 
239
                                break;
 
240
                case '\t':      /* Tab.  Handle with direct motion (Buggy) */
 
241
                                i=curwin->cursor.y;
 
242
                                do {
 
243
                                        ++curwin->cursor.y;
 
244
                                } while ( !curwin->tabstops[curwin->cursor.y-1]
 
245
                                        && (curwin->cursor.y < curwin->cols) );
 
246
                                vt_right(curwin->cursor.y - i);
 
247
                                break;
 
248
                case '\013':    /* Processed as linefeeds */
 
249
                case '\014':    /* Don't let the cursor move below window or scrolling region */
 
250
                case '\n':      if ( curwin->cursor.x < curwin->scr_lower )
 
251
                                        ++curwin->cursor.x;
 
252
                                else
 
253
                                        scroll_video(curwin, 1);
 
254
                                printf("\n");
 
255
                                break;
 
256
                case '\r':      /* Move cursor to left margin */
 
257
                                curwin->cursor.y = 1;
 
258
                                printf("\r");
 
259
                                break;
 
260
                case '\016':    /* S0 (selects G1 charset) */
 
261
                case '\017':    /* S1 (selects G0 charset) */
 
262
                case '\021':    /* XON (continue transmission) */
 
263
                case '\022':    /* XOFF (stop transmission) */
 
264
                                printf("%c", c);
 
265
                                break;
 
266
                case '\030':    /* Processed as escape cancel */
 
267
                case '\032':    reset_esc();
 
268
                                break;
 
269
                case '\033':    curwin->process_char=E_;
 
270
                                break;
 
271
                default:        if ( curwin->cursor.y > curwin->cols )
 
272
                                {       /* Wrap */
 
273
                                        if (curwin->cursor.x<curwin->scr_lower)
 
274
                                        {
 
275
                                                ++curwin->cursor.x;
 
276
                                        } else
 
277
                                                scroll_video(curwin, 1);
 
278
                                        printf("\r\n");
 
279
                                        curwin->cursor.y=1;
 
280
                                }
 
281
                                add_video(curwin, c); printf("%c", c);
 
282
                                ++curwin->cursor.y;
 
283
                                break;
 
284
        }
 
285
        return;
 
286
}
 
287
void E_(c, source)
 
288
int c;
 
289
int *source;
 
290
{
 
291
        /* Return inside the switch to prevent reset_esc() */
 
292
        switch (c) {
 
293
                case '\030':    /* Processed as escape cancel */
 
294
                case '\032':    reset_esc();
 
295
                                return;
 
296
                case '[':       curwin->process_char=E_brac;
 
297
                                return;
 
298
                case '(':       curwin->process_char=E_lparen;
 
299
                                return;
 
300
                case ')':       curwin->process_char=E_rparen;
 
301
                                return;
 
302
                case '#':       curwin->process_char=E_pound;
 
303
                                return;
 
304
                case 'D':       /* Cursor down with scroll up at margin */
 
305
                                if ( curwin->cursor.x < curwin->scr_lower ) {
 
306
                                        ++curwin->cursor.x;
 
307
                                } else
 
308
                                        scroll_video(curwin, 1);
 
309
                                printf("\n");
 
310
                                break;
 
311
                case 'M':       /* Reverse scroll (move up; scroll at top) */
 
312
                                if ( (curwin->cursor.x > curwin->scr_upper) )
 
313
                                        --curwin->cursor.x;
 
314
                                else
 
315
                                        revscroll_video(curwin, 1);
 
316
                                vt_revscroll();
 
317
                                break;
 
318
                case 'E':       /* Next line (CR-LF) */
 
319
                                if ( curwin->cursor.x < curwin->scr_lower )
 
320
                                        ++curwin->cursor.x;
 
321
                                else 
 
322
                                        scroll_video(curwin, 1);
 
323
                                curwin->cursor.y = 1;
 
324
                                printf("\r\n");
 
325
                                break;
 
326
                case '7':       /* Save cursor and attribute */
 
327
                                curwin->saved_cursor=curwin->cursor;
 
328
                                curwin->saved_textattr=curwin->textattr;
 
329
                                break;
 
330
                case '8':       /* Restore saved cursor and attribute */
 
331
                                curwin->cursor=curwin->saved_cursor;
 
332
                                if ( curwin->cursor.x > curwin->rows )
 
333
                                        curwin->cursor.x = curwin->rows;
 
334
                                if ( curwin->cursor.y > curwin->cols )
 
335
                                        curwin->cursor.y = curwin->cols;
 
336
                                vt_goto(curwin->cursor.x+curwin->row_offset, 
 
337
                                                        curwin->cursor.y);
 
338
                                curwin->textattr=curwin->saved_textattr;
 
339
                                set_attr(curwin);
 
340
                                break;
 
341
                case '=':       /* Set application keypad mode */
 
342
                                curwin->key_state=application;
 
343
                                vt_keystate(curwin->key_state);
 
344
                                break;
 
345
                case '>':       /* Set numeric keypad mode */
 
346
                                curwin->key_state=normal;
 
347
                                vt_keystate(curwin->key_state);
 
348
                                break;
 
349
                case 'N':       /* Select charset G2 for one character */
 
350
                                /* UNSUPPORTED */
 
351
                                break;
 
352
                case 'O':       /* Select charset G3 for one character */
 
353
                                /* UNSUPPORTED */
 
354
                                break;
 
355
                case 'H':       /* Set horizontal tab */
 
356
                                curwin->tabstops[curwin->cursor.y-1]=1;
 
357
                                break;
 
358
                case 'Z':       /* Request terminal identification string */
 
359
                                /* Respond with "I am a vt102" */
 
360
                                write(*source, "\033[?6c", 5);
 
361
                                break;
 
362
                case 'c':       /* Terminal reset */
 
363
                                vt_resetwin(curwin);
 
364
                                break;
 
365
                default:        /* Unrecognized escape: ignore */
 
366
                                break;
 
367
        }
 
368
        reset_esc();
 
369
}
 
370
void E_brac(c, source)
 
371
int c;
 
372
int *source;
 
373
{
 
374
        int newx, newy, i;
 
375
        char reply[128];
 
376
 
 
377
        /* Check for numeric argument first */
 
378
        if ( isdigit(c) ) {
 
379
                *curwin->cur_param *= 10;
 
380
                *curwin->cur_param += (c-'0');
 
381
                return;
 
382
        }
 
383
 
 
384
        /* Return inside the switch to prevent reset_esc() */
 
385
        switch (c) {
 
386
                case '\030':    /* Processed as escape cancel */
 
387
                case '\032':    reset_esc();
 
388
                                return;
 
389
                case '?':       /* Format should be \E[?<n> */
 
390
                                if ( *curwin->cur_param )
 
391
                                        reset_esc();
 
392
                                else
 
393
                                        curwin->process_char=E_brac_Q;
 
394
                                return;
 
395
                case ';':       if ( ++curwin->param_idx < MAX_PARAMS ) {
 
396
                                        curwin->cur_param =
 
397
                                        &curwin->esc_param[curwin->param_idx];
 
398
                                }
 
399
                                return;
 
400
                case 'h':       /* Set modes */
 
401
                        switch (curwin->esc_param[0]) {
 
402
                                case 2:  /* Lock keyboard */
 
403
                                         /* UNSUPPORTED */
 
404
                                case 4:  /* Character insert mode */
 
405
                                         /* UNSUPPORTED */
 
406
                                case 12: /* Local echo on */
 
407
                                         /* UNSUPPORTED (easily supported) */
 
408
                                case 20: /* <Return> = CR */
 
409
                                         /* UNSUPPORTED (easily supported) */
 
410
                                default: break;
 
411
                        }
 
412
                        break;
 
413
                case 'l':       /* Reset modes */
 
414
                        switch (curwin->esc_param[0]) {
 
415
                                case 2:  /* Unlock keyboard */
 
416
                                         /* UNSUPPORTED */
 
417
                                case 4:  /* Character overstrike mode */
 
418
                                         /* UNSUPPORTED */
 
419
                                case 12: /* Local echo off */
 
420
                                         /* UNSUPPORTED (easily supported) */
 
421
                                case 20: /* <Return> = CR-LF */
 
422
                                         /* UNSUPPORTED (easily supported) */
 
423
                                default: break;
 
424
                        }
 
425
                        break;
 
426
                case 'r':       /* Set scroll region */
 
427
                        if ( ! curwin->esc_param[0] && ! curwin->esc_param[1] ) {
 
428
                                curwin->scr_upper=1;
 
429
                                curwin->scr_lower=curwin->rows;
 
430
                        } else {
 
431
                                /* Check parameters: VERY important. :) */
 
432
                                if (curwin->esc_param[0] < 1) /* Not needed */
 
433
                                        curwin->scr_upper=1;
 
434
                                else
 
435
                                        curwin->scr_upper=curwin->esc_param[0];
 
436
 
 
437
                                if ( curwin->esc_param[1] > curwin->rows )
 
438
                                        curwin->scr_lower=curwin->rows;
 
439
                                else
 
440
                                        curwin->scr_lower=curwin->esc_param[1];
 
441
 
 
442
                                if ( curwin->scr_upper > curwin->scr_lower ) {
 
443
                                        /* Reset scroll region */
 
444
                                        curwin->scr_upper=1;
 
445
                                        curwin->scr_lower=curwin->rows;
 
446
                                }
 
447
                        }
 
448
                        curwin->cursor.x=1;
 
449
                        curwin->cursor.y=1;
 
450
                        vt_setscroll(curwin->scr_upper+curwin->row_offset, 
 
451
                                        curwin->scr_lower+curwin->row_offset);
 
452
                        vt_goto(curwin->cursor.x+curwin->row_offset, 1);
 
453
                        break;
 
454
                case 'A':       /* Cursor UP */
 
455
                        if ( curwin->cursor.x == curwin->scr_upper )
 
456
                                break;
 
457
                        if ( ! curwin->esc_param[0] )
 
458
                                curwin->esc_param[0]=1;
 
459
                        newx = (curwin->cursor.x - curwin->esc_param[0]);
 
460
                        if ( newx > curwin->scr_upper ) {
 
461
                                curwin->cursor.x=newx;
 
462
                                vt_up(curwin->esc_param[0]);
 
463
                        } else {
 
464
                                curwin->cursor.x=curwin->scr_upper;
 
465
                                vt_goto(curwin->cursor.x+curwin->row_offset,
 
466
                                                        curwin->cursor.y);
 
467
                        }
 
468
                        break;
 
469
                case 'B':       /* Cursor DOWN */
 
470
                        if ( curwin->cursor.x == curwin->scr_lower )
 
471
                                break;
 
472
                        if ( ! curwin->esc_param[0] )
 
473
                                curwin->esc_param[0]=1;
 
474
                        newx = (curwin->cursor.x + curwin->esc_param[0]);
 
475
                        if ( newx <= curwin->scr_lower ) {
 
476
                                curwin->cursor.x=newx;
 
477
                                vt_down(curwin->esc_param[0]);
 
478
                        } else {
 
479
                                curwin->cursor.x=curwin->scr_lower;
 
480
                                vt_goto(curwin->cursor.x+curwin->row_offset,
 
481
                                                        curwin->cursor.y);
 
482
                        }
 
483
                        break;
 
484
                case 'C':       /* Cursor RIGHT */
 
485
                        if ( curwin->cursor.y == curwin->cols )
 
486
                                break;
 
487
                        if ( ! curwin->esc_param[0] )
 
488
                                curwin->esc_param[0]=1;
 
489
                        newy = (curwin->cursor.y + curwin->esc_param[0]);
 
490
                        if ( newy < curwin->cols ) {
 
491
                                curwin->cursor.y=newy;
 
492
                                vt_right(curwin->esc_param[0]);
 
493
                        } else {
 
494
                                curwin->cursor.y=curwin->cols;
 
495
                                vt_goto(curwin->cursor.x+curwin->row_offset,
 
496
                                                        curwin->cursor.y);
 
497
                        }
 
498
                        break;
 
499
                case 'D':       /* Cursor LEFT */
 
500
                        if ( curwin->cursor.y == 1 )
 
501
                                break;
 
502
                        if ( ! curwin->esc_param[0] )
 
503
                                curwin->esc_param[0]=1;
 
504
                        newy = (curwin->cursor.y - curwin->esc_param[0]);
 
505
                        if ( newy > 1 ) {
 
506
                                curwin->cursor.y=newy;
 
507
                                vt_left(curwin->esc_param[0]);
 
508
                        } else {
 
509
                                curwin->cursor.y=1;
 
510
                                printf("\r");
 
511
                        }
 
512
                        break;
 
513
                case 'f':
 
514
                case 'H':       /* Move cursor to coordinates */
 
515
                        if ( ! curwin->esc_param[0] )
 
516
                                curwin->esc_param[0]=1;
 
517
                        if ( ! curwin->esc_param[1] )
 
518
                                curwin->esc_param[1]=1;
 
519
                        if ( (curwin->cursor.x=curwin->esc_param[0]) >
 
520
                                                                curwin->rows )
 
521
                                curwin->cursor.x=curwin->rows;
 
522
                        if ( (curwin->cursor.y=curwin->esc_param[1]) >
 
523
                                                                curwin->cols )
 
524
                                curwin->cursor.y=curwin->cols;
 
525
                        vt_goto(curwin->cursor.x+curwin->row_offset,
 
526
                                                        curwin->cursor.y);
 
527
                        break;
 
528
                case 'g':       /* Clear tabstops */
 
529
                        switch (curwin->esc_param[0]) {
 
530
                                case 0: /* Clear a tabstop */
 
531
                                        curwin->tabstops[curwin->cursor.y-1]=0;
 
532
                                        break;
 
533
                                case 3: /* Clear all tabstops */
 
534
                                        for (newy=0; newy<curwin->cols; ++newy)
 
535
                                                curwin->tabstops[newy]=0;
 
536
                                        break;
 
537
                                default: break;
 
538
                        }
 
539
                        break;
 
540
                case 'm':       /* Set terminal attributes */
 
541
                        process_m(curwin, curwin->esc_param[0]);
 
542
                        for ( i=1; curwin->esc_param[i] && i<MAX_PARAMS; ++i )
 
543
                                process_m(curwin, curwin->esc_param[i]);
 
544
                        break;
 
545
                case 'J':       /* Clear screen */
 
546
                        switch (curwin->esc_param[0]) {
 
547
                                case 0: /* Clear from cursor down */
 
548
                                        erase_video(curwin, 
 
549
                                                curwin->cursor.x, curwin->rows,
 
550
                                                1, curwin->cols);
 
551
                                        newx=curwin->cursor.x;
 
552
                                        vt_savecursor();
 
553
                                        printf("\r");
 
554
                                        while ( newx++ < curwin->rows ) {
 
555
                                                vt_clreol();
 
556
                                                printf("\n");
 
557
                                        }
 
558
                                        vt_clreol();
 
559
                                        vt_restcursor();
 
560
                                        break;
 
561
                                case 1: /* Clear from cursor up */
 
562
                                        erase_video(curwin, 
 
563
                                                1, curwin->cursor.x,
 
564
                                                1, curwin->cols);
 
565
                                        newx=curwin->cursor.x;
 
566
                                        vt_savecursor();
 
567
                                        printf("\r");
 
568
                                        while ( --newx > 0 ) {
 
569
                                                vt_clreol();
 
570
                                                vt_up(1);
 
571
                                        }
 
572
                                        vt_clreol();
 
573
                                        vt_restcursor();
 
574
                                        break;
 
575
                                case 2: /* Clear whole screen */
 
576
                                        erase_video(curwin, 
 
577
                                                1, curwin->rows,
 
578
                                                1, curwin->cols);
 
579
                                        vt_goto(curwin->row_offset+1, 1);
 
580
                                        curwin->cursor.x=1;
 
581
                                        curwin->cursor.y=1;
 
582
                                        newx=curwin->cursor.x;
 
583
                                        vt_savecursor();
 
584
                                        printf("\r");
 
585
                                        while ( newx++ < curwin->rows ) {
 
586
                                                vt_clreol();
 
587
                                                printf("\n");
 
588
                                        }
 
589
                                        vt_clreol();
 
590
                                        vt_restcursor();
 
591
                                        break;
 
592
                                default: break;
 
593
                        }
 
594
                        break;
 
595
                case 'K':       /* Clear line */
 
596
                        switch (curwin->esc_param[0]) {
 
597
                                case 0: /* Clear to end of line */
 
598
                                        erase_video(curwin, 
 
599
                                                curwin->cursor.x, curwin->cursor.x,
 
600
                                                curwin->cursor.y, curwin->cols);
 
601
                                        vt_clreol();
 
602
                                        break;
 
603
                                case 1: /* Clear to beginning of line */
 
604
                                        erase_video(curwin, 
 
605
                                                curwin->cursor.x, curwin->cursor.x,
 
606
                                                1, curwin->cursor.y);
 
607
                                        vt_clrbgl();
 
608
                                        break;
 
609
                                case 2: /* Clear whole line */
 
610
                                        erase_video(curwin, 
 
611
                                                curwin->cursor.x, curwin->cursor.x,
 
612
                                                1, curwin->cols);
 
613
                                        vt_clrline();
 
614
                                        break;
 
615
                        }
 
616
                        break;
 
617
                case 'P':       /* Delete under cursor */
 
618
                                erase_video(curwin, 
 
619
                                        curwin->cursor.x, curwin->cursor.x,
 
620
                                        curwin->cursor.y, curwin->cursor.y);
 
621
                                vt_delunder(curwin->esc_param[0]);
 
622
                                break;
 
623
                case 'M':       /* Delete lines */
 
624
                                revscroll_video(curwin, 1);
 
625
                                vt_delline(curwin->esc_param[0]);
 
626
                                break;
 
627
                case 'L':       /* Insert lines */
 
628
                                vt_insline(curwin->esc_param[0]);
 
629
                                break;
 
630
                case '@':       /* Insert characters */
 
631
                                if ( ! curwin->esc_param[0] )
 
632
                                        curwin->esc_param[0] = 1;
 
633
                                vt_insertchar(curwin->esc_param[0]);
 
634
                                rshift_video(curwin, curwin->esc_param[0]);     
 
635
                                break;
 
636
                case 'i':       /* Printing (UNSUPPORTED) */
 
637
                                break;
 
638
                case 'n':       /* Device status request */
 
639
                        switch (curwin->esc_param[0]) {
 
640
                                case 5: /* Status report request */
 
641
                                        /* Say we're just fine. */
 
642
                                        write(*source, "\033[0n", 4);
 
643
                                        break;
 
644
                                case 6: /* Cursor position request */
 
645
                                        sprintf(reply, "\033[%d;%dR", 
 
646
                                                        curwin->cursor.x,
 
647
                                                        curwin->cursor.y);
 
648
                                        write(*source, reply, strlen(reply));
 
649
                                        break;
 
650
                        }
 
651
                        break;
 
652
                case 'c':       /* Request terminal identification string */
 
653
                                /* Respond with "I am a vt102" */
 
654
                                write(*source, "\033[?6c", 5);
 
655
                                break;
 
656
                default:        /* Unrecognized escape: ignore */
 
657
                                break;
 
658
        }
 
659
        reset_esc();
 
660
}
 
661
void E_brac_Q(c, source)
 
662
int c;
 
663
int *source;
 
664
{
 
665
        /* Check for numeric argument first */
 
666
        if ( isdigit(c) ) {
 
667
                *curwin->cur_param *= 10;
 
668
                *curwin->cur_param += (c-'0');
 
669
                return;
 
670
        }
 
671
 
 
672
        /* Return inside the switch to prevent reset_esc() */
 
673
        switch (c) {
 
674
                case '\030':    /* Processed as escape cancel */
 
675
                case '\032':    reset_esc();
 
676
                                return;
 
677
                case 'h':       /* Set modes */
 
678
                        switch (curwin->esc_param[0]) {
 
679
                                case 1: /* Cursorkeys in application mode */
 
680
                                        curwin->key_state=application;
 
681
                                        vt_keystate(curwin->key_state);
 
682
                                        break;
 
683
                                case 2: /* Set ansi mode */
 
684
                                        /* UNSUPPORTED */
 
685
                                        break;
 
686
                                case 3: /* 132 char/row */
 
687
                                        if ( physical.cols != 132 ) {
 
688
                                                upper.cols=132;
 
689
                                                lower.cols=132;
 
690
                                                physical.cols=132;
 
691
                                                vt_widemode(1);
 
692
                                        }
 
693
                                        break;
 
694
                                case 4: /* Set jump scroll */   
 
695
                                        /* UNSUPPORTED */
 
696
                                        break;
 
697
                                case 5: /* Set reverse screen */
 
698
                                        /* UNSUPPORTED */
 
699
                                        break;
 
700
                                case 6: /* Set relative coordinates */
 
701
                                        /* UNSUPPORTED */
 
702
                                        break;
 
703
                                case 7: /* Set auto wrap on */
 
704
                                        /* UNSUPPORTED */
 
705
                                        break;
 
706
                                case 8: /* Set auto repeat on */
 
707
                                        /* UNSUPPORTED */
 
708
                                        break;
 
709
                                case 25: /* Set cursor on */
 
710
                                        /* UNSUPPORTED */
 
711
                                        break;
 
712
                                case 47: /* Switch to alternate buffer */
 
713
                                        /* UNSUPPORTED (xterm sequence) */
 
714
                                        break;
 
715
                                default:
 
716
                                        /* UNSUPPORTED */
 
717
                                        break;
 
718
                        }
 
719
                        break;
 
720
                case 'l':       /* Reset modes */
 
721
                        switch (curwin->esc_param[0]) {
 
722
                                case 1: /* Cursorkeys in normal mode */
 
723
                                        curwin->key_state=normal;
 
724
                                        vt_keystate(curwin->key_state);
 
725
                                        break;
 
726
                                case 2: /* Set VT52 mode */
 
727
                                        /* UNSUPPORTED */
 
728
                                        break;
 
729
                                case 3: /* 80 char/row */
 
730
                                        if ( physical.cols == 132 ) {
 
731
                                                vt_rows_cols(terminal_type, 
 
732
                                                        NULL, &physical.cols);
 
733
                                                upper.cols=physical.cols;
 
734
                                                lower.cols=physical.cols;
 
735
                                                vt_widemode(0);
 
736
                                        }
 
737
                                        break;
 
738
                                case 4: /* Set smooth scroll */ 
 
739
                                        /* UNSUPPORTED */
 
740
                                        break;
 
741
                                case 5: /* Set non-reversed (normal) screen */
 
742
                                        /* UNSUPPORTED */
 
743
                                        break;
 
744
                                case 6: /* Set absolute coordinates */
 
745
                                        /* UNSUPPORTED */
 
746
                                        break;
 
747
                                case 7: /* Set auto wrap off */
 
748
                                        /* UNSUPPORTED */
 
749
                                        break;
 
750
                                case 8: /* Set auto repeat off */
 
751
                                        /* UNSUPPORTED */
 
752
                                        break;
 
753
                                case 25: /* Set cursor off */
 
754
                                        /* UNSUPPORTED */
 
755
                                        break;
 
756
                                case 47: /* Switch from alternate buffer */
 
757
                                        /* UNSUPPORTED (xterm sequence) */
 
758
                                        break;
 
759
                                default:
 
760
                                        /* UNSUPPORTED */
 
761
                                        break;
 
762
                        }
 
763
                        break;
 
764
                default:        /* Unrecognized escape: ignore */
 
765
                        break;
 
766
        }
 
767
        reset_esc();
 
768
}
 
769
void E_lparen(c, source)
 
770
int c;
 
771
int *source;
 
772
{
 
773
        /* Return inside the switch to prevent reset_esc() */
 
774
        switch (c) {
 
775
                case '\030':    /* Processed as escape cancel */
 
776
                case '\032':    reset_esc();
 
777
                                return;
 
778
                /* Select character sets */
 
779
                case 'A':       /* UK as G0 */
 
780
                                curwin->charset[G0]=UK_CHARSET;
 
781
                                vt_altcharset(G0, UK_CHARSET);
 
782
                                break;
 
783
                case 'B':       /* US as G0 */
 
784
                                curwin->charset[G0]=US_CHARSET;
 
785
                                vt_altcharset(G0, US_CHARSET);
 
786
                                break;
 
787
                case '0':       /* Special character set as G0 */
 
788
                                curwin->charset[G0]=GRAPHICS;
 
789
                                vt_altcharset(G0, GRAPHICS);
 
790
                                break;
 
791
                case '1':       /* Alternate ROM as G0 */
 
792
                case '2':       /* Alternate ROM special character set as G0 */
 
793
                default:        /* Unrecognized escape: ignore */
 
794
                                break;
 
795
        }
 
796
        reset_esc();
 
797
}
 
798
void E_rparen(c, source)
 
799
int c;
 
800
int *source;
 
801
{
 
802
        /* Return inside the switch to prevent reset_esc() */
 
803
        switch (c) {
 
804
                case '\030':    /* Processed as escape cancel */
 
805
                case '\032':    reset_esc();
 
806
                                return;
 
807
                /* Select character sets */
 
808
                case 'A':       /* UK as G1 */
 
809
                                curwin->charset[G1]=UK_CHARSET;
 
810
                                vt_altcharset(G1, UK_CHARSET);
 
811
                                break;
 
812
                case 'B':       /* US as G1 */
 
813
                                curwin->charset[G1]=US_CHARSET;
 
814
                                vt_altcharset(G1, US_CHARSET);
 
815
                                break;
 
816
                case '0':       /* Special character set as G1 */
 
817
                                curwin->charset[G1]=GRAPHICS;
 
818
                                vt_altcharset(G1, GRAPHICS);
 
819
                case '1':       /* Alternate ROM as G1 */
 
820
                case '2':       /* Alternate ROM special character set as G1 */
 
821
                default:        /* Unrecognized escape: ignore */
 
822
                                break;
 
823
        }
 
824
        reset_esc();
 
825
}
 
826
void E_pound(c, source)
 
827
int c;
 
828
int *source;
 
829
{
 
830
        switch (c) {   /* Line attributes not supported */
 
831
                case '3':       /* Double height (top half) */
 
832
                case '4':       /* Double height (bottom half) */
 
833
                case '5':       /* Single width, single height */
 
834
                case '6':       /* Double width */
 
835
                default:
 
836
                        reset_esc();
 
837
                        break;
 
838
        }
 
839
        return;
 
840
}
 
841
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 
842
 
 
843
/* Routine to initialize the vt100 screening, returning an error message,
 
844
   or NULL if all went well. */
 
845
 
 
846
static int setup_vt100 = 0;     /* Have we initialized the vt100 system? */
 
847
 
 
848
char *init_vt100()
 
849
{
 
850
#ifdef TIOCGWINSZ
 
851
        struct /* winsize */ {
 
852
                unsigned short  ws_row;         /* rows, in characters */
 
853
                unsigned short  ws_col;         /* columns, in characters */
 
854
                unsigned short  ws_xpixel;      /* horizontal size - not used */
 
855
                unsigned short  ws_ypixel;      /* vertical size - not used */
 
856
        } mywinz;
 
857
#endif
 
858
        int i, **videomem, oldrows, newrows, newcols;
 
859
        position newpos;
 
860
        char *ptr, *errmesg;
 
861
 
 
862
        /* Check to make sure it's okay to run */
 
863
        if ( ! isatty(0) || ! isatty(1) )
 
864
                return("Standard input and output must be a tty");
 
865
 
 
866
        /* Initialize the termcap environment */
 
867
        if ( ! setup_vt100 ) {
 
868
                if ( (errmesg=vt_initterm(terminal_type,
 
869
                                &physical.rows, &physical.cols)) != NULL )
 
870
                        return(errmesg);
 
871
                vt_initsel();
 
872
        }
 
873
 
 
874
#ifdef TIOCGWINSZ
 
875
        if ( ioctl(0, TIOCGWINSZ, &mywinz) == 0 ) {
 
876
                if ( mywinz.ws_row )
 
877
                        physical.rows=mywinz.ws_row;
 
878
                if ( mywinz.ws_col )
 
879
                        physical.cols=mywinz.ws_col;
 
880
        }
 
881
#endif
 
882
        if ( (ptr=(char *)getenv("LINES")) != NULL )
 
883
                physical.rows=atoi(ptr);
 
884
        if ( (ptr=(char *)getenv("COLUMNS")) != NULL )
 
885
                physical.cols=atoi(ptr);
 
886
 
 
887
        /* Now set defaults if we can't find the window size */
 
888
        if ( ! physical.rows )  physical.rows=24;
 
889
        if ( ! physical.cols )  physical.cols=80;
 
890
        physical.subwins[UPPER] = &upper;
 
891
        physical.subwins[LOWER] = &lower;
 
892
 
 
893
        /* Check that each window is at least 3 lines tall */
 
894
        if ( physical.rows < 7 )
 
895
                return("Screen is not tall enough to split.");
 
896
 
 
897
        /* If physical.cols has been set to 132, assume we are on a
 
898
           vt100 wide terminal, and set 132 column mode.  Note that
 
899
           setting COLUMNS in the environment will override termcap */
 
900
        if ( physical.cols == 132 )
 
901
                vt_widemode(1);
 
902
 
 
903
        /* Set the exportable variables */
 
904
        if ( UU_lines ) {
 
905
                /* Check the user set # of lines */
 
906
                if ( UU_lines > (physical.rows-1-3) )
 
907
                        LU_lines=(physical.rows-1-3);
 
908
                else if ( UU_lines < 3 )
 
909
                        LU_lines=3;
 
910
                else
 
911
                        LU_lines=UU_lines;
 
912
 
 
913
                WU_lines=LU_lines;
 
914
                WL_lines=(physical.rows-1-LU_lines);
 
915
        } else
 
916
                WL_lines=WU_lines=((physical.rows-1)/2);
 
917
        W_columns=physical.cols;
 
918
 
 
919
        /* Set up the window structures */
 
920
        newcols=physical.cols;
 
921
        newrows=WU_lines;
 
922
        if ( (videomem=alloc_video(newrows, newcols)) == NULL )
 
923
                return("Out of memory");
 
924
        if ( setup_vt100 ) {
 
925
                oldrows=upper.rows;
 
926
                copy_video(&upper, videomem, newrows, newcols, &newpos);
 
927
                for ( i=0; i<upper.rows; ++i )
 
928
                        (void) free(upper.videomem[i]);
 
929
                (void) free(upper.videomem);
 
930
                (void) free(upper.tabstops);
 
931
        }
 
932
        if ( (upper.tabstops=(int *)malloc(newcols*sizeof(int))) == NULL )
 
933
                return("Out of memory");
 
934
        for ( i=0; i<newcols; ++i ) {
 
935
                if ( (i%TABSTOP) == 0 )
 
936
                        upper.tabstops[i]=1;
 
937
                else
 
938
                        upper.tabstops[i]=0;
 
939
        }
 
940
        upper.videomem=videomem;
 
941
        upper.cols=physical.cols;
 
942
        upper.rows=newrows;
 
943
        upper.row_offset=0;
 
944
        if ( setup_vt100 ) {
 
945
                if ( upper.scr_lower == oldrows )
 
946
                        upper.scr_lower=newrows;
 
947
                upper.cursor=newpos;
 
948
                vt_checkwin(&upper);
 
949
        } else 
 
950
                vt_resetwin(&upper);
 
951
        newrows=WL_lines;
 
952
        if ( (videomem=alloc_video(newrows, newcols)) == NULL )
 
953
                return("Out of memory");
 
954
        if ( setup_vt100 ) {
 
955
                oldrows=lower.rows;
 
956
                copy_video(&lower, videomem, newrows, newcols, &newpos);
 
957
                for ( i=0; i<lower.rows; ++i )
 
958
                        (void) free(lower.videomem[i]);
 
959
                (void) free(lower.videomem);
 
960
                (void) free(lower.tabstops);
 
961
        }
 
962
        if ( (lower.tabstops=(int *)malloc(newcols*sizeof(int))) == NULL )
 
963
                return("Out of memory");
 
964
        for ( i=0; i<newcols; ++i ) {
 
965
                if ( (i%TABSTOP) == 0 )
 
966
                        lower.tabstops[i]=1;
 
967
                else
 
968
                        lower.tabstops[i]=0;
 
969
        }
 
970
        lower.videomem=videomem;
 
971
        lower.cols=physical.cols;
 
972
        lower.rows=newrows;
 
973
        lower.row_offset=(upper.rows+1);
 
974
        if ( setup_vt100 ) {
 
975
                if ( lower.scr_lower == oldrows )
 
976
                        lower.scr_lower=newrows;
 
977
                lower.cursor=newpos;
 
978
                vt_checkwin(&lower);
 
979
        } else 
 
980
                vt_resetwin(&lower);
 
981
 
 
982
        /* Set up the separator (cols-1) */
 
983
        if ( setup_vt100 )
 
984
                (void) free(sep);
 
985
        if ( (sep=(char *)malloc(physical.cols+1)) == NULL )
 
986
                return("Out of memory");
 
987
        for ( i=0; i<(physical.cols-1); ++i )
 
988
                sep[i]=SEP_CHAR;
 
989
        sep[i]='\0';
 
990
 
 
991
        /* Clear the screen, and set up the windows */
 
992
        if ( ! setup_vt100 ) {
 
993
                curwin=(&upper);
 
994
                vt_clrscr(); 
 
995
                vt_goto((WU_lines+1), 1);               /* Move past the top win */
 
996
                vt_reverse(1);
 
997
                printf("%s", sep);                      /* Print separator */
 
998
                vt_resetattr();
 
999
                vt_update();
 
1000
                lastwin=(-1);
 
1001
        } else
 
1002
                vt_redraw();
 
1003
 
 
1004
        ++setup_vt100;                          /* Set setup_vt100 flag */
 
1005
        return(NULL);
 
1006
}
 
1007
 
 
1008
int vt_write(win, data, len, source)
 
1009
int win;                /* The window; 0 if top, 1 if bottom */
 
1010
char *data;             /* The data to write */
 
1011
int len;                /* The amount of data to write */
 
1012
int *source;            /* File descriptor through which to reply to Esc-Z */
 
1013
{
 
1014
        int i;
 
1015
 
 
1016
        /* First set the proper window */
 
1017
        set_win(win);
 
1018
 
 
1019
        /* Now cycle through the input */
 
1020
        for ( i=0; i<len; ++i )
 
1021
                (*curwin->process_char)((int)*(data++), source);
 
1022
        vt_update();
 
1023
        return len;
 
1024
}
 
1025
 
 
1026
/* Print out a prompt on the screen, get a character in response, and 
 
1027
   return it.  (Assume a one line prompt)
 
1028
*/
 
1029
 
 
1030
char vt_prompt(prompt)
 
1031
char *prompt;
 
1032
{
 
1033
        char format[BUFSIZ], buff[1];
 
1034
 
 
1035
        /* Save cursor position, go home, clear line and print prompt */
 
1036
        if ( prompt ) {
 
1037
                vt_savecursor();
 
1038
                vt_resetattr();
 
1039
                vt_goto(WU_lines+1, 0);
 
1040
                vt_clreol();
 
1041
                sprintf(format, "%%.%ds", physical.cols);
 
1042
                vt_bold(1);
 
1043
                printf(format, prompt);
 
1044
                vt_update();
 
1045
        }
 
1046
        
 
1047
        /* Read the response */
 
1048
        if ( read(0, buff, 1) <= 0 )
 
1049
                buff[0]='\0';
 
1050
 
 
1051
        /* Print out the top separator and go back to where we were */
 
1052
        if ( prompt ) {
 
1053
                vt_resetattr();
 
1054
                vt_reverse(1);
 
1055
                printf("\r%s", sep);
 
1056
                vt_restcursor();
 
1057
                set_attr(curwin);
 
1058
                vt_update();
 
1059
        }
 
1060
 
 
1061
        return(buff[0]);
 
1062
}
 
1063
 
 
1064
/* Print out information at the bottom of the screen */
 
1065
 
 
1066
void vt_info(info)
 
1067
char *info;
 
1068
{
 
1069
        char format[80];
 
1070
 
 
1071
        /* Save cursor, go to info bar, clear it */
 
1072
        vt_savecursor();
 
1073
        vt_resetattr();
 
1074
        vt_goto(WU_lines+1, 0);
 
1075
        vt_clreol();
 
1076
 
 
1077
        if ( info ) {
 
1078
                sprintf(format, "%%.%ds", physical.cols);
 
1079
                vt_bold(1);
 
1080
                printf(format, info);
 
1081
        } 
 
1082
        else { /* Get rid of the info message */
 
1083
                vt_reverse(1);
 
1084
                printf("\r%s", sep);
 
1085
        }
 
1086
 
 
1087
        /* Then go back where we were supposed to be and update it */
 
1088
        vt_restcursor();
 
1089
        set_attr(curwin);
 
1090
        vt_update();
 
1091
}
 
1092
 
 
1093
/* Repaint both of the screens */
 
1094
void vt_redraw()
 
1095
{
 
1096
        /* We need to paint current window last so scrolling works */
 
1097
        vt_clrscr();
 
1098
        paint_video(lastwin == UPPER ? &lower : &upper);
 
1099
        vt_goto(WU_lines+1, 0);
 
1100
        vt_reverse(1);
 
1101
        printf("%s", sep);
 
1102
        paint_video(lastwin == UPPER ? &upper : &lower);
 
1103
        vt_update();
 
1104
}
 
1105
 
 
1106
/* Show a (help) screen, wait, then refresh the screen */
 
1107
void vt_showscreen(title, text)
 
1108
char *title;
 
1109
char *text[];
 
1110
{
 
1111
        int i;
 
1112
 
 
1113
        vt_clrscr();
 
1114
        vt_setscroll(0,0);
 
1115
        vt_goto(1,1);
 
1116
        vt_bold(1);
 
1117
        printf("%s\r\n\r\n", title);
 
1118
        vt_resetattr();
 
1119
        for ( i=0; text[i]; ++i )
 
1120
                printf("%s\r\n", text[i]);
 
1121
        printf("\n");
 
1122
        vt_reverse(1);
 
1123
        printf("Press any key to continue: ");
 
1124
        vt_resetattr();
 
1125
        vt_update();
 
1126
        getchar();
 
1127
        vt_redraw();
 
1128
}
 
1129
 
 
1130
/* Clean up the screen and clear the scrolling regions */
 
1131
void end_vt100()
 
1132
{
 
1133
        int i;
 
1134
 
 
1135
        if ( ! setup_vt100 )
 
1136
                return;
 
1137
 
 
1138
        /* Clear any old setup */
 
1139
        lastwin=(-1);
 
1140
        for ( i=0; i<upper.rows; ++i )
 
1141
                (void) free(upper.videomem[i]);
 
1142
        (void) free(upper.videomem);
 
1143
        (void) free(upper.tabstops);
 
1144
        for ( i=0; i<lower.rows; ++i )
 
1145
                (void) free(lower.videomem[i]);
 
1146
        (void) free(lower.videomem);
 
1147
        (void) free(lower.tabstops);
 
1148
        setup_vt100=0;
 
1149
 
 
1150
        /* Fix up the display */
 
1151
        vt_setscroll(0,0);
 
1152
        vt_goto(physical.rows, 1);
 
1153
        vt_clreol();
 
1154
        vt_resetattr();
 
1155
        vt_update();
 
1156
}
 
1157