Commit | Line | Data |
---|---|---|
af5295ff KM |
1 | /* |
2 | * Copyright (c) 1992 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. | |
7 | * | |
8 | * %sccs.include.redist.c% | |
9 | * | |
10 | * from: $Hdr: vt100.c,v 4.300 91/06/09 06:14:56 root Rel41 $ SONY | |
11 | * | |
6d429c8e | 12 | * @(#)vt100.c 7.2 (Berkeley) %G% |
af5295ff KM |
13 | */ |
14 | ||
15 | #include "../include/fix_machine_type.h" | |
16 | ||
17 | #include "types.h" | |
18 | #include "param.h" | |
6d429c8e | 19 | #include "systm.h" |
af5295ff KM |
20 | #include "../iop/framebuf.h" |
21 | #include "../iop/kbreg.h" | |
22 | #include "../iop/keyboard.h" | |
23 | #include "../fb/fbdefs.h" | |
24 | #include "../bm/vt100.h" | |
25 | #include "../bm/bitmapif.h" | |
26 | ||
27 | #ifdef IPC_MRX | |
28 | #include "config.h" | |
29 | #define kbd_ioctl(chan, cmd, argp) { \ | |
30 | if (kb_ioctl) \ | |
31 | (*kb_ioctl)(chan, cmd, argp); \ | |
32 | } | |
33 | #endif | |
34 | ||
35 | #ifdef IPC_MRX | |
36 | #include "mrx.h" | |
37 | #include "process.h" | |
38 | #include "object.h" | |
39 | #include "console.h" | |
40 | #endif | |
41 | ||
42 | #ifdef CPU_SINGLE | |
43 | #include "../sio/scc.h" | |
44 | #endif | |
45 | ||
46 | extern Key_string key_str; | |
47 | extern int tmode; | |
48 | static unsigned int first_code; | |
49 | ||
50 | #ifdef IPC_MRX | |
51 | #define SCC_KEYBOARD 0 | |
52 | #endif | |
53 | ||
54 | SCREEN screen; | |
55 | struct cursor inner_buf_csr; | |
56 | int inner_buf_tstat; | |
57 | char c_pos_mess[C_MESS_SIZ]; | |
58 | extern struct csr_buf local_csr_buf; | |
59 | ||
60 | #ifdef IPC_MRX | |
61 | int bitmap_use; | |
62 | #ifdef IPC_3CPU | |
63 | #include "../../ubdev/msgio.h" | |
64 | extern int ipc_ready; | |
65 | #endif /* IPC_3CPU */ | |
66 | extern struct cons_devsw vt100_cons; | |
67 | #endif /* IPC_MRX */ | |
68 | ||
69 | #ifdef CPU_DOUBLE | |
70 | int auto_dimmer(); | |
71 | #endif | |
72 | ||
73 | #if CPU_SINGLE | |
74 | extern int hz; | |
75 | extern kbd_profun_init(); | |
76 | #endif | |
77 | ||
78 | lRectangle char_r1; | |
79 | lRectangle font_r1; | |
80 | lRectangle char_r2; | |
81 | lRectangle font_r2; | |
82 | ||
83 | int font_len1; | |
84 | int font_len2; | |
85 | ||
86 | int fcolor; | |
87 | int bcolor; | |
88 | ||
89 | int font_w; | |
90 | int font_h; | |
91 | int char_w; | |
92 | int char_h; | |
93 | int scr_w; | |
94 | int scr_h; | |
95 | int ch_pos; | |
96 | int ul_pos; | |
97 | int x_ofst; | |
98 | int y_ofst; | |
99 | int rit_m; | |
100 | int btm_m; | |
101 | int bell_len; | |
102 | int dim_cnt; | |
103 | int a_dim_on; | |
104 | ||
105 | unsigned short fbuf[256]; | |
106 | int fp; | |
107 | int fpn; | |
108 | lPoint fpp; | |
109 | int fpa; | |
110 | ||
111 | vt100init() | |
112 | { | |
113 | register int i; | |
114 | register SCREEN *sp = &screen; | |
115 | ||
116 | sp->s_term_mode = 0; | |
117 | sp->s_term_mode |= (SRM|DECSCLM|DECAWM|DECARM|DECCSR_ACTV); | |
118 | sp->s_current_stat = 0; | |
119 | sp->s_csr.csr_x = 1; | |
120 | sp->s_csr.csr_y = 1; | |
121 | sp->s_csr.csr_p.x = x_ofst; | |
122 | sp->s_csr.csr_p.y = y_ofst; | |
123 | sp->s_csr.csr_attributes = NORMALM; | |
124 | sp->s_region.top_margin = TOP_M; | |
125 | sp->s_region.btm_margin = btm_m; | |
126 | sp->s_plane = consfb->planemask; | |
127 | sp->s_bgcol = 0; | |
128 | fcolor = sp->s_plane; | |
129 | bcolor = sp->s_bgcol; | |
130 | for (i = 0; i < RIT_M_MAX; i++) | |
131 | sp->s_tab_pos[i] = 0; | |
132 | for (i = 9; i < RIT_M_MAX; i +=8) | |
133 | sp->s_tab_pos[i] = 1; | |
134 | ||
135 | esc_store_csr(sp); | |
136 | inner_buf_tstat = sp->s_term_mode & (DECOM|DECAWM); | |
137 | local_csr_buf.csr_number = 1; | |
138 | ||
139 | cursor_on(&sp->s_csr.csr_p); | |
140 | } | |
141 | ||
142 | ncp_str(p, q, n) | |
143 | register char *p, *q; | |
144 | register int n; | |
145 | { | |
146 | while (n-- > 0) | |
147 | *q++ = *p++; | |
148 | } | |
149 | ||
150 | /* | |
151 | * default parameter set | |
152 | */ | |
153 | set_default_param() | |
154 | { | |
155 | register struct fbdev *cfb = consfb; | |
156 | ||
157 | font_w = cfb->font_w; | |
158 | font_h = cfb->font_h; | |
159 | char_w = cfb->char_w; | |
160 | char_h = cfb->char_h; | |
161 | scr_w = cfb->scr_w; | |
162 | scr_h = cfb->scr_h; | |
163 | ch_pos = cfb->ch_pos; | |
164 | ul_pos = cfb->ul_pos; | |
165 | x_ofst = cfb->x_offset; | |
166 | y_ofst = cfb->y_offset; | |
167 | rit_m = cfb->rit_m; | |
168 | btm_m = cfb->btm_m; | |
169 | a_dim_on = 1; | |
170 | ||
171 | font_r1.extent.x = font_w; | |
172 | font_r1.extent.y = font_h; | |
173 | font_r2.extent.x = font_w * 2; | |
174 | font_r2.extent.y = font_h; | |
175 | font_len1 = (font_w + 0x0f) >> 4; | |
176 | font_len2 = (font_w*2 + 0x0f) >> 4; | |
177 | char_r1.extent.x = char_w; | |
178 | char_r1.extent.y = char_h; | |
179 | char_r2.extent.x = char_w * 2; | |
180 | char_r2.extent.y = char_h; | |
181 | ||
182 | dim_cnt = DIM_CNT_DFLT; | |
183 | bell_len = BELL_LEN_DFLT; | |
184 | } | |
185 | ||
186 | vt100_open() | |
187 | { | |
188 | static int only_one = 0; | |
189 | extern char **ext_fnt_addr; | |
190 | ||
191 | set_default_param(); | |
192 | vt100init(); | |
193 | bitmapinit(); | |
194 | if (only_one == 0) { | |
195 | #ifdef IPC_MRX | |
196 | #ifdef IPC_3CPU | |
197 | while (ipc_ready == 0) | |
198 | proc_sleep_self(100); | |
199 | #endif | |
200 | while ((bitmap_use = object_query(BITMAP)) <= 0) | |
201 | proc_sleep_self(100); | |
202 | ||
203 | proc_create("auto_dimmer", auto_dimmer, 401, 512, 0); | |
204 | #endif /* IPC_MRX */ | |
205 | only_one = 1; | |
206 | } | |
207 | #define INIT_STRING "\033[42;1H" | |
208 | vt100_write(0, INIT_STRING, sizeof(INIT_STRING) - 1); | |
209 | #ifdef CPU_SINGLE | |
210 | kbd_open(SCC_KEYBOARD); | |
211 | #endif | |
212 | } | |
213 | ||
214 | #ifdef IPC_MRX | |
215 | vt100_cons_setup() | |
216 | { | |
217 | int vt100_open(), vt100_read(), vt100_write(), vt100_ioctl(); | |
218 | ||
219 | vt100_cons.open = vt100_open; | |
220 | vt100_cons.read = vt100_read; | |
221 | vt100_cons.write = vt100_write; | |
222 | vt100_cons.ioctl = vt100_ioctl; | |
223 | } | |
224 | ||
225 | #define DIMMER_RESET 0 | |
226 | #define DIMMER_ON 1 | |
227 | #define DIMMER_OFF 2 | |
228 | #define DIMMER_INTERVAL 60 /* sec */ | |
229 | ||
230 | static int dimmer_stdport; | |
231 | ||
232 | auto_dimmer() | |
233 | { | |
234 | register int select, i; | |
235 | register int dimm_counter = DIM_CNT_DFLT; | |
236 | register int dimm_level = 0; | |
237 | int ports[2], *mode; | |
238 | ||
239 | spl0(); | |
240 | ports[0] = dimmer_stdport = STDPORT; | |
241 | ports[1] = port_create("auto_dimmer_sub"); | |
242 | register_interval(ports[1], DIMMER_INTERVAL); | |
243 | for(;;) { | |
244 | select = msg_select(2, ports); | |
245 | if (select == 0) { | |
246 | msg_recv(ports[0], NULL, &mode, NULL, 0); | |
247 | switch (*mode) { | |
248 | case DIMMER_RESET: | |
249 | if (!a_dim_on) | |
250 | break; | |
251 | dimm_counter = dim_cnt; | |
252 | if (dimm_level > 0) { | |
253 | dimm_level =0; | |
254 | for (i = 0; i < nfbdev; i++) | |
255 | fbbm_set_dimmer(&fbdev[i], 0); | |
256 | } | |
257 | break; | |
258 | case DIMMER_ON: | |
259 | dimm_counter = dim_cnt; | |
260 | dimm_level =0; | |
261 | for (i = 0; i < nfbdev; i++) | |
262 | fbbm_set_dimmer(&fbdev[i], dimm_level); | |
263 | a_dim_on = 1; | |
264 | break; | |
265 | case DIMMER_OFF: | |
266 | dimm_counter = dim_cnt; | |
267 | dimm_level =0; | |
268 | for (i = 0; i < nfbdev; i++) | |
269 | fbbm_set_dimmer(&fbdev[i], dimm_level); | |
270 | a_dim_on = 0; | |
271 | break; | |
272 | } | |
273 | } else { | |
274 | msg_recv(ports[1], NULL, NULL, NULL, 0); | |
275 | if (a_dim_on && (dimm_counter-- <= 0)) { | |
276 | if (dimm_level < 3) { | |
277 | dimm_level++; | |
278 | } | |
279 | for (i = 0; i < nfbdev; i++) | |
280 | fbbm_set_dimmer(&fbdev[i], dimm_level); | |
281 | dimm_counter = dim_cnt; | |
282 | } | |
283 | } | |
284 | } | |
285 | } | |
286 | ||
287 | rst_dimmer_cnt() | |
288 | { | |
289 | register int diff; | |
290 | static unsigned last_time; | |
291 | extern unsigned sys_time; | |
292 | int mode = DIMMER_RESET; | |
293 | ||
294 | diff = sys_time - last_time; | |
295 | if (diff > DIMMER_INTERVAL*HZ || diff < 0) { | |
296 | dimmer(DIMMER_RESET); | |
297 | last_time = sys_time; | |
298 | } | |
299 | } | |
300 | ||
301 | auto_dimmer_on() | |
302 | { | |
303 | dimmer(DIMMER_ON); | |
304 | } | |
305 | ||
306 | auto_dimmer_off() | |
307 | { | |
308 | dimmer(DIMMER_OFF); | |
309 | } | |
310 | ||
311 | dimmer(mode) | |
312 | int mode; | |
313 | { | |
314 | if (dimmer_stdport) | |
315 | msg_send(dimmer_stdport, 0, &mode, sizeof(mode), 0); | |
316 | } | |
317 | #else /* IPC_MRX */ | |
318 | ||
319 | static int dimmer_counter = DIM_CNT_DFLT; | |
320 | static int dim_level = 0; | |
321 | ||
322 | #ifdef CPU_SINGLE | |
323 | auto_dimmer() | |
324 | { | |
325 | register int s, i; | |
326 | ||
327 | s = spl4(); | |
328 | if (a_dim_on && (dimmer_counter-- <= 0)) { | |
329 | if (dim_level < 3) | |
330 | dim_level++; | |
331 | for (i = 0; i < nfbdev; i++) | |
332 | fbbm_set_dimmer(&fbdev[i], dim_level); | |
333 | dimmer_counter = dim_cnt; | |
334 | } | |
335 | splx(s); | |
336 | timeout(auto_dimmer, (caddr_t) 0, 60 * hz); | |
337 | } | |
338 | #endif | |
339 | ||
340 | rst_dimmer_cnt() | |
341 | { | |
342 | register int s, i; | |
343 | ||
344 | if (!a_dim_on) | |
345 | return; | |
346 | #ifdef CPU_SINGLE | |
347 | s = spl4(); | |
348 | #endif | |
349 | dimmer_counter = dim_cnt; | |
350 | ||
351 | if (dim_level > 0) { | |
352 | dim_level =0; | |
353 | for (i = 0; i < nfbdev; i++) | |
354 | fbbm_set_dimmer(&fbdev[i], 0); | |
355 | } | |
356 | splx(s); | |
357 | } | |
358 | ||
359 | auto_dimmer_on() | |
360 | { | |
361 | register int s, i; | |
362 | ||
363 | #ifdef CPU_SINGLE | |
364 | s = spl4(); | |
365 | #endif | |
366 | dimmer_counter = dim_cnt; | |
367 | dim_level =0; | |
368 | for (i = 0; i < nfbdev; i++) | |
369 | fbbm_set_dimmer(&fbdev[i], dim_level); | |
370 | a_dim_on = 1; | |
371 | splx(s); | |
372 | } | |
373 | ||
374 | auto_dimmer_off() | |
375 | { | |
376 | register int s, i; | |
377 | ||
378 | #ifdef CPU_SINGLE | |
379 | s = spl4(); | |
380 | #endif | |
381 | dimmer_counter = dim_cnt; | |
382 | dim_level =0; | |
383 | for (i = 0; i < nfbdev; i++) | |
384 | fbbm_set_dimmer(&fbdev[i], dim_level); | |
385 | a_dim_on = 0; | |
386 | splx(s); | |
387 | } | |
388 | #endif /* IPC_MRX */ | |
389 | /* | |
390 | * The routine `_putc(sp, c)' only prints a character c with the cursor | |
391 | * attributes by using `copy_char(x, y, c, attributes)'. | |
392 | * And when IRM (terminal insertion-replacement mode) is set, the characters | |
393 | * righthand side of the cursor are shifted right and lost when they passed | |
394 | * beyond the right margin. | |
395 | * The position is specified by the sp pointer of the structure SCREEN. | |
396 | * | |
397 | */ | |
398 | static | |
399 | _putc(sp, c, kanji) | |
400 | register SCREEN *sp; | |
401 | unsigned int c; | |
402 | { | |
403 | if (sp->s_term_mode & IRM) { | |
404 | vt_flush(&(sp->s_csr)); | |
405 | move_chars(sp->s_csr.csr_x, sp->s_csr.csr_y, | |
406 | rit_m - sp->s_csr.csr_x - ((kanji)? 1: 0), | |
407 | sp->s_csr.csr_x + ((kanji) ? 2: 1)); | |
408 | copy_char(sp, c, kanji); | |
409 | } | |
410 | if (fp) { | |
411 | fbuf[fp++] = c; | |
412 | fpn += kanji + 1; | |
413 | } else { | |
414 | fbuf[fp++] = c; | |
415 | fpp = sp->s_csr.csr_p; | |
416 | fpa = sp->s_csr.csr_attributes; | |
417 | fpn = kanji + 1; | |
418 | } | |
419 | } | |
420 | ||
421 | /* | |
422 | * Scroll up and down in the scroll region. | |
423 | * New oriented line must be cleared with terminal mode, that is whether | |
424 | * the screen is reverse mode or not. | |
425 | */ | |
426 | scroll_up(top, bottom, revsw, fcol, bcol) | |
427 | int top; | |
428 | int bottom; | |
429 | int revsw; | |
430 | int fcol; | |
431 | int bcol; | |
432 | { | |
433 | move_lines(top + 1, bottom - top, top); | |
434 | clear_lines(bottom, 1, revsw, fcol, bcol); | |
435 | } | |
436 | ||
437 | scroll_down(top, bottom, revsw, fcol, bcol) | |
438 | int top; | |
439 | int bottom; | |
440 | int revsw; | |
441 | int fcol; | |
442 | int bcol; | |
443 | { | |
444 | move_lines(top, bottom - top, top + 1); | |
445 | clear_lines(top, 1, revsw, fcol, bcol); | |
446 | } | |
447 | ||
448 | /* | |
449 | * Back space | |
450 | * back_space(sp) moves cursor next to left at current cursor position. | |
451 | * The cursor can not move beyond left or right margin. | |
452 | */ | |
453 | back_space(sp) | |
454 | register SCREEN *sp; | |
455 | { | |
456 | register struct cursor *spc = &sp->s_csr; | |
457 | ||
458 | cursor_off(); | |
459 | if (spc->csr_x > LFT_M) { | |
460 | spc->csr_x -= 1; | |
461 | spc->csr_p.x -= char_w; | |
462 | } | |
463 | cursor_on(&spc->csr_p); | |
464 | } | |
465 | ||
466 | /* | |
467 | * Tab stop | |
468 | * next_tab_stop(sp) moves cursor to next tab stop. | |
469 | */ | |
470 | next_tab_stop(sp) | |
471 | register SCREEN *sp; | |
472 | { | |
473 | register int i; | |
474 | ||
475 | cursor_off(); | |
476 | for (i = sp->s_csr.csr_x + 1; i < rit_m; i++) | |
477 | if (sp->s_tab_pos[i] == 1) | |
478 | break; | |
6d429c8e | 479 | sp->s_csr.csr_x = min(i, rit_m); |
af5295ff KM |
480 | sp->s_csr.csr_p.x = (sp->s_csr.csr_x - 1) * char_w + x_ofst; |
481 | cursor_on(&sp->s_csr.csr_p); | |
482 | } | |
483 | ||
484 | /* | |
485 | * Carriage return | |
486 | * carriage_ret(sp) moves cursor at beginning of the current line. | |
487 | */ | |
488 | carriage_ret(sp) | |
489 | register SCREEN *sp; | |
490 | { | |
491 | cursor_off(); | |
492 | sp->s_csr.csr_x = LFT_M; | |
493 | sp->s_csr.csr_p.x = x_ofst; | |
494 | cursor_on(&sp->s_csr.csr_p); | |
495 | } | |
496 | ||
497 | /* | |
498 | * Bell | |
499 | */ | |
500 | static | |
501 | bell() | |
502 | { | |
503 | #ifdef news1800 | |
504 | static int port; | |
505 | ||
506 | if (port == 0) | |
507 | port = port_create("port_cons_bell"); | |
508 | kbd_ioctl(port, KIOCBELL, &bell_len); | |
509 | #else | |
510 | kbd_ioctl(SCC_KEYBOARD, KIOCBELL, &bell_len); | |
511 | #endif | |
512 | return (0); | |
513 | } | |
514 | ||
515 | int | |
516 | Putchar(c, eob) | |
517 | unsigned int c; | |
518 | { | |
519 | register SCREEN *sp = &screen; | |
520 | unsigned int sftjis_to_jis(); | |
521 | ||
522 | c &= 0xff; | |
523 | ||
524 | if (eob) { | |
525 | vt_flush(&(sp->s_csr)); | |
526 | return(0); | |
527 | } | |
528 | ||
529 | if (c == 0x1b) { /* c == esc */ | |
530 | vt_flush(&(sp->s_csr)); | |
531 | recover(sp); | |
532 | sp->s_current_stat |= ESCAPE; | |
533 | return; | |
534 | } else if (sp->s_current_stat & ESCAPE) { | |
535 | (*sp->s_esc_handler)(sp, c); | |
536 | return; | |
537 | } else if (sp->s_current_stat & SKANJI) { | |
538 | c = sftjis_to_jis(first_code, c); | |
539 | if (sp->s_current_stat & JKANJI) { | |
540 | addch(sp, c); | |
541 | } else { | |
542 | sp->s_current_stat |= JKANJI; | |
543 | addch(sp, c); | |
544 | sp->s_current_stat &= ~JKANJI; | |
545 | } | |
546 | sp->s_current_stat &= ~SKANJI; | |
547 | goto set_csr; | |
548 | } else if (sp->s_current_stat & EKANJI) { | |
549 | c = (c & 0x7f) | (first_code << 8); | |
550 | if (sp->s_current_stat & JKANJI) { | |
551 | addch(sp, c); | |
552 | } else { | |
553 | sp->s_current_stat |= JKANJI; | |
554 | addch(sp, c); | |
555 | sp->s_current_stat &= ~JKANJI; | |
556 | } | |
557 | sp->s_current_stat &= ~EKANJI; | |
558 | goto set_csr; | |
559 | } else if (sp->s_current_stat & JKANJI) { | |
560 | jiskanji(sp, c); | |
561 | goto set_csr; | |
562 | } else if (sp->s_current_stat & EKANA) { | |
563 | sp->s_current_stat &= ~EKANA; | |
564 | addch(sp, c); | |
565 | goto set_csr; | |
566 | } | |
567 | if (c < 0x20) { /* control code */ | |
568 | vt_flush(&(sp->s_csr)); | |
569 | switch (c) { | |
570 | case 0x00: /* ignore */ | |
571 | break; | |
572 | case 0x07: /* bell */ | |
573 | bell(); | |
574 | break; | |
575 | case 0x08: /* back space */ | |
576 | back_space(sp); | |
577 | break; | |
578 | case 0x09: /* tabulation */ | |
579 | next_tab_stop(sp); | |
580 | break; | |
581 | case 0x0a: /* line feed */ | |
582 | case 0x0b: /* vertical feed */ | |
583 | case 0x0c: /* form feed */ | |
584 | esc_index(sp); | |
585 | break; | |
586 | case 0x0d: /* carriage return */ | |
587 | carriage_ret(sp); | |
588 | break; | |
589 | case 0x0e: /* shift out */ | |
590 | break; | |
591 | case 0x0f: /* shift in */ | |
592 | break; | |
593 | case 0x11: /* xon */ | |
594 | break; | |
595 | case 0x13: /* xoff */ | |
596 | break; | |
597 | case 0x18: /* cancel */ | |
598 | sp->s_current_stat &= ~ESCAPE; | |
599 | break; | |
600 | case 0x1b: /* escape */ | |
601 | /* NOT REACHED */ | |
602 | recover(sp); | |
603 | sp->s_current_stat |= ESCAPE; | |
604 | break; | |
605 | case 0x7f: /* delete */ | |
606 | break; | |
607 | ||
608 | default: | |
609 | break; | |
610 | } | |
611 | } else { | |
612 | switch (tmode) { | |
613 | #ifdef KM_SJIS | |
614 | case KM_SJIS: | |
615 | if ((c >= JVR1S && c <= JVR1E) || | |
616 | (c >= JVR2S && c <= JVR2E)) { | |
617 | sp->s_current_stat |= SKANJI; | |
618 | first_code = c; | |
619 | } | |
620 | else | |
621 | addch(sp, c); | |
622 | break; | |
623 | #endif | |
624 | #ifdef KM_EUC | |
625 | case KM_EUC: | |
626 | if (c >= CS1S && c <= CS1E) { | |
627 | sp->s_current_stat |= EKANJI; | |
628 | first_code = c & 0x7f; | |
629 | } | |
630 | else if (c == SS2) | |
631 | sp->s_current_stat |= EKANA; | |
632 | else | |
633 | addch(sp, c); | |
634 | break; | |
635 | #endif | |
636 | #ifdef KM_JIS | |
637 | case KM_JIS: | |
638 | #endif | |
639 | #ifdef KM_ASCII | |
640 | case KM_ASCII: | |
641 | #endif | |
642 | default: | |
643 | addch(sp, c); | |
644 | } | |
645 | } | |
646 | ||
647 | set_csr: | |
648 | cursor_on(&sp->s_csr.csr_p); | |
649 | /* altered */ | |
650 | return ; | |
651 | } | |
652 | ||
653 | /* | |
654 | * A printable character is printed in this routine by using | |
655 | * the routine `_putc()'. | |
656 | * Anyway, a character is printed in replacement mode or insertion | |
657 | * mode and if the terminal is autowrap then it takes place wrapping | |
658 | * and if cursor is bottom margin of the scroll region then it takes | |
659 | * place scroll up. | |
660 | * The escape sequence handling is another routine. | |
661 | * | |
662 | */ | |
663 | addch(sp, c) | |
664 | register SCREEN *sp; | |
665 | unsigned int c; | |
666 | { | |
667 | register struct cursor *spc = &(sp->s_csr); | |
668 | register struct region *spr = &(sp->s_region); | |
669 | ||
670 | if (spc->csr_x >= rit_m || | |
671 | ((sp->s_current_stat & JKANJI) && (spc->csr_x >= rit_m - 1))) { | |
672 | vt_flush(spc); | |
673 | if (sp->s_term_mode & DECAWM) { | |
674 | if ((sp->s_current_stat & WRAP) || (spc->csr_x == rit_m | |
675 | && sp->s_current_stat & JKANJI)) { | |
676 | if (spc->csr_y == spr->btm_margin) { | |
677 | cursor_off(); | |
678 | scroll_up(spr->top_margin, | |
679 | spr->btm_margin, | |
680 | sp->s_term_mode & DECSCNM, | |
681 | sp->s_plane, sp->s_bgcol); | |
682 | cursor_on(&(spc->csr_p)); | |
683 | } else if (spc->csr_y < btm_m) { | |
684 | spc->csr_y += 1; | |
685 | spc->csr_p.y += char_h; | |
686 | } | |
687 | spc->csr_x = LFT_M; | |
688 | spc->csr_p.x = x_ofst; | |
689 | addch(sp, c); | |
690 | return; | |
691 | } | |
692 | sp->s_current_stat |= WRAP; | |
693 | } | |
694 | if (sp->s_current_stat & JKANJI) { | |
695 | if (spc->csr_x != rit_m) { | |
696 | _putc(sp, c, 1); | |
697 | } | |
698 | } else { | |
699 | _putc(sp, c, 0); | |
700 | } | |
701 | if (spc->csr_x < rit_m) { | |
702 | spc->csr_x += 1; | |
703 | spc->csr_p.x += char_w; | |
704 | } | |
705 | ||
706 | return ; | |
707 | } | |
708 | if (sp->s_current_stat & JKANJI) { | |
709 | _putc(sp, c, 1); | |
710 | spc->csr_x++; | |
711 | spc->csr_p.x += char_w; | |
712 | } else { | |
713 | _putc(sp, c, 0); | |
714 | } | |
715 | ||
716 | spc->csr_x++; /* altered */ | |
717 | spc->csr_p.x += char_w; | |
718 | ||
719 | sp->s_current_stat &= ~WRAP; | |
720 | return ; | |
721 | } |