Updated italian translation
[midnight-commander.git] / slang / slvideo.c
blob24197cd9d6b4d0c3fe0a5d77fe78b0d5fbc2cb77
1 /* -*- mode: C; mode: fold -*- */
2 /* Copyright (c) 1992, 1997, 2001, 2002, 2003 John E. Davis
3 * This file is part of the S-Lang library.
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Perl Artistic License.
7 */
9 /* This file is best edited with a folding editor */
11 #include "slinclud.h"
13 #if !defined(__WIN32__) && !defined(__IBMC__)
14 # include <dos.h>
15 #endif
17 #include "slang.h"
18 #include "_slang.h"
20 int SLtt_Term_Cannot_Insert;
21 int SLtt_Term_Cannot_Scroll;
22 int SLtt_Ignore_Beep = 3;
23 int SLtt_Use_Ansi_Colors;
24 int SLtt_Has_Status_Line = 0;
25 int SLtt_Screen_Rows = 25;
26 int SLtt_Screen_Cols = 80;
27 int SLtt_Msdos_Cheap_Video = 0;
29 void (*_SLtt_color_changed_hook)(void);
31 /* This definition will need changing when SLsmg_Char_Type changes. */
32 #define SLSMG_CHAR_TO_USHORT(x) ((unsigned short)(x))
34 /*{{{ ------------- static local variables ---------- */
36 static int Attribute_Byte;
37 static int Scroll_r1 = 0, Scroll_r2 = 25;
38 static int Cursor_Row = 1, Cursor_Col = 1;
39 static int Current_Color;
40 static int IsColor = 1;
41 static int Blink_Killed = 1; /* high intensity background enabled */
43 #define JMAX_COLORS 256
44 #define JNORMAL_COLOR 0
45 #define JNO_COLOR -1
47 static unsigned char Color_Map [JMAX_COLORS] =
49 0x7, 0x70, 0x70, 0x70, 0x70, 0x7, 0x7, 0x7,
50 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
51 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
52 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
53 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
54 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
55 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
56 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
57 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
58 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
59 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
60 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
61 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
62 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
63 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
64 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
65 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
66 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
67 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
68 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
69 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
70 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
71 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
72 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
73 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
74 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
75 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
76 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
77 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
78 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
79 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
80 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7
83 #define JMAX_COLOR_NAMES 16
84 static const char * const Color_Names [JMAX_COLOR_NAMES] =
86 "black", "blue", "green", "cyan",
87 "red", "magenta", "brown", "lightgray",
88 "gray", "brightblue", "brightgreen", "brightcyan",
89 "brightred", "brightmagenta", "yellow", "white"
92 static void fixup_colors (void);
94 /*}}}*/
96 static void goto_rc_abs (int r, int c)
98 SLtt_goto_rc (r - Scroll_r1, c);
101 #if defined(__BORLANDC__) && defined(__MSDOS__)
102 # define IBMPC_ASM_VIDEO 1
103 #endif
105 #if defined(__WATCOMC__) && !defined(__NT__) && !defined(__os2__)
106 # define WATCOM_VIDEO 1
107 #endif
109 #if defined (__GO32__)
110 # define GO32_VIDEO 1
111 #endif
113 #if defined (__EMX__) /* EMX video does both DOS & OS/2 */
114 # define EMX_VIDEO 1
115 #else
116 # if defined(__os2__)
117 # define OS2_VIDEO 1
118 # endif
119 #endif
121 #if defined (__WIN32__)
122 # define WIN32_VIDEO 1
123 #endif
125 /* The functions in these folds contain somewhat video system specific code
126 * that if merged together into single functions will become a confusing
127 * mess.
130 #ifdef IBMPC_ASM_VIDEO /*{{{*/
132 # include <conio.h>
133 # include <bios.h>
134 # include <mem.h>
136 /* buffer to hold a line of character/attribute pairs */
137 #define MAXCOLS 256
138 static unsigned char Line_Buffer [MAXCOLS*2];
140 #define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20)
142 static unsigned char *Video_Base;
143 # define MK_SCREEN_POINTER(row,col) ((unsigned short *)\
144 (Video_Base +\
145 2 * (SLtt_Screen_Cols * (row)\
146 + (col))))
147 static int Video_Status_Port;
149 # define MONO_STATUS 0x3BA
150 # define CGA_STATUS 0x3DA
151 # define CGA_SETMODE 0x3D8
153 # define SNOW_CHECK \
154 if (SLtt_Msdos_Cheap_Video)\
155 { while ((inp (CGA_STATUS) & 0x08)); while (!(inp (CGA_STATUS) & 0x08)); }
157 void SLtt_write_string (char *str)
159 /* FIXME: Priority=medium
160 * This should not go to stdout. */
161 fputs (str, stdout);
164 /* row is with respect to the scrolling region. */
165 void SLtt_goto_rc (int r, int c)
167 union REGS regs;
169 r += Scroll_r1;
171 if (r > SLtt_Screen_Rows - 1) r = SLtt_Screen_Rows - 1;
172 if (c > SLtt_Screen_Cols - 1) c = SLtt_Screen_Cols - 1;
174 Cursor_Row = r;
175 Cursor_Col = c;
177 regs.h.dh = r;
178 regs.h.dl = c;
179 regs.h.bh = 0;
180 regs.h.ah = 2;
181 int86 (0x10, &regs, &regs);
184 static void asm_video_getxy (void)
186 asm mov ah, 3
187 asm mov bh, 0
188 asm int 10h
189 asm xor ax, ax
190 asm mov al, dh
191 asm mov Cursor_Row, ax
192 asm xor ax, ax
193 asm mov al, dl
194 asm mov Cursor_Col, ax
197 void SLtt_begin_insert (void)
199 unsigned short *p;
200 int n;
202 asm_video_getxy ();
203 n = SLtt_Screen_Cols - Cursor_Col;
204 p = MK_SCREEN_POINTER (Cursor_Row, SLtt_Screen_Cols - 1);
206 SNOW_CHECK;
207 asm mov ax, ds
208 asm mov bx, di
209 asm mov dx, si
211 asm mov cx, n
212 asm les di, p
213 asm lds si, p
214 asm sub si, 2
215 asm std
216 asm rep movsw
218 asm mov ds, ax
219 asm mov di, bx
220 asm mov si, dx
223 void SLtt_end_insert (void)
227 void SLtt_delete_char (void)
229 unsigned short *p;
230 int n;
232 asm_video_getxy ();
233 n = SLtt_Screen_Cols - Cursor_Col - 1;
234 p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
236 SNOW_CHECK;
237 asm mov ax, ds
238 asm mov bx, si
239 asm mov dx, di
241 asm mov cx, n
242 asm les di, p
243 asm lds si, p
244 asm add si, 2
245 asm cld
246 asm rep movsw
248 asm mov ds, ax
249 asm mov si, bx
250 asm mov di, dx
253 void SLtt_erase_line (void)
255 unsigned short w, *p;
257 p = MK_SCREEN_POINTER (Cursor_Row, 0);
258 Attribute_Byte = 0x07;
260 w = MK_SPACE_CHAR ();
262 SNOW_CHECK;
263 asm mov dx, di
264 asm mov ax, w
265 asm mov cx, SLtt_Screen_Cols
266 asm les di, p
267 asm cld
268 asm rep stosw
269 asm mov di, dx
271 Current_Color = JNO_COLOR; /* since we messed with attribute byte */
274 void SLtt_delete_nlines (int nlines)
276 SLtt_normal_video ();
278 /* This has the effect of pulling all lines below it up */
279 asm mov ax, nlines
280 asm mov ah, 6 /* int 6h */
281 asm xor cx, cx
282 asm mov ch, byte ptr Scroll_r1
283 asm mov dx, SLtt_Screen_Cols
284 asm dec dx
285 asm mov dh, byte ptr Scroll_r2
286 asm mov bh, byte ptr Attribute_Byte
287 asm int 10h
290 void SLtt_reverse_index (int nlines)
292 SLtt_normal_video ();
293 asm xor cx, cx
294 asm mov ch, byte ptr Scroll_r1
295 asm mov dx, SLtt_Screen_Cols
296 asm dec dx
297 asm mov dh, byte ptr Scroll_r2
298 asm mov bh, byte ptr Attribute_Byte
299 asm mov ah, 7
300 asm mov al, byte ptr nlines
301 asm int 10h
304 static void asm_video_invert_region (int top_row, int bot_row)
306 register unsigned short ch, sh;
307 register unsigned short *pmin = MK_SCREEN_POINTER (top_row, 0);
308 register unsigned short *pmax = MK_SCREEN_POINTER (bot_row, 0);
310 while (pmin < pmax)
312 sh = *pmin;
313 ch = sh;
314 ch = ch ^ 0xFF00;
315 *pmin = (ch & 0xFF00) | (sh & 0x00FF);
316 pmin++;
320 void SLtt_del_eol (void)
322 unsigned short *p;
323 unsigned short w;
324 int n;
326 n = SLtt_Screen_Cols - Cursor_Col;
327 p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
328 if (Current_Color != JNO_COLOR) SLtt_normal_video ();
329 w = MK_SPACE_CHAR ();
331 SNOW_CHECK;
332 asm mov dx, di
333 asm les di, p
334 asm mov ax, w
335 asm mov cx, n
336 asm cld
337 asm rep stosw
339 asm mov di, dx
342 static unsigned short *asm_video_write (register unsigned char *pp,
343 register unsigned char *p,
344 register unsigned short *pos)
346 int n = (int) (p - pp); /* num of characters of PP to write */
348 asm push si
349 asm push ds
350 asm push di
352 /* set up register for BOTH fast and slow */
353 asm mov bx, SLtt_Msdos_Cheap_Video
355 /* These are the registers needed for both fast AND slow */
356 asm mov ah, byte ptr Attribute_Byte
357 asm mov cx, n
358 asm lds si, dword ptr pp
359 asm les di, dword ptr pos
360 asm cld
362 asm cmp bx, 0 /* cheap video test */
363 asm je L_fast
364 asm mov bx, ax
365 asm mov dx, CGA_STATUS
366 asm jg L_slow_blank
368 /* slow video */
369 asm cli
371 /* wait for retrace */
372 L_slow:
373 asm in al, dx
374 asm test al, 1
375 asm jnz L_slow
377 L_slow1:
378 asm in al, dx
379 asm test al, 1
380 asm jz L_slow1
382 /* move a character out */
383 asm mov ah, bh
384 asm lodsb
385 asm stosw
386 asm loop L_slow
388 asm sti
389 asm jmp done
391 /* -------------- slow video, vertical retace and pump --------------*/
392 L_slow_blank:
393 L_slow_blank_loop:
394 asm in al, dx
395 asm test al, 8
396 asm jnz L_slow_blank_loop
398 L_slow_blank1:
399 asm in al, dx
400 asm test al, 8
401 asm jz L_slow_blank1
402 /* write line */
403 asm mov ah, bh
404 L_slow_blank2:
405 asm lodsb
406 asm stosw
407 asm loop L_slow_blank2
409 asm jmp done
410 /*-------------- Fast video --------------*/
412 L_fast:
413 asm lodsb
414 asm stosw
415 asm loop L_fast
416 done:
417 asm pop di
418 asm pop ds
419 asm pop si
420 return (pos + n);
423 static void write_attributes (SLsmg_Char_Type *src, unsigned int count)
425 register unsigned char *p;
426 register unsigned short pair;
427 unsigned char ch, color;
428 register unsigned short *pos;
430 p = Line_Buffer;
431 pos = MK_SCREEN_POINTER (Cursor_Row, 0);
433 while (count--)
435 pair = SLSMG_CHAR_TO_USHORT(*src); /* character/color pair */
436 src++;
437 ch = pair & 0xff; /* character value */
438 color = pair >> 8; /* color value */
439 if (color != Current_Color) /* need a new color */
441 if (p != Line_Buffer)
443 pos = asm_video_write (Line_Buffer, p, pos);
444 p = Line_Buffer;
446 SLtt_reverse_video (color); /* change color */
448 *(p++) = ch;
450 pos = asm_video_write (Line_Buffer, p, pos);
453 void SLtt_cls (void)
455 SLtt_normal_video ();
457 asm mov dx, SLtt_Screen_Cols
458 asm dec dx
459 asm mov ax, SLtt_Screen_Rows
460 asm dec ax
461 asm mov dh, al
462 asm xor cx, cx
463 asm xor ax, ax
464 asm mov ah, 7
465 asm mov bh, byte ptr Attribute_Byte
466 asm int 10h
469 void SLtt_putchar (char ch)
471 unsigned short p, *pp;
473 if (Current_Color) SLtt_normal_video ();
474 asm_video_getxy (); /* get current position */
475 switch (ch)
477 case 7: /* ^G - break */
478 SLtt_beep (); break;
479 case 8: /* ^H - backspace */
480 goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
481 case 13: /* ^M - carriage return */
482 goto_rc_abs (Cursor_Row, 0); break;
483 default:
484 /* write character to screen */
485 pp = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
486 p = (Attribute_Byte << 8) | (unsigned char) ch;
487 SNOW_CHECK;
488 *pp = p;
489 goto_rc_abs (Cursor_Row, Cursor_Col + 1);
493 void SLtt_get_screen_size (void)
495 int w, h;
497 h = 0;
499 /* Get BIOS's screenwidth, this works on ALL displays. */
500 w = *((int *)MK_FP(0x40, 0x4a));
502 /* Use Ralf Brown test for EGA or greater */
503 asm mov ah, 12h
504 asm mov bl, 10h
505 asm mov bh, 0xFF /* EGA or greater will change this */
506 asm int 10h
507 asm cmp bh, 0xFF
508 asm je L1
509 /* if EGA or compatible: Get BIOS's number of rows. */
510 h = *(char *)MK_FP(0x40, 0x84) + 1;
511 /* scan_lines = *(int *) 0x485; */
514 if (h <= 0) h = 25;
516 SLtt_Screen_Rows = h;
517 SLtt_Screen_Cols = w;
520 void SLtt_get_terminfo (void)
522 SLtt_get_screen_size ();
525 /*----------------------------------------------------------------------*\
526 * Function: int SLtt_init_video (void);
527 \*----------------------------------------------------------------------*/
528 int SLtt_init_video (void)
530 unsigned char *p;
532 #ifdef HAS_SAVE_SCREEN
533 save_screen ();
534 #endif
536 Cursor_Row = Cursor_Col = 0;
537 p = (unsigned char far *) 0x00400049L;
538 if (*p == 7)
540 Video_Status_Port = MONO_STATUS;
541 Video_Base = (unsigned char *) MK_FP (0xb000,0000);
542 IsColor = 0;
544 else
546 Video_Status_Port = CGA_STATUS;
547 Video_Base = (unsigned char *) MK_FP (0xb800,0000);
548 IsColor = 1;
551 /* test for video adapter type. Of primary interest is whether there is
552 * snow or not. Assume snow if the card is color and not EGA or greater.
555 /* Use Ralf Brown test for EGA or greater */
556 asm mov ah, 0x12
557 asm mov bl, 0x10
558 asm mov bh, 0xFF
559 asm int 10h
560 asm cmp bh, 0xFF
561 asm je L1
563 /* (V)EGA */
564 asm xor bx, bx
565 asm mov SLtt_Msdos_Cheap_Video, bx
566 asm mov ax, Attribute_Byte
567 asm cmp ax, bx
568 asm jne L2
569 asm mov ax, 0x17
570 asm mov Attribute_Byte, ax
571 asm jmp L2
574 /* Not (V)EGA */
575 asm mov ah, 0x0F
576 asm int 10h
577 asm cmp al, 7
578 asm je L3
579 asm mov ax, 1
580 asm mov SLtt_Msdos_Cheap_Video, ax
582 asm mov ax, Attribute_Byte
583 asm cmp ax, 0
584 asm jne L2
585 asm mov ax, 0x07
586 asm mov Attribute_Byte, ax
588 /* toggle the blink bit so we can use hi intensity background */
589 if (IsColor && !SLtt_Msdos_Cheap_Video)
591 asm mov ax, 0x1003
592 asm mov bx, 0
593 asm int 0x10
594 Blink_Killed = 1;
597 SLtt_Use_Ansi_Colors = IsColor;
598 SLtt_get_screen_size ();
599 SLtt_reset_scroll_region ();
600 fixup_colors ();
601 return 0;
604 void SLtt_beep (void)
606 int audible; /* audible bell */
607 int special = 0; /* first row to invert */
608 int visual = 0; /* final row to invert */
610 if (!SLtt_Ignore_Beep) return;
612 audible = (SLtt_Ignore_Beep & 1);
613 if ( (SLtt_Ignore_Beep & 4) )
615 special = SLtt_Screen_Rows - 1;
616 visual = special--; /* only invert bottom status line */
618 else if ( (SLtt_Ignore_Beep & 2) )
620 visual = SLtt_Screen_Rows;
623 if (visual) asm_video_invert_region (special, visual);
624 if (audible) sound (1500); delay (100); if (audible) nosound ();
625 if (visual) asm_video_invert_region (special, visual);
628 #endif /* IBMPC_ASM_VIDEO */
630 /*}}}*/
632 #ifdef GO32_VIDEO /*{{{*/
634 # include <pc.h>
635 # define HAS_SAVE_SCREEN 1
637 # ifdef HAS_SAVE_SCREEN
638 static void *Saved_Screen_Buffer;
639 static int Saved_Cursor_Row;
641 static void save_screen (void)
643 int row, col;
645 SLfree ((char *) Saved_Screen_Buffer);
646 Saved_Screen_Buffer = NULL;
648 Saved_Screen_Buffer = (short *) SLmalloc (sizeof (short) *
649 ScreenCols () * ScreenRows ());
651 if (Saved_Screen_Buffer == NULL)
652 return;
654 ScreenRetrieve (Saved_Screen_Buffer);
655 ScreenGetCursor (&row, &col);
656 Saved_Cursor_Row = row;
659 static void restore_screen (void)
661 if (Saved_Screen_Buffer == NULL) return;
662 ScreenUpdate (Saved_Screen_Buffer);
663 goto_rc_abs (Saved_Cursor_Row, 0);
665 #endif /* HAS_SAVE_SCREEN */
667 void SLtt_write_string (char *str)
669 while (Cursor_Col < SLtt_Screen_Cols)
671 char ch = *str++;
673 if (ch == 0)
674 break;
676 ScreenPutChar (ch, Attribute_Byte, Cursor_Col, Cursor_Row);
677 Cursor_Col++;
679 goto_rc_abs (Cursor_Row, Cursor_Col);
682 void SLtt_goto_rc (int row, int col)
684 row += Scroll_r1;
685 if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
686 if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
688 ScreenSetCursor (row, col);
690 Cursor_Row = row;
691 Cursor_Col = col;
694 static void go32_video_getxy (void)
696 ScreenGetCursor (&Cursor_Row, &Cursor_Col);
699 static void go32_video_deleol (int x)
701 while (x < SLtt_Screen_Cols)
702 ScreenPutChar (32, Attribute_Byte, x++, Cursor_Row);
705 void SLtt_begin_insert (void)
709 void SLtt_end_insert (void)
713 void SLtt_delete_char (void)
717 void SLtt_erase_line (void)
719 Attribute_Byte = 0x07;
720 go32_video_deleol (0);
721 Current_Color = JNO_COLOR; /* since we messed with attribute byte */
724 void SLtt_delete_nlines (int nlines)
726 union REGS r;
728 SLtt_normal_video ();
730 r.x.ax = nlines;
731 r.x.cx = 0;
732 r.h.ah = 6;
733 r.h.ch = Scroll_r1;
734 r.h.dl = SLtt_Screen_Cols - 1;
735 r.h.dh = Scroll_r2;
736 r.h.bh = Attribute_Byte;
737 int86 (0x10, &r, &r);
740 void SLtt_reverse_index (int nlines)
742 union REGS r;
744 SLtt_normal_video ();
746 r.h.al = nlines;
747 r.x.cx = 0;
748 r.h.ah = 7;
749 r.h.ch = Scroll_r1;
750 r.h.dl = SLtt_Screen_Cols - 1;
751 r.h.dh = Scroll_r2;
752 r.h.bh = Attribute_Byte;
753 int86 (0x10, &r, &r);
756 static void go32_video_invert_region (int top_row, int bot_row)
758 unsigned char buf [2 * 180 * 80]; /* 180 cols x 80 rows */
759 unsigned char *b, *bmax;
761 b = buf + 1 + 2 * SLtt_Screen_Cols * top_row;
762 bmax = buf + 1 + 2 * SLtt_Screen_Cols * bot_row;
764 ScreenRetrieve (buf);
765 while (b < bmax)
767 *b ^= 0xFF;
768 b += 2;
770 ScreenUpdate (buf);
773 void SLtt_beep (void)
775 int audible; /* audible bell */
776 int special = 0; /* first row to invert */
777 int visual = 0; /* final row to invert */
779 if (!SLtt_Ignore_Beep) return;
781 audible = (SLtt_Ignore_Beep & 1);
782 if ( (SLtt_Ignore_Beep & 4) )
784 special = SLtt_Screen_Rows - 1;
785 visual = special--; /* only invert bottom status line */
787 else if ( (SLtt_Ignore_Beep & 2) )
789 visual = SLtt_Screen_Rows;
792 if (visual) go32_video_invert_region (special, visual);
793 if (audible) sound (1500); delay (100); if (audible) nosound ();
794 if (visual) go32_video_invert_region (special, visual);
797 void SLtt_del_eol (void)
799 if (Current_Color != JNO_COLOR) SLtt_normal_video ();
800 go32_video_deleol (Cursor_Col);
803 static void
804 write_attributes (SLsmg_Char_Type *src, unsigned int count)
806 register unsigned short pair;
807 unsigned int n;
809 /* write into a character/attribute pair */
810 n = Cursor_Col;
811 while (count)
813 pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
814 src++;
815 SLtt_reverse_video (pair >> 8); /* color change */
816 ScreenPutChar ((int)pair & 0xFF, Attribute_Byte, n, Cursor_Row);
817 n++;
818 count--;
822 /*----------------------------------------------------------------------*\
823 * Function: void SLtt_cls (void);
824 \*----------------------------------------------------------------------*/
825 void SLtt_cls (void)
827 SLtt_normal_video ();
828 SLtt_reset_scroll_region ();
829 SLtt_goto_rc (0, 0);
830 SLtt_delete_nlines (SLtt_Screen_Rows);
833 void SLtt_putchar (char ch)
835 if (Current_Color) SLtt_normal_video ();
837 go32_video_getxy (); /* get current position */
839 switch (ch)
841 case 7: /* ^G - break */
842 SLtt_beep (); break;
843 case 8: /* ^H - backspace */
844 goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
845 case 13: /* ^M - carriage return */
846 goto_rc_abs (Cursor_Row, 0); break;
847 default: /* write character to screen */
848 ScreenPutChar ((int) ch, Attribute_Byte, Cursor_Col, Cursor_Row);
849 goto_rc_abs (Cursor_Row, Cursor_Col + 1);
853 void SLtt_get_screen_size (void)
855 SLtt_Screen_Rows = ScreenRows ();
856 SLtt_Screen_Cols = ScreenCols ();
859 void SLtt_get_terminfo (void)
861 SLtt_get_screen_size ();
864 int SLtt_init_video (void)
866 #ifdef HAS_SAVE_SCREEN
867 save_screen ();
868 #endif
870 if (!Attribute_Byte) Attribute_Byte = 0x17;
872 IsColor = 1; /* is it really? */
874 if (IsColor)
876 union REGS r;
877 r.x.ax = 0x1003; r.x.bx = 0;
878 int86 (0x10, &r, &r);
879 Blink_Killed = 1;
882 Cursor_Row = Cursor_Col = 0;
884 SLtt_Term_Cannot_Insert = 1;
885 SLtt_reset_scroll_region ();
886 SLtt_Use_Ansi_Colors = IsColor;
887 fixup_colors ();
888 return 0;
891 #endif /* GO32_VIDEO */
893 /*}}}*/
895 #ifdef EMX_VIDEO /*{{{*/
897 # define INCL_VIO
898 # define INCL_DOSPROCESS
899 # include <os2.h>
900 # include <os2emx.h>
901 # include <sys/video.h>
903 static VIOMODEINFO vioModeInfo;
904 /* buffer to hold a line of character/attribute pairs */
905 #define MAXCOLS 256
906 static unsigned char Line_Buffer [MAXCOLS*2];
908 /* this is how to make a space character */
909 #define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20)
911 void SLtt_write_string (char *str)
913 /* FIXME: Priority=medium
914 * This should not go to stdout. */
915 fputs (str, stdout);
918 void SLtt_goto_rc (int row, int col)
920 row += Scroll_r1;
921 if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
922 if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
923 v_gotoxy (col, row);
924 Cursor_Row = row;
925 Cursor_Col = col;
928 static void emx_video_getxy (void)
930 v_getxy (&Cursor_Col, &Cursor_Row);
933 static void emx_video_deleol (int x)
935 unsigned char *p, *pmax;
936 int count = SLtt_Screen_Cols - x;
937 int w = MK_SPACE_CHAR ();
939 p = Line_Buffer;
940 pmax = p + 2 * count;
942 while (p < pmax)
944 *p++ = (unsigned char) w;
945 *p++ = (unsigned char) (w >> 8);
948 v_putline (Line_Buffer, x, Cursor_Row, count);
951 void SLtt_begin_insert (void)
953 int n;
955 emx_video_getxy ();
957 n = SLtt_Screen_Cols - Cursor_Col;
958 v_getline (Line_Buffer, Cursor_Col, Cursor_Row, n);
959 v_putline (Line_Buffer, Cursor_Col+1, Cursor_Row, n - 1);
962 void SLtt_end_insert (void)
966 void SLtt_delete_char (void)
968 int n;
970 emx_video_getxy ();
972 n = SLtt_Screen_Cols - Cursor_Col - 1;
973 v_getline (Line_Buffer, Cursor_Col+1, Cursor_Row, n);
974 v_putline (Line_Buffer, Cursor_Col, Cursor_Row, n);
977 void SLtt_erase_line (void)
979 Attribute_Byte = 0x07;
980 emx_video_deleol (0);
981 Current_Color = JNO_COLOR; /* since we messed with attribute byte */
984 void SLtt_delete_nlines (int nlines)
986 SLtt_normal_video ();
987 v_attrib (Attribute_Byte);
988 v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines, V_SCROLL_UP);
991 void SLtt_reverse_index (int nlines)
993 SLtt_normal_video ();
995 v_attrib (Attribute_Byte);
996 v_scroll (0, Scroll_r1, SLtt_Screen_Cols-1, Scroll_r2, nlines,
997 V_SCROLL_DOWN);
1000 static void emx_video_invert_region (int top_row, int bot_row)
1002 int row, col;
1004 for (row = top_row; row < bot_row; row++)
1006 v_getline (Line_Buffer, 0, row, SLtt_Screen_Cols);
1007 for (col = 1; col < SLtt_Screen_Cols * 2; col += 2)
1008 Line_Buffer [col] ^= 0xff;
1009 v_putline (Line_Buffer, 0, row, SLtt_Screen_Cols);
1013 void SLtt_beep (void)
1015 int audible; /* audible bell */
1016 int special = 0; /* first row to invert */
1017 int visual = 0; /* final row to invert */
1019 if (!SLtt_Ignore_Beep) return;
1021 audible = (SLtt_Ignore_Beep & 1);
1022 if ( (SLtt_Ignore_Beep & 4) )
1024 special = SLtt_Screen_Rows - 1;
1025 visual = special--; /* only invert bottom status line */
1027 else if ( (SLtt_Ignore_Beep & 2) )
1029 visual = SLtt_Screen_Rows;
1032 if (visual) emx_video_invert_region (special, visual);
1033 if (audible) /*sound (1500)*/; _sleep2 (100); if (audible) /* nosound () */;
1034 if (visual) emx_video_invert_region (special, visual);
1037 void SLtt_del_eol (void)
1039 if (Current_Color != JNO_COLOR) SLtt_normal_video ();
1040 emx_video_deleol (Cursor_Col);
1043 static void
1044 write_attributes (SLsmg_Char_Type *src, unsigned int count)
1046 register unsigned char *p = Line_Buffer;
1047 register unsigned short pair;
1048 int n = count;
1050 /* write into a character/attribute pair */
1051 while (n-- > 0)
1053 pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
1054 src++;
1055 SLtt_reverse_video (pair >> 8); /* color change */
1056 *(p++) = pair & 0xff; /* character byte */
1057 *(p++) = Attribute_Byte; /* attribute byte */
1059 v_putline (Line_Buffer, Cursor_Col, Cursor_Row, count);
1062 void SLtt_cls (void)
1064 SLtt_normal_video ();
1065 SLtt_reset_scroll_region ();
1066 SLtt_goto_rc (0, 0);
1067 SLtt_delete_nlines (SLtt_Screen_Rows);
1070 void SLtt_putchar (char ch)
1072 if (Current_Color) SLtt_normal_video ();
1074 emx_video_getxy (); /* get current position */
1075 switch (ch)
1077 case 7: /* ^G - break */
1078 SLtt_beep (); break;
1079 case 8: /* ^H - backspace */
1080 goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
1081 case 13: /* ^M - carriage return */
1082 goto_rc_abs (Cursor_Row, 0); break;
1083 default: /* write character to screen */
1084 v_putn (ch, 1);
1085 goto_rc_abs (Cursor_Row, Cursor_Col + 1);
1089 void SLtt_get_terminfo (void)
1091 SLtt_get_screen_size ();
1094 void SLtt_get_screen_size (void)
1096 vioModeInfo.cb = sizeof(vioModeInfo);
1097 VioGetMode (&vioModeInfo, 0);
1098 SLtt_Screen_Cols = vioModeInfo.col;
1099 SLtt_Screen_Rows = vioModeInfo.row;
1102 int SLtt_init_video (void)
1104 int OldCol, OldRow;
1105 PTIB ptib;
1106 PPIB ppib;
1107 USHORT args[3] = { 6, 2, 1 };
1109 #ifdef HAS_SAVE_SCREEN
1110 save_screen ();
1111 #endif
1113 Cursor_Row = Cursor_Col = 0;
1115 v_init ();
1116 if ( v_hardware () != V_MONOCHROME ) IsColor = 1; else IsColor = 0;
1118 v_getxy(&OldCol,&OldRow);
1119 v_gotoxy (0, 0);
1120 if (IsColor)
1122 if (_osmode == OS2_MODE)
1124 # if 0
1125 /* Enable high-intensity background colors */
1126 VIOINTENSITY RequestBlock;
1127 RequestBlock.cb = sizeof (RequestBlock);
1128 RequestBlock.type = 2; RequestBlock.fs = 1;
1129 VioSetState (&RequestBlock, 0); /* nop if !fullscreen */
1130 # endif
1134 DosGetInfoBlocks (&ptib, &ppib);
1135 if ((ppib->pib_ultype) == 2) /* VIO */
1136 Blink_Killed = 1;
1137 else
1138 { /* Fullscreen */
1139 if (VioSetState (args, 0) == 0)
1140 Blink_Killed = 1;
1141 else
1142 Blink_Killed = 0;
1145 if (!Attribute_Byte)
1147 /* find the attribute currently under the cursor */
1148 v_getline (Line_Buffer, OldCol, OldRow, 1);
1149 Attribute_Byte = Line_Buffer[1];
1150 SLtt_set_color (JNORMAL_COLOR, NULL,
1151 Color_Names[(Attribute_Byte) & 0xf],
1152 Color_Names[(Attribute_Byte) >> 4]);
1155 v_attrib (Attribute_Byte);
1157 fixup_colors ();
1159 SLtt_get_screen_size ();
1160 SLtt_Use_Ansi_Colors = IsColor;
1161 SLtt_reset_scroll_region ();
1162 return 0;
1165 #endif /* EMX_VIDEO */
1167 /*}}}*/
1169 #ifdef WIN32_VIDEO /*{{{*/
1171 #include <windows.h>
1173 static HANDLE hStdout = INVALID_HANDLE_VALUE;
1175 #define MAXCOLS 256
1176 static CHAR_INFO Line_Buffer [MAXCOLS];
1178 void SLtt_write_string (char *str)
1180 DWORD bytes;
1181 int n, c;
1182 if (str == NULL) return;
1184 n = (int) strlen (str);
1185 c = n + Cursor_Col;
1186 if (c >= SLtt_Screen_Cols)
1187 n = SLtt_Screen_Cols - Cursor_Col;
1188 if (n < 0) n = 0;
1190 (void) WriteConsole (hStdout, str, (unsigned int) n, &bytes, NULL);
1192 goto_rc_abs (Cursor_Row, Cursor_Col + n);
1195 void SLtt_goto_rc (int row, int col)
1197 COORD newPosition;
1199 row += Scroll_r1;
1200 if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
1201 if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
1202 newPosition.X = col;
1203 newPosition.Y = row;
1205 (void) SetConsoleCursorPosition(hStdout, newPosition);
1207 Cursor_Row = row;
1208 Cursor_Col = col;
1211 static void win32_video_getxy (void)
1213 CONSOLE_SCREEN_BUFFER_INFO screenInfo;
1215 if (TRUE == GetConsoleScreenBufferInfo(hStdout, &screenInfo))
1217 Cursor_Row = screenInfo.dwCursorPosition.Y;
1218 Cursor_Col = screenInfo.dwCursorPosition.X;
1222 static void win32_video_hscroll (int n)
1224 SMALL_RECT rc;
1225 COORD c;
1226 CHAR_INFO ci;
1227 WORD w = 227;
1228 DWORD d;
1230 win32_video_getxy ();
1232 rc.Left = Cursor_Col;
1233 rc.Right = SLtt_Screen_Cols;
1234 rc.Top = rc.Bottom = Cursor_Row;
1236 c.Y = Cursor_Row;
1237 #if 1
1238 c.X = SLtt_Screen_Cols - 1;
1239 ReadConsoleOutputAttribute(hStdout, &w, 1, c, &d);
1240 #else
1241 /* New region gets the current color */
1242 w = Attribute_Byte;
1243 #endif
1244 c.X = Cursor_Col + n;
1246 ci.Char.AsciiChar = ' ';
1247 ci.Attributes = w;
1249 ScrollConsoleScreenBuffer(hStdout, &rc, &rc, c, &ci);
1252 static void win32_video_deleol (int x)
1254 DWORD d;
1255 COORD c;
1257 c.X = x;
1258 c.Y = Cursor_Row;
1260 x = SLtt_Screen_Cols - x;
1261 FillConsoleOutputCharacter(hStdout, ' ', x, c, &d);
1262 FillConsoleOutputAttribute(hStdout, (char)Attribute_Byte, x, c, &d);
1265 static void win32_video_vscroll (int n)
1267 SMALL_RECT rc, clip_rc;
1268 COORD c;
1269 CHAR_INFO ci;
1271 SLtt_normal_video();
1273 /* ScrollConsoleScreenBuffer appears to have a bug when
1274 * Scroll_r1 == Scroll_r2. Sigh.
1276 if (Scroll_r2 == Scroll_r1)
1278 SLtt_goto_rc (0, 0);
1279 win32_video_deleol (0);
1280 return;
1283 rc.Left = clip_rc.Left = 0;
1284 rc.Right = clip_rc.Right = SLtt_Screen_Cols - 1;
1285 rc.Top = clip_rc.Top = Scroll_r1;
1286 rc.Bottom = clip_rc.Bottom = Scroll_r2;
1288 c.X = 0;
1289 c.Y = Scroll_r1 + n;
1291 ci.Char.AsciiChar = ' ';
1292 ci.Attributes = Attribute_Byte;
1294 ScrollConsoleScreenBuffer(hStdout, &rc, &clip_rc, c, &ci);
1297 void SLtt_begin_insert (void)
1299 win32_video_hscroll (1);
1302 void SLtt_end_insert (void)
1306 void SLtt_delete_char (void)
1308 win32_video_hscroll (-1);
1311 void SLtt_erase_line (void)
1313 Attribute_Byte = 0x7;
1314 win32_video_deleol (0);
1315 Current_Color = JNO_COLOR;
1318 void SLtt_delete_nlines (int nlines)
1320 win32_video_vscroll (-nlines);
1323 void SLtt_reverse_index (int nlines)
1325 win32_video_vscroll (nlines);
1328 static void win32_invert_region (int top_row, int bot_row)
1330 (void) top_row; (void) bot_row;
1333 void SLtt_beep (void)
1335 int audible; /* audible bell */
1336 int special = 0; /* first row to invert */
1337 int visual = 0; /* final row to invert */
1339 if (!SLtt_Ignore_Beep) return;
1341 audible = (SLtt_Ignore_Beep & 1);
1343 if ( (SLtt_Ignore_Beep & 4) )
1345 special = SLtt_Screen_Rows - 1;
1346 visual = special--; /* only invert bottom status line */
1348 else if ( (SLtt_Ignore_Beep & 2) )
1350 visual = SLtt_Screen_Rows;
1353 if (visual) win32_invert_region (special, visual);
1354 if (audible) Beep (1500, 100); else Sleep (100);
1355 if (visual) win32_invert_region (special, visual);
1358 void SLtt_del_eol (void)
1360 if (Current_Color != JNO_COLOR)
1361 SLtt_normal_video ();
1362 win32_video_deleol (Cursor_Col);
1365 static void
1366 write_attributes (SLsmg_Char_Type *src, unsigned int count)
1368 unsigned short pair;
1369 COORD coord, c;
1370 CHAR_INFO *p;
1371 unsigned int n;
1372 SMALL_RECT rc;
1374 /* write into a character/attribute pair */
1375 n = count;
1376 p = Line_Buffer;
1377 while (n)
1379 n--;
1380 pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
1381 src++;
1382 SLtt_reverse_video (pair >> 8); /* color change */
1383 p->Char.AsciiChar = pair & 0xff;
1384 p->Attributes = Attribute_Byte;
1385 p++;
1388 c.X = count;
1389 c.Y = 1;
1390 coord.X = coord.Y = 0;
1391 rc.Left = Cursor_Col;
1392 rc.Right = Cursor_Col + count - 1;
1393 rc.Top = rc.Bottom = Cursor_Row;
1394 WriteConsoleOutput(hStdout, Line_Buffer, c, coord, &rc);
1397 void SLtt_cls (void)
1399 DWORD bytes;
1400 COORD coord;
1401 char ch;
1403 SLtt_normal_video ();
1404 /* clear the WIN32 screen in one shot */
1405 coord.X = 0;
1406 coord.Y = 0;
1408 ch = ' ';
1410 (void) FillConsoleOutputCharacter(hStdout,
1412 SLtt_Screen_Cols * SLtt_Screen_Rows,
1413 coord,
1414 &bytes);
1416 /* now set screen to the current attribute */
1417 ch = Attribute_Byte;
1418 (void) FillConsoleOutputAttribute(hStdout,
1420 SLtt_Screen_Cols * SLtt_Screen_Rows,
1421 coord,
1422 &bytes);
1425 void SLtt_putchar (char ch)
1427 DWORD bytes;
1428 WORD attr;
1429 COORD c;
1431 if (Current_Color) SLtt_normal_video ();
1432 win32_video_getxy ();
1433 switch (ch)
1435 case 7: /* ^G - break */
1436 SLtt_beep (); break;
1437 case 8: /* ^H - backspace */
1438 goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
1439 case 13: /* ^M - carriage return */
1440 goto_rc_abs (Cursor_Row, 0); break;
1441 default: /* write character to screen */
1442 c.X = Cursor_Col;
1443 c.Y = Cursor_Row;
1444 attr = Attribute_Byte;
1445 WriteConsoleOutputCharacter(hStdout, &ch, 1, c, &bytes);
1446 WriteConsoleOutputAttribute(hStdout, &attr, 1, c, &bytes);
1447 goto_rc_abs (Cursor_Row, Cursor_Col + 1);
1451 void SLtt_get_screen_size (void)
1453 CONSOLE_SCREEN_BUFFER_INFO csbi;
1454 HANDLE h;
1456 h = hStdout;
1457 if (h == INVALID_HANDLE_VALUE)
1458 h = GetStdHandle (STD_OUTPUT_HANDLE);
1460 if ((h == INVALID_HANDLE_VALUE)
1461 || (FALSE == GetConsoleScreenBufferInfo(h, &csbi)))
1463 SLang_exit_error ("Unable to determine the screen size");
1464 return;
1466 #if 0
1467 SLtt_Screen_Rows = csbi.dwSize.Y;
1468 SLtt_Screen_Cols = csbi.dwSize.X;
1469 #else
1470 SLtt_Screen_Rows = (csbi.srWindow.Bottom - csbi.srWindow.Top) + 1;
1471 SLtt_Screen_Cols = (csbi.srWindow.Right - csbi.srWindow.Left) + 1;
1472 #endif
1475 void SLtt_get_terminfo (void)
1477 SLtt_get_screen_size ();
1480 static int win32_resize (void)
1482 SMALL_RECT windowRect;
1484 SLtt_get_screen_size ();
1486 windowRect.Left = 0;
1487 windowRect.Top = 0;
1488 windowRect.Right = SLtt_Screen_Cols - 1;
1489 windowRect.Bottom = SLtt_Screen_Rows - 1;
1491 if (FALSE == SetConsoleWindowInfo(hStdout, TRUE, &windowRect))
1492 return -1;
1494 return 0;
1497 static int win32_init (void)
1499 SECURITY_ATTRIBUTES sec;
1501 memset ((char *) &sec, 0, sizeof(SECURITY_ATTRIBUTES));
1502 sec.nLength = sizeof (SECURITY_ATTRIBUTES);
1503 sec.bInheritHandle = FALSE;
1505 hStdout = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
1506 FILE_SHARE_READ|FILE_SHARE_WRITE,
1507 &sec,
1508 CONSOLE_TEXTMODE_BUFFER,
1511 if (hStdout == INVALID_HANDLE_VALUE)
1512 return -1;
1514 if ((FALSE == SetConsoleActiveScreenBuffer(hStdout))
1515 || (FALSE == SetConsoleMode(hStdout, 0))
1516 || (-1 == win32_resize ()))
1518 SLtt_reset_video ();
1519 return -1;
1522 return 0;
1525 int SLtt_init_video (void)
1527 SLtt_reset_video ();
1529 if (-1 == win32_init ())
1530 return -1;
1532 /* It is possible for SLtt_init_video to be called after suspension.
1533 * For all I know, the window size may have changed. So, resize it
1534 * now.
1537 Cursor_Row = Cursor_Col = 0;
1538 SLtt_Use_Ansi_Colors = IsColor = 1;
1539 Blink_Killed = 1;
1541 SLtt_reset_scroll_region ();
1542 goto_rc_abs (0, 0);
1543 fixup_colors ();
1545 return 0;
1548 int SLtt_reset_video (void)
1550 if (hStdout == INVALID_HANDLE_VALUE)
1551 return 0;
1553 SLtt_reset_scroll_region ();
1554 SLtt_goto_rc (SLtt_Screen_Rows - 1, 0);
1555 Attribute_Byte = 0x7;
1556 Current_Color = JNO_COLOR;
1557 SLtt_del_eol ();
1558 (void) CloseHandle (hStdout);
1560 hStdout = GetStdHandle (STD_OUTPUT_HANDLE);
1561 if (hStdout != INVALID_HANDLE_VALUE)
1562 (void) SetConsoleActiveScreenBuffer(hStdout);
1564 hStdout = INVALID_HANDLE_VALUE;
1565 return 0;
1568 #endif
1570 /*}}}*/
1572 #ifdef OS2_VIDEO /*{{{*/
1574 # define INCL_BASE
1575 # define INCL_NOPM
1576 # define INCL_VIO
1577 # define INCL_KBD
1579 # define INCL_DOSPROCESS
1581 # include <os2.h>
1582 # ifndef __IBMC__
1583 # include <dos.h>
1584 # endif
1585 /* this is how to make a space character */
1586 #define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20)
1588 /* buffer to hold a line of character/attribute pairs */
1589 #define MAXCOLS 256
1590 static unsigned char Line_Buffer [MAXCOLS*2];
1592 void SLtt_write_string (char *str)
1594 /* FIXME: Priority=medium
1595 * This should not go to stdout. */
1596 fputs (str, stdout);
1599 void SLtt_goto_rc (int row, int col)
1601 row += Scroll_r1;
1602 VioSetCurPos (row, col, 0);
1603 Cursor_Row = row;
1604 Cursor_Col = col;
1607 static void os2_video_getxy (void)
1609 USHORT r, c;
1611 VioGetCurPos (&r, &c, 0);
1612 Cursor_Row = r;
1613 Cursor_Col = c;
1616 void SLtt_begin_insert (void)
1618 USHORT n;
1620 os2_video_getxy ();
1621 n = SLtt_Screen_Cols - Cursor_Col;
1623 n = 2 * (n - 1);
1624 VioReadCellStr ((PCH)Line_Buffer, &n, Cursor_Row, Cursor_Col, 0);
1625 VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col + 1, 0);
1628 void SLtt_end_insert (void)
1632 void SLtt_delete_char (void)
1634 USHORT n;
1636 os2_video_getxy ();
1637 n = SLtt_Screen_Cols - Cursor_Col - 1;
1639 n *= 2;
1640 VioReadCellStr ((PCH)Line_Buffer, &n, Cursor_Row, Cursor_Col + 1, 0);
1641 VioWrtCellStr ((PCH)Line_Buffer, n, Cursor_Row, Cursor_Col, 0);
1644 void SLtt_erase_line (void)
1646 USHORT w;
1648 Attribute_Byte = 0x07;
1649 w = MK_SPACE_CHAR ();
1651 VioWrtNCell ((BYTE*)&w, SLtt_Screen_Cols, Cursor_Row, 0, 0);
1653 Current_Color = JNO_COLOR; /* since we messed with attribute byte */
1656 void SLtt_delete_nlines (int nlines)
1658 SLtt_normal_video ();
1660 Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte;
1661 VioScrollUp (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1,
1662 nlines, (PCH) Line_Buffer, 0);
1665 void SLtt_reverse_index (int nlines)
1667 SLtt_normal_video ();
1669 Line_Buffer[0] = ' '; Line_Buffer[1] = Attribute_Byte;
1670 VioScrollDn (Scroll_r1, 0, Scroll_r2, SLtt_Screen_Cols-1,
1671 nlines, (PCH) Line_Buffer, 0);
1674 static void os2_video_invert_region (int top_row, int bot_row)
1676 int row, col;
1677 USHORT length = SLtt_Screen_Cols * 2;
1679 for (row = top_row; row < bot_row; row++)
1681 VioReadCellStr ((PCH)Line_Buffer, &length, row, 0, 0);
1682 for (col = 1; col < length; col += 2)
1683 Line_Buffer [col] ^= 0xff;
1684 VioWrtCellStr ((PCH)Line_Buffer, length, row, 0, 0);
1688 void SLtt_beep (void)
1690 int audible; /* audible bell */
1691 int special = 0; /* first row to invert */
1692 int visual = 0; /* final row to invert */
1694 if (!SLtt_Ignore_Beep) return;
1696 audible = (SLtt_Ignore_Beep & 1);
1698 if ( (SLtt_Ignore_Beep & 4) )
1700 special = SLtt_Screen_Rows - 1;
1701 visual = special--; /* only invert bottom status line */
1703 else if ( (SLtt_Ignore_Beep & 2) )
1705 visual = SLtt_Screen_Rows;
1708 if (visual) os2_video_invert_region (special, visual);
1709 if (audible) DosBeep (1500, 100); else DosSleep (100);
1710 if (visual) os2_video_invert_region (special, visual);
1713 void SLtt_del_eol (void)
1715 USHORT w;
1716 if (Current_Color != JNO_COLOR) SLtt_normal_video ();
1718 w = MK_SPACE_CHAR ();
1720 VioWrtNCell ((BYTE*)&w, (SLtt_Screen_Cols - Cursor_Col),
1721 Cursor_Row, Cursor_Col, 0);
1724 static void
1725 write_attributes (SLsmg_Char_Type *src, unsigned int count)
1727 register unsigned char *p = Line_Buffer;
1728 register unsigned short pair;
1729 int n = count;
1731 /* write into a character/attribute pair */
1732 while (n-- > 0)
1734 pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
1735 src++;
1736 SLtt_reverse_video (pair >> 8); /* color change */
1737 *(p++) = pair & 0xff; /* character byte */
1738 *(p++) = Attribute_Byte; /* attribute byte */
1741 VioWrtCellStr ((PCH)Line_Buffer, (USHORT)(2 * count),
1742 (USHORT)Cursor_Row, (USHORT)Cursor_Col, 0);
1745 void SLtt_cls (void)
1747 SLtt_normal_video ();
1748 Line_Buffer [0] = ' '; Line_Buffer [1] = Attribute_Byte;
1749 VioScrollUp (0, 0, -1, -1, -1, (PCH)Line_Buffer, 0);
1752 void SLtt_putchar (char ch)
1754 unsigned short p, *pp;
1756 if (Current_Color) SLtt_normal_video ();
1757 os2_video_getxy (); /* get current position */
1759 switch (ch)
1761 case 7: /* ^G - break */
1762 SLtt_beep (); break;
1763 case 8: /* ^H - backspace */
1764 goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
1765 case 13: /* ^M - carriage return */
1766 goto_rc_abs (Cursor_Row, 0); break;
1767 default: /* write character to screen */
1768 VioWrtCharStrAtt (&ch, 1, Cursor_Row, Cursor_Col,
1769 (BYTE*)&Attribute_Byte, 0);
1770 goto_rc_abs (Cursor_Row, Cursor_Col + 1);
1774 void SLtt_get_screen_size (void)
1776 #ifdef __os2__
1777 # ifdef __IBMC__
1778 VIOMODEINFO vioModeInfo;
1779 # endif
1780 vioModeInfo.cb = sizeof(vioModeInfo);
1781 VioGetMode (&vioModeInfo, 0);
1782 SLtt_Screen_Cols = vioModeInfo.col;
1783 SLtt_Screen_Rows = vioModeInfo.row;
1784 #endif
1787 void SLtt_get_terminfo (void)
1789 SLtt_get_screen_size ();
1792 int SLtt_init_video (void)
1794 VIOINTENSITY RequestBlock;
1795 PTIB ptib;
1796 PPIB ppib;
1797 USHORT args[3] = { 6, 2, 1 };
1799 Cursor_Row = Cursor_Col = 0;
1801 IsColor = 1; /* is it really? */
1803 /* Enable high-intensity background colors */
1804 RequestBlock.cb = sizeof (RequestBlock);
1805 RequestBlock.type = 2; RequestBlock.fs = 1;
1806 VioSetState (&RequestBlock, 0); /* nop if !fullscreen */
1808 DosGetInfoBlocks (&ptib, &ppib);
1809 if ((ppib->pib_ultype) == 2) /* VIO */
1810 Blink_Killed = 1;
1811 else
1812 { /* Fullscreen */
1813 if (VioSetState (args, 0) == 0)
1814 Blink_Killed = 1;
1815 else
1816 Blink_Killed = 0;
1819 if (!Attribute_Byte)
1821 /* find the attribute currently under the cursor */
1822 USHORT len, r, c;
1824 len = 2;
1825 VioGetCurPos (&r, &c, 0);
1826 VioReadCellStr ((PCH)Line_Buffer, &len, r, c, 0);
1827 Attribute_Byte = Line_Buffer[1];
1829 SLtt_set_color (JNORMAL_COLOR, NULL,
1830 Color_Names[(Attribute_Byte) & 0xf],
1831 Color_Names[(Attribute_Byte) >> 4]);
1834 SLtt_Use_Ansi_Colors = IsColor;
1835 SLtt_get_screen_size ();
1836 SLtt_reset_scroll_region ();
1837 fixup_colors ();
1839 return 0;
1842 #endif /* OS2_VIDEO */
1843 /*}}}*/
1845 #ifdef WATCOM_VIDEO /*{{{*/
1847 # include <graph.h>
1848 # define int86 int386 /* simplify code writing */
1850 #include <dos.h>
1852 /* this is how to make a space character */
1853 #define MK_SPACE_CHAR() (((Attribute_Byte) << 8) | 0x20)
1855 /* buffer to hold a line of character/attribute pairs */
1856 #define MAXCOLS 256
1857 static unsigned char Line_Buffer [MAXCOLS*2];
1859 /* define for direct to memory screen writes */
1860 static unsigned char *Video_Base;
1861 #define MK_SCREEN_POINTER(row,col) \
1862 ((unsigned short *)(Video_Base + 2 * (SLtt_Screen_Cols * (row) + (col))))
1864 #define ScreenPrimary (0xb800 << 4)
1865 #define ScreenSize (SLtt_Screen_Cols * SLtt_Screen_Rows)
1866 #define ScreenSetCursor(x,y) _settextposition (x+1,y+1)
1868 void ScreenGetCursor (int *x, int *y)
1870 struct rccoord rc = _gettextposition ();
1871 *x = rc.row - 1;
1872 *y = rc.col - 1;
1875 void ScreenRetrieve (unsigned char *dest)
1877 memcpy (dest, (unsigned char *) ScreenPrimary, 2 * ScreenSize);
1880 void ScreenUpdate (unsigned char *src)
1882 memcpy ((unsigned char *) ScreenPrimary, src, 2 * ScreenSize);
1885 void SLtt_write_string (char *str)
1887 /* FIXME: Priority=medium
1888 * This should not go to stdout. */
1889 fputs (str, stdout);
1892 void SLtt_goto_rc (int row, int col)
1894 row += Scroll_r1;
1895 if (row > SLtt_Screen_Rows) row = SLtt_Screen_Rows;
1896 if (col > SLtt_Screen_Cols) col = SLtt_Screen_Cols;
1897 ScreenSetCursor(row, col);
1898 Cursor_Row = row;
1899 Cursor_Col = col;
1902 static void watcom_video_getxy (void)
1904 ScreenGetCursor (&Cursor_Row, &Cursor_Col);
1907 void SLtt_begin_insert (void)
1909 unsigned short *p;
1910 unsigned short *pmin;
1911 int n;
1913 watcom_video_getxy ();
1914 n = SLtt_Screen_Cols - Cursor_Col;
1916 p = MK_SCREEN_POINTER (Cursor_Row, SLtt_Screen_Cols - 1);
1917 pmin = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
1919 while (p-- > pmin) *(p + 1) = *p;
1922 void SLtt_end_insert (void)
1926 void SLtt_delete_char (void)
1928 unsigned short *p;
1929 register unsigned short *p1;
1930 int n;
1932 watcom_video_getxy ();
1933 n = SLtt_Screen_Cols - Cursor_Col - 1;
1935 p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
1936 while (n--)
1938 p1 = p + 1;
1939 *p = *p1;
1940 p++;
1944 void SLtt_erase_line (void)
1946 unsigned short w;
1947 unsigned short *p = MK_SCREEN_POINTER (Cursor_Row, 0);
1948 register unsigned short *pmax = p + SLtt_Screen_Cols;
1950 Attribute_Byte = 0x07;
1951 w = MK_SPACE_CHAR ();
1952 while (p < pmax) *p++ = w;
1953 Current_Color = JNO_COLOR; /* since we messed with attribute byte */
1956 void SLtt_delete_nlines (int nlines)
1958 union REGS r;
1960 SLtt_normal_video ();
1961 r.x.eax = nlines;
1962 r.x.ecx = 0;
1963 r.h.ah = 6;
1964 r.h.ch = Scroll_r1;
1965 r.h.dl = SLtt_Screen_Cols - 1;
1966 r.h.dh = Scroll_r2;
1967 r.h.bh = Attribute_Byte;
1968 int86 (0x10, &r, &r);
1971 void SLtt_reverse_index (int nlines)
1973 union REGS r;
1975 SLtt_normal_video ();
1976 r.h.al = nlines;
1977 r.x.ecx = 0;
1978 r.h.ah = 7;
1979 r.h.ch = Scroll_r1;
1980 r.h.dl = SLtt_Screen_Cols - 1;
1981 r.h.dh = Scroll_r2;
1982 r.h.bh = Attribute_Byte;
1983 int86 (0x10, &r, &r);
1986 static void watcom_video_invert_region (int top_row, int bot_row)
1988 unsigned char buf [2 * 180 * 80]; /* 180 cols x 80 rows */
1989 unsigned char *b, *bmax;
1991 b = buf + 1 + 2 * SLtt_Screen_Cols * top_row;
1992 bmax = buf + 1 + 2 * SLtt_Screen_Cols * bot_row;
1993 ScreenRetrieve (buf);
1994 while (b < bmax)
1996 *b ^= 0xFF;
1997 b += 2;
1999 ScreenUpdate (buf);
2002 void SLtt_beep (void)
2004 int audible; /* audible bell */
2005 int special = 0; /* first row to invert */
2006 int visual = 0; /* final row to invert */
2008 if (!SLtt_Ignore_Beep) return;
2010 audible = (SLtt_Ignore_Beep & 1);
2011 if ( (SLtt_Ignore_Beep & 4) )
2013 special = SLtt_Screen_Rows - 1;
2014 visual = special--; /* only invert bottom status line */
2016 else if ( (SLtt_Ignore_Beep & 2) )
2018 visual = SLtt_Screen_Rows;
2021 if (visual) watcom_video_invert_region (special, visual);
2022 if (audible) sound (1500); delay (100); if (audible) nosound ();
2023 if (visual) watcom_video_invert_region (special, visual);
2026 void SLtt_del_eol (void)
2028 unsigned short *p, *pmax;
2029 unsigned short w;
2030 int n;
2032 n = SLtt_Screen_Cols - Cursor_Col;
2033 p = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
2034 pmax = p + n;
2036 if (Current_Color != JNO_COLOR) SLtt_normal_video ();
2038 w = MK_SPACE_CHAR ();
2039 while (p < pmax) *p++ = w;
2042 static void
2043 write_attributes (SLsmg_Char_Type *src, unsigned int count)
2045 register unsigned short pair;
2046 register unsigned short *pos = MK_SCREEN_POINTER (Cursor_Row, 0);
2048 /* write into a character/attribute pair */
2049 while (count--)
2051 pair = SLSMG_CHAR_TO_USHORT(*src);/* character/color pair */
2052 src++;
2053 SLtt_reverse_video (pair >> 8); /* color change */
2054 *(pos++) = ((unsigned short) Attribute_Byte << 8) | (pair & 0xff);
2058 void SLtt_cls (void)
2060 SLtt_normal_video ();
2061 SLtt_reset_scroll_region ();
2062 SLtt_goto_rc (0, 0);
2063 SLtt_delete_nlines (SLtt_Screen_Rows);
2066 void SLtt_putchar (char ch)
2068 unsigned short p, *pp;
2070 if (Current_Color) SLtt_normal_video ();
2071 watcom_video_getxy ();
2072 switch (ch)
2074 case 7: /* ^G - break */
2075 SLtt_beep (); break;
2076 case 8: /* ^H - backspace */
2077 goto_rc_abs (Cursor_Row, Cursor_Col - 1); break;
2078 case 13: /* ^M - carriage return */
2079 goto_rc_abs (Cursor_Row, 0); break;
2080 default: /* write character to screen */
2081 p = (Attribute_Byte << 8) | (unsigned char) ch;
2082 pp = MK_SCREEN_POINTER (Cursor_Row, Cursor_Col);
2083 *pp = p;
2084 goto_rc_abs (Cursor_Row, Cursor_Col + 1);
2088 void SLtt_get_screen_size (void)
2090 struct videoconfig vc;
2091 _getvideoconfig(&vc);
2093 SLtt_Screen_Rows = vc.numtextrows;
2094 SLtt_Screen_Cols = vc.numtextcols;
2097 void SLtt_get_terminfo (void)
2099 SLtt_get_screen_size ();
2102 int SLtt_init_video (void)
2104 #ifdef HAS_SAVE_SCREEN
2105 save_screen ();
2106 #endif
2108 Cursor_Row = Cursor_Col = 0;
2109 Video_Base = (unsigned char *) ScreenPrimary;
2110 if (!Attribute_Byte) Attribute_Byte = 0x17;
2111 IsColor = 1; /* is it really? */
2113 if (IsColor)
2115 union REGS r;
2116 r.x.eax = 0x1003; r.x.ebx = 0;
2117 int86 (0x10, &r, &r);
2118 Blink_Killed = 1;
2121 SLtt_Use_Ansi_Colors = IsColor;
2122 SLtt_get_screen_size ();
2123 SLtt_reset_scroll_region ();
2124 fixup_colors ();
2126 return 0;
2129 #endif /* WATCOM_VIDEO */
2131 /*}}}*/
2133 /* -------------------------------------------------------------------------*\
2134 * The rest of the functions are, for the most part, independent of a specific
2135 * video system.
2136 \* ------------------------------------------------------------------------ */
2138 /*----------------------------------------------------------------------*\
2139 * Function: void SLtt_set_scroll_region (int r1, int r2);
2141 * define a scroll region of top_row to bottom_row
2142 \*----------------------------------------------------------------------*/
2143 void SLtt_set_scroll_region (int top_row, int bottom_row)
2145 Scroll_r1 = top_row;
2146 Scroll_r2 = bottom_row;
2149 /*----------------------------------------------------------------------*\
2150 * Function: void SLtt_reset_scroll_region (void);
2152 * reset the scrol region to be the entire screen,
2153 * ie, SLtt_set_scroll_region (0, SLtt_Screen_Rows);
2154 \*----------------------------------------------------------------------*/
2155 void SLtt_reset_scroll_region (void)
2157 Scroll_r1 = 0;
2158 Scroll_r2 = SLtt_Screen_Rows - 1;
2161 /*----------------------------------------------------------------------*\
2162 * Function: int SLtt_flush_output (void);
2163 \*----------------------------------------------------------------------*/
2164 int SLtt_flush_output (void)
2166 #if defined(WIN32_VIDEO)
2167 return 0;
2168 #else
2169 /* FIXME: Priority=medium
2170 * This should not go to stdout. */
2171 fflush (stdout);
2172 return 0;
2173 #endif
2176 int SLtt_set_cursor_visibility (int show)
2178 #if defined(WIN32_VIDEO)
2179 CONSOLE_CURSOR_INFO c;
2181 if (0 == GetConsoleCursorInfo (hStdout, &c))
2182 return -1;
2183 c.bVisible = (show ? TRUE: FALSE);
2184 if (0 == SetConsoleCursorInfo (hStdout, &c))
2185 return -1;
2186 return 0;
2187 #else
2188 (void) show;
2189 return -1;
2190 #endif
2193 /*----------------------------------------------------------------------*\
2194 * Function: void SLtt_reverse_video (int color);
2196 * set Attribute_Byte corresponding to COLOR.
2197 * Use Current_Color to remember the color which was set.
2198 * convert from the COLOR number to the attribute value.
2199 \*----------------------------------------------------------------------*/
2200 void SLtt_reverse_video (int color)
2202 if ((color >= JMAX_COLORS) || (color < 0))
2203 return;
2205 Attribute_Byte = Color_Map [color];
2206 Current_Color = color;
2209 /*----------------------------------------------------------------------*\
2210 * Function: void SLtt_normal_video (void);
2212 * reset the attributes for normal video
2213 \*----------------------------------------------------------------------*/
2214 void SLtt_normal_video (void)
2216 SLtt_reverse_video (JNORMAL_COLOR);
2219 /*----------------------------------------------------------------------*\
2220 * Function: void SLtt_smart_puts (SLsmg_Char_Type *new_string,
2221 * SLsmg_Char_Type *old_string,
2222 * int len, int row);
2224 * puts NEW_STRING, which has length LEN, at row ROW. NEW_STRING contains
2225 * characters/colors packed in the form value = ((color << 8) | (ch));
2227 * the puts tries to avoid overwriting the same characters/colors
2229 * OLD_STRING is not used, maintained for compatibility with other systems
2230 \*----------------------------------------------------------------------*/
2231 void SLtt_smart_puts (SLsmg_Char_Type *new_string,
2232 SLsmg_Char_Type *old_string,
2233 int len, int row)
2235 (void) old_string;
2236 Cursor_Row = row;
2237 Cursor_Col = 0;
2238 write_attributes (new_string, len);
2241 /*----------------------------------------------------------------------*\
2242 * Function: int SLtt_reset_video (void);
2243 \*----------------------------------------------------------------------*/
2244 #ifndef WIN32_VIDEO
2245 int SLtt_reset_video (void)
2247 SLtt_reset_scroll_region ();
2248 SLtt_goto_rc (SLtt_Screen_Rows - 1, 0);
2249 #ifdef HAS_SAVE_SCREEN
2250 restore_screen ();
2251 #endif
2252 Attribute_Byte = 0x07;
2253 Current_Color = JNO_COLOR;
2254 SLtt_del_eol ();
2255 return 0;
2257 #endif
2259 /*----------------------------------------------------------------------*\
2260 * Function: void SLtt_set_color (int obj, char *what, char *fg, char *bg);
2262 * set foreground and background colors of OBJ to the attributes which
2263 * correspond to the names FG and BG, respectively.
2265 * WHAT is the name corresponding to the object OBJ, but is not used in
2266 * this routine.
2267 \*----------------------------------------------------------------------*/
2268 void SLtt_set_color (int obj, char *what, char *fg, char *bg)
2270 int i, b = 0, f = 7;
2272 (void) what;
2274 if ((obj < 0) || (obj >= JMAX_COLORS))
2275 return;
2277 for (i = 0; i < JMAX_COLOR_NAMES; i++ )
2279 if (!strcmp (fg, Color_Names [i]))
2281 f = i;
2282 break;
2286 for (i = 0; i < JMAX_COLOR_NAMES; i++)
2288 if (!strcmp (bg, Color_Names [i]))
2290 if (Blink_Killed) b = i; else b = i & 0x7;
2291 break;
2294 if (f == b) return;
2296 Color_Map [obj] = (b << 4) | f;
2298 /* if we're setting the normal color, and the attribute byte hasn't
2299 been set yet, set it to the new color */
2300 if ((obj == 0) && (Attribute_Byte == 0))
2301 SLtt_reverse_video (0);
2303 if (_SLtt_color_changed_hook != NULL)
2304 (*_SLtt_color_changed_hook)();
2307 static void fixup_colors (void)
2309 unsigned int i;
2311 if (Blink_Killed)
2312 return;
2314 for (i = 0; i < JMAX_COLORS; i++)
2315 Color_Map[i] &= 0x7F;
2317 SLtt_normal_video ();
2321 /* FIXME!!! Add mono support.
2322 * The following functions have not been fully implemented.
2324 void SLtt_set_mono (int obj_unused, char *unused, SLtt_Char_Type c_unused)
2326 (void) obj_unused;
2327 (void) unused;
2328 (void) c_unused;
2331 #if 0
2332 void SLtt_add_color_attribute (int obj, SLtt_Char_Type attr)
2334 (void) obj;
2335 (void) attr;
2337 #endif