aboutsummaryrefslogtreecommitdiff
path: root/payloads/libpayload/curses/PDCurses-3.4/dos/pdcscrn.c
diff options
context:
space:
mode:
Diffstat (limited to 'payloads/libpayload/curses/PDCurses-3.4/dos/pdcscrn.c')
-rw-r--r--payloads/libpayload/curses/PDCurses-3.4/dos/pdcscrn.c757
1 files changed, 757 insertions, 0 deletions
diff --git a/payloads/libpayload/curses/PDCurses-3.4/dos/pdcscrn.c b/payloads/libpayload/curses/PDCurses-3.4/dos/pdcscrn.c
new file mode 100644
index 0000000000..ddfb095677
--- /dev/null
+++ b/payloads/libpayload/curses/PDCurses-3.4/dos/pdcscrn.c
@@ -0,0 +1,757 @@
+/* Public Domain Curses */
+
+#include "pdcdos.h"
+
+RCSID("$Id: pdcscrn.c,v 1.89 2008/07/13 16:08:17 wmcbrine Exp $")
+
+#include <stdlib.h>
+
+#ifdef CHTYPE_LONG
+# define PDC_OFFSET 32
+#else
+# define PDC_OFFSET 8
+#endif
+
+/* COLOR_PAIR to attribute encoding table. */
+
+unsigned char *pdc_atrtab = (unsigned char *)NULL;
+
+int pdc_adapter; /* screen type */
+int pdc_scrnmode; /* default screen mode */
+int pdc_font; /* default font size */
+bool pdc_direct_video; /* allow direct screen memory writes */
+bool pdc_bogus_adapter; /* TRUE if adapter has insane values */
+unsigned pdc_video_seg; /* video base segment */
+unsigned pdc_video_ofs; /* video base offset */
+
+static short curstoreal[16], realtocurs[16] =
+{
+ COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN, COLOR_RED,
+ COLOR_MAGENTA, COLOR_YELLOW, COLOR_WHITE, COLOR_BLACK + 8,
+ COLOR_BLUE + 8, COLOR_GREEN + 8, COLOR_CYAN + 8, COLOR_RED + 8,
+ COLOR_MAGENTA + 8, COLOR_YELLOW + 8, COLOR_WHITE + 8
+};
+
+static bool sizeable = FALSE; /* TRUE if adapter is resizeable */
+
+static unsigned short *saved_screen = NULL;
+static int saved_lines = 0;
+static int saved_cols = 0;
+
+static int saved_scrnmode[3];
+static int saved_font[3];
+
+/* Thanks to Jeff Duntemann, K16RA for providing the impetus
+ (through the Dr. Dobbs Journal, March 1989 issue) for getting
+ the routines below merged into Bjorn Larsson's PDCurses 1.3...
+ -- frotz@dri.com 900730 */
+
+/* _get_font() - Get the current font size */
+
+static int _get_font(void)
+{
+ int retval;
+
+ retval = getdosmemword(0x485);
+
+ /* Assume the MDS Genius is in 66 line mode. */
+
+ if ((retval == 0) && (pdc_adapter == _MDS_GENIUS))
+ retval = _FONT15;
+
+ switch (pdc_adapter)
+ {
+ case _MDA:
+ retval = 10; /* POINTS is not certain on MDA/Hercules */
+ break;
+
+ case _EGACOLOR:
+ case _EGAMONO:
+ switch (retval)
+ {
+ case _FONT8:
+ case _FONT14:
+ break;
+ default:
+ retval = _FONT14;
+ }
+ break;
+
+ case _CGA:
+ retval = _FONT8;
+ }
+
+ return retval;
+}
+
+/* _set_font() - Sets the current font size, if the adapter allows such a
+ change. It is an error to attempt to change the font size on a
+ "bogus" adapter. The reason for this is that we have a known video
+ adapter identity problem. e.g. Two adapters report the same identifying
+ characteristics. */
+
+static void _set_font(int size)
+{
+ PDCREGS regs;
+
+ if (pdc_bogus_adapter)
+ return;
+
+ switch (pdc_adapter)
+ {
+ case _CGA:
+ case _MDA:
+ case _MCGACOLOR:
+ case _MCGAMONO:
+ case _MDS_GENIUS:
+ break;
+
+ case _EGACOLOR:
+ case _EGAMONO:
+ if (sizeable && (pdc_font != size))
+ {
+ switch (size)
+ {
+ case _FONT8:
+ regs.W.ax = 0x1112;
+ regs.h.bl = 0x00;
+ PDCINT(0x10, regs);
+ break;
+ case _FONT14:
+ regs.W.ax = 0x1111;
+ regs.h.bl = 0x00;
+ PDCINT(0x10, regs);
+ }
+ }
+ break;
+
+ case _VGACOLOR:
+ case _VGAMONO:
+ if (sizeable && (pdc_font != size))
+ {
+ switch (size)
+ {
+ case _FONT8:
+ regs.W.ax = 0x1112;
+ regs.h.bl = 0x00;
+ PDCINT(0x10, regs);
+ break;
+ case _FONT14:
+ regs.W.ax = 0x1111;
+ regs.h.bl = 0x00;
+ PDCINT(0x10, regs);
+ break;
+ case _FONT16:
+ regs.W.ax = 0x1114;
+ regs.h.bl = 0x00;
+ PDCINT(0x10, regs);
+ }
+ }
+ }
+
+ curs_set(SP->visibility);
+
+ pdc_font = _get_font();
+}
+
+/* _set_80x25() - force a known screen state: 80x25 text mode. Forces the
+ appropriate 80x25 alpha mode given the display adapter. */
+
+static void _set_80x25(void)
+{
+ PDCREGS regs;
+
+ switch (pdc_adapter)
+ {
+ case _CGA:
+ case _EGACOLOR:
+ case _EGAMONO:
+ case _VGACOLOR:
+ case _VGAMONO:
+ case _MCGACOLOR:
+ case _MCGAMONO:
+ regs.h.ah = 0x00;
+ regs.h.al = 0x03;
+ PDCINT(0x10, regs);
+ break;
+ case _MDA:
+ regs.h.ah = 0x00;
+ regs.h.al = 0x07;
+ PDCINT(0x10, regs);
+ }
+}
+
+/* _get_scrn_mode() - Return the current BIOS video mode */
+
+static int _get_scrn_mode(void)
+{
+ PDCREGS regs;
+
+ regs.h.ah = 0x0f;
+ PDCINT(0x10, regs);
+
+ return (int)regs.h.al;
+}
+
+/* _set_scrn_mode() - Sets the BIOS Video Mode Number only if it is
+ different from the current video mode. */
+
+static void _set_scrn_mode(int new_mode)
+{
+ PDCREGS regs;
+
+ if (_get_scrn_mode() != new_mode)
+ {
+ regs.h.ah = 0;
+ regs.h.al = (unsigned char) new_mode;
+ PDCINT(0x10, regs);
+ }
+
+ pdc_font = _get_font();
+ pdc_scrnmode = new_mode;
+ LINES = PDC_get_rows();
+ COLS = PDC_get_columns();
+}
+
+/* _sanity_check() - A video adapter identification sanity check. This
+ routine will force sane values for various control flags. */
+
+static int _sanity_check(int adapter)
+{
+ int fontsize = _get_font();
+ int rows = PDC_get_rows();
+
+ PDC_LOG(("_sanity_check() - called: Adapter %d\n", adapter));
+
+ switch (adapter)
+ {
+ case _EGACOLOR:
+ case _EGAMONO:
+ switch (rows)
+ {
+ case 25:
+ case 43:
+ break;
+ default:
+ pdc_bogus_adapter = TRUE;
+ }
+
+ switch (fontsize)
+ {
+ case _FONT8:
+ case _FONT14:
+ break;
+ default:
+ pdc_bogus_adapter = TRUE;
+ }
+ break;
+
+ case _VGACOLOR:
+ case _VGAMONO:
+ break;
+
+ case _CGA:
+ case _MDA:
+ case _MCGACOLOR:
+ case _MCGAMONO:
+ switch (rows)
+ {
+ case 25:
+ break;
+ default:
+ pdc_bogus_adapter = TRUE;
+ }
+ break;
+
+ default:
+ pdc_bogus_adapter = TRUE;
+ }
+
+ if (pdc_bogus_adapter)
+ {
+ sizeable = FALSE;
+ pdc_direct_video = FALSE;
+ }
+
+ return adapter;
+}
+
+/* _query_adapter_type() - Determine PC video adapter type. */
+
+static int _query_adapter_type(void)
+{
+ PDCREGS regs;
+ int retval = _NONE;
+
+ /* thanks to paganini@ax.apc.org for the GO32 fix */
+
+#if !defined(__DJGPP__) && !defined(__WATCOMC__)
+ struct SREGS segs;
+#endif
+ short video_base = getdosmemword(0x463);
+
+ PDC_LOG(("_query_adapter_type() - called\n"));
+
+ /* attempt to call VGA Identify Adapter Function */
+
+ regs.W.ax = 0x1a00;
+ PDCINT(0x10, regs);
+
+ if ((regs.h.al == 0x1a) && (retval == _NONE))
+ {
+ /* We know that the PS/2 video BIOS is alive and well. */
+
+ switch (regs.h.al)
+ {
+ case 0:
+ retval = _NONE;
+ break;
+ case 1:
+ retval = _MDA;
+ break;
+ case 2:
+ retval = _CGA;
+ break;
+ case 4:
+ retval = _EGACOLOR;
+ sizeable = TRUE;
+ break;
+ case 5:
+ retval = _EGAMONO;
+ break;
+ case 26: /* ...alt. VGA BIOS... */
+ case 7:
+ retval = _VGACOLOR;
+ sizeable = TRUE;
+ break;
+ case 8:
+ retval = _VGAMONO;
+ break;
+ case 10:
+ case 13:
+ retval = _MCGACOLOR;
+ break;
+ case 12:
+ retval = _MCGAMONO;
+ break;
+ default:
+ retval = _CGA;
+ }
+ }
+ else
+ {
+ /* No VGA BIOS, check for an EGA BIOS by selecting an
+ Alternate Function Service...
+
+ bx == 0x0010 --> return EGA information */
+
+ regs.h.ah = 0x12;
+ regs.W.bx = 0x10;
+ PDCINT(0x10, regs);
+
+ if ((regs.h.bl != 0x10) && (retval == _NONE))
+ {
+ /* An EGA BIOS exists */
+
+ regs.h.ah = 0x12;
+ regs.h.bl = 0x10;
+ PDCINT(0x10, regs);
+
+ if (regs.h.bh == 0)
+ retval = _EGACOLOR;
+ else
+ retval = _EGAMONO;
+ }
+ else if (retval == _NONE)
+ {
+ /* Now we know we only have CGA or MDA */
+
+ PDCINT(0x11, regs);
+
+ switch (regs.h.al & 0x30)
+ {
+ case 0x10:
+ case 0x20:
+ retval = _CGA;
+ break;
+ case 0x30:
+ retval = _MDA;
+ break;
+ default:
+ retval = _NONE;
+ }
+ }
+ }
+
+ if (video_base == 0x3d4)
+ {
+ pdc_video_seg = 0xb800;
+ switch (retval)
+ {
+ case _EGAMONO:
+ retval = _EGACOLOR;
+ break;
+ case _VGAMONO:
+ retval = _VGACOLOR;
+ }
+ }
+
+ if (video_base == 0x3b4)
+ {
+ pdc_video_seg = 0xb000;
+ switch (retval)
+ {
+ case _EGACOLOR:
+ retval = _EGAMONO;
+ break;
+ case _VGACOLOR:
+ retval = _VGAMONO;
+ }
+ }
+
+ if ((retval == _NONE)
+#ifndef CGA_DIRECT
+ || (retval == _CGA)
+#endif
+ )
+ pdc_direct_video = FALSE;
+
+ if ((unsigned)pdc_video_seg == 0xb000)
+ SP->mono = TRUE;
+ else
+ SP->mono = FALSE;
+
+ /* Check for DESQview shadow buffer
+ thanks to paganini@ax.apc.org for the GO32 fix */
+
+#ifndef __WATCOMC__
+ regs.h.ah = 0xfe;
+ regs.h.al = 0;
+ regs.x.di = pdc_video_ofs;
+# ifdef __DJGPP__
+ regs.x.es = pdc_video_seg;
+ __dpmi_int(0x10, &regs);
+ pdc_video_seg = regs.x.es;
+# else
+ segs.es = pdc_video_seg;
+ int86x(0x10, &regs, &regs, &segs);
+ pdc_video_seg = segs.es;
+# endif
+ pdc_video_ofs = regs.x.di;
+#endif
+ if (!pdc_adapter)
+ pdc_adapter = retval;
+
+ return _sanity_check(retval);
+}
+
+/* close the physical screen -- may restore the screen to its state
+ before PDC_scr_open(); miscellaneous cleanup */
+
+void PDC_scr_close(void)
+{
+#if SMALL || MEDIUM
+# ifndef __PACIFIC__
+ struct SREGS segregs;
+# endif
+ int ds;
+#endif
+ PDC_LOG(("PDC_scr_close() - called\n"));
+
+ if (getenv("PDC_RESTORE_SCREEN") && saved_screen)
+ {
+#ifdef __DJGPP__
+ dosmemput(saved_screen, saved_lines * saved_cols * 2,
+ (unsigned long)_FAR_POINTER(pdc_video_seg,
+ pdc_video_ofs));
+#else
+# if (SMALL || MEDIUM)
+# ifdef __PACIFIC__
+ ds = FP_SEG((void far *)saved_screen);
+# else
+ segread(&segregs);
+ ds = segregs.ds;
+# endif
+ movedata(ds, (int)saved_screen, pdc_video_seg, pdc_video_ofs,
+ (saved_lines * saved_cols * 2));
+# else
+ memcpy((void *)_FAR_POINTER(pdc_video_seg, pdc_video_ofs),
+ (void *)saved_screen, (saved_lines * saved_cols * 2));
+# endif
+#endif
+ free(saved_screen);
+ saved_screen = NULL;
+ }
+
+ reset_shell_mode();
+
+ if (SP->visibility != 1)
+ curs_set(1);
+
+ /* Position cursor to the bottom left of the screen. */
+
+ PDC_gotoyx(PDC_get_rows() - 2, 0);
+}
+
+void PDC_scr_free(void)
+{
+ if (SP)
+ free(SP);
+ if (pdc_atrtab)
+ free(pdc_atrtab);
+
+ pdc_atrtab = (unsigned char *)NULL;
+}
+
+/* open the physical screen -- allocate SP, miscellaneous intialization,
+ and may save the existing screen for later restoration */
+
+int PDC_scr_open(int argc, char **argv)
+{
+#if SMALL || MEDIUM
+# ifndef __PACIFIC__
+ struct SREGS segregs;
+# endif
+ int ds;
+#endif
+ int i;
+
+ PDC_LOG(("PDC_scr_open() - called\n"));
+
+ SP = calloc(1, sizeof(SCREEN));
+ pdc_atrtab = calloc(PDC_COLOR_PAIRS * PDC_OFFSET, 1);
+
+ if (!SP || !pdc_atrtab)
+ return ERR;
+
+ for (i = 0; i < 16; i++)
+ curstoreal[realtocurs[i]] = i;
+
+ SP->orig_attr = FALSE;
+
+ pdc_direct_video = TRUE; /* Assume that we can */
+ pdc_video_seg = 0xb000; /* Base screen segment addr */
+ pdc_video_ofs = 0x0; /* Base screen segment ofs */
+
+ pdc_adapter = _query_adapter_type();
+ pdc_scrnmode = _get_scrn_mode();
+ pdc_font = _get_font();
+
+ SP->lines = PDC_get_rows();
+ SP->cols = PDC_get_columns();
+
+ SP->mouse_wait = PDC_CLICK_PERIOD;
+ SP->audible = TRUE;
+
+ /* If the environment variable PDCURSES_BIOS is set, the DOS int10()
+ BIOS calls are used in place of direct video memory access. */
+
+ if (getenv("PDCURSES_BIOS"))
+ pdc_direct_video = FALSE;
+
+ /* This code for preserving the current screen. */
+
+ if (getenv("PDC_RESTORE_SCREEN"))
+ {
+ saved_lines = SP->lines;
+ saved_cols = SP->cols;
+
+ saved_screen = malloc(saved_lines * saved_cols * 2);
+
+ if (!saved_screen)
+ {
+ SP->_preserve = FALSE;
+ return OK;
+ }
+#ifdef __DJGPP__
+ dosmemget((unsigned long)_FAR_POINTER(pdc_video_seg, pdc_video_ofs),
+ saved_lines * saved_cols * 2, saved_screen);
+#else
+# if SMALL || MEDIUM
+# ifdef __PACIFIC__
+ ds = FP_SEG((void far *) saved_screen);
+# else
+ segread(&segregs);
+ ds = segregs.ds;
+# endif
+ movedata(pdc_video_seg, pdc_video_ofs, ds, (int)saved_screen,
+ (saved_lines * saved_cols * 2));
+# else
+ memcpy((void *)saved_screen,
+ (void *)_FAR_POINTER(pdc_video_seg, pdc_video_ofs),
+ (saved_lines * saved_cols * 2));
+# endif
+#endif
+ }
+
+ SP->_preserve = (getenv("PDC_PRESERVE_SCREEN") != NULL);
+
+ return OK;
+}
+
+/* the core of resize_term() */
+
+int PDC_resize_screen(int nlines, int ncols)
+{
+ PDC_LOG(("PDC_resize_screen() - called. Lines: %d Cols: %d\n",
+ nlines, ncols));
+
+ /* Trash the stored value of orig_cursor -- it's only good if the
+ video mode doesn't change */
+
+ SP->orig_cursor = 0x0607;
+
+ switch (pdc_adapter)
+ {
+ case _EGACOLOR:
+ if (nlines >= 43)
+ _set_font(_FONT8);
+ else
+ _set_80x25();
+ break;
+
+ case _VGACOLOR:
+ if (nlines > 28)
+ _set_font(_FONT8);
+ else
+ if (nlines > 25)
+ _set_font(_FONT14);
+ else
+ _set_80x25();
+ }
+
+ PDC_set_blink(COLORS == 8);
+
+ return OK;
+}
+
+void PDC_reset_prog_mode(void)
+{
+ PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
+}
+
+void PDC_reset_shell_mode(void)
+{
+ PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
+}
+
+void PDC_restore_screen_mode(int i)
+{
+ if (i >= 0 && i <= 2)
+ {
+ pdc_font = _get_font();
+ _set_font(saved_font[i]);
+
+ if (_get_scrn_mode() != saved_scrnmode[i])
+ _set_scrn_mode(saved_scrnmode[i]);
+ }
+}
+
+void PDC_save_screen_mode(int i)
+{
+ if (i >= 0 && i <= 2)
+ {
+ saved_font[i] = pdc_font;
+ saved_scrnmode[i] = pdc_scrnmode;
+ }
+}
+
+void PDC_init_pair(short pair, short fg, short bg)
+{
+ unsigned char att, temp_bg;
+ chtype i;
+
+ fg = curstoreal[fg];
+ bg = curstoreal[bg];
+
+ for (i = 0; i < PDC_OFFSET; i++)
+ {
+ att = fg | (bg << 4);
+
+ if (i & (A_REVERSE >> PDC_ATTR_SHIFT))
+ att = bg | (fg << 4);
+ if (i & (A_UNDERLINE >> PDC_ATTR_SHIFT))
+ att = 1;
+ if (i & (A_INVIS >> PDC_ATTR_SHIFT))
+ {
+ temp_bg = att >> 4;
+ att = temp_bg << 4 | temp_bg;
+ }
+ if (i & (A_BOLD >> PDC_ATTR_SHIFT))
+ att |= 8;
+ if (i & (A_BLINK >> PDC_ATTR_SHIFT))
+ att |= 128;
+
+ pdc_atrtab[pair * PDC_OFFSET + i] = att;
+ }
+}
+
+int PDC_pair_content(short pair, short *fg, short *bg)
+{
+ *fg = realtocurs[pdc_atrtab[pair * PDC_OFFSET] & 0x0F];
+ *bg = realtocurs[(pdc_atrtab[pair * PDC_OFFSET] & 0xF0) >> 4];
+
+ return OK;
+}
+
+/* _egapal() - Find the EGA palette value (0-63) for the color (0-15).
+ On VGA, this is an index into the DAC. */
+
+static short _egapal(short color)
+{
+ PDCREGS regs;
+
+ regs.W.ax = 0x1007;
+ regs.h.bl = curstoreal[color];
+
+ PDCINT(0x10, regs);
+
+ return regs.h.bh;
+}
+
+bool PDC_can_change_color(void)
+{
+ return (pdc_adapter == _VGACOLOR);
+}
+
+/* These are only valid when pdc_adapter == _VGACOLOR */
+
+int PDC_color_content(short color, short *red, short *green, short *blue)
+{
+ PDCREGS regs;
+
+ /* Read single DAC register */
+
+ regs.W.ax = 0x1015;
+ regs.h.bl = _egapal(color);
+
+ PDCINT(0x10, regs);
+
+ /* Scale and store */
+
+ *red = DIVROUND((unsigned)(regs.h.dh) * 1000, 63);
+ *green = DIVROUND((unsigned)(regs.h.ch) * 1000, 63);
+ *blue = DIVROUND((unsigned)(regs.h.cl) * 1000, 63);
+
+ return OK;
+}
+
+int PDC_init_color(short color, short red, short green, short blue)
+{
+ PDCREGS regs;
+
+ /* Scale */
+
+ regs.h.dh = DIVROUND((unsigned)red * 63, 1000);
+ regs.h.ch = DIVROUND((unsigned)green * 63, 1000);
+ regs.h.cl = DIVROUND((unsigned)blue * 63, 1000);
+
+ /* Set single DAC register */
+
+ regs.W.ax = 0x1010;
+ regs.W.bx = _egapal(color);
+
+ PDCINT(0x10, regs);
+
+ return OK;
+}