coreboot-kgpe-d16/payloads/libpayload/curses/PDCurses-3.4/os2/pdcscrn.c
Patrick Georgi 3b77b723ca libpayload: Add PDCurses and ncurses' libform/libmenu
PDCurses provides an alternative implementation of the curses library
standard in addition to tinycurses.
Where tinycurses is really tiny, PDCurses is more complete and provides
virtually unlimited windows and the full API.
The PDCurses code is brought in "vanilla", with all local changes
residing in curses/pdcurses-backend/

In addition to a curses library, this change also provides libpanel (as
part of the PDCurses code), and libform and libmenu which were derived
from ncurses-5.9.
As they rely on ncurses internals (and PDCurses is not ncurses), more
changes were required for these libraries to work.

The build system is extended to install the right set of header files
depending on the selected curses implementation.

Change-Id: I9e5b920f94b6510da01da2f656196a993170d1c5
Signed-off-by: Patrick Georgi <patrick.georgi@secunet.com>
Reviewed-on: http://review.coreboot.org/106
Tested-by: build bot (Jenkins)
Reviewed-by: Marc Jones <marcj303@gmail.com>
2011-08-04 08:10:41 +02:00

422 lines
8.7 KiB
C

/* Public Domain Curses */
#include "pdcos2.h"
RCSID("$Id: pdcscrn.c,v 1.76 2008/07/14 04:24:51 wmcbrine Exp $")
#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_font; /* default font size */
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
};
#ifdef EMXVIDEO
static unsigned char *saved_screen = NULL;
static int saved_lines = 0;
static int saved_cols = 0;
#else
# ifdef PDCTHUNK
# ifdef __EMX__
# define THUNKEDVIO VIOCOLORREG
# else
typedef struct {
USHORT cb;
USHORT type;
USHORT firstcolorreg;
USHORT numcolorregs;
ptr_16 colorregaddr;
} THUNKEDVIO;
# endif
# endif
static PCH saved_screen = NULL;
static USHORT saved_lines = 0;
static USHORT saved_cols = 0;
static VIOMODEINFO scrnmode; /* default screen mode */
static VIOMODEINFO saved_scrnmode[3];
static int saved_font[3];
static bool can_change = FALSE;
static int _get_font(void)
{
VIOMODEINFO modeInfo = {0};
modeInfo.cb = sizeof(modeInfo);
VioGetMode(&modeInfo, 0);
return (modeInfo.vres / modeInfo.row);
}
static void _set_font(int size)
{
VIOMODEINFO modeInfo = {0};
if (pdc_font != size)
{
modeInfo.cb = sizeof(modeInfo);
/* set most parameters of modeInfo */
VioGetMode(&modeInfo, 0);
modeInfo.cb = 8; /* ignore horiz an vert resolution */
modeInfo.row = modeInfo.vres / size;
VioSetMode(&modeInfo, 0);
}
curs_set(SP->visibility);
pdc_font = _get_font();
}
#endif
/* close the physical screen -- may restore the screen to its state
before PDC_scr_open(); miscellaneous cleanup */
void PDC_scr_close(void)
{
PDC_LOG(("PDC_scr_close() - called\n"));
if (saved_screen && getenv("PDC_RESTORE_SCREEN"))
{
#ifdef EMXVIDEO
v_putline(saved_screen, 0, 0, saved_lines * saved_cols);
#else
VioWrtCellStr(saved_screen, saved_lines * saved_cols * 2,
0, 0, (HVIO)NULL);
#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)
{
#ifdef EMXVIDEO
int adapter;
#else
USHORT totchars;
#endif
int i;
short r, g, b;
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;
#ifdef EMXVIDEO
v_init();
#endif
SP->orig_attr = FALSE;
#ifdef EMXVIDEO
adapter = v_hardware();
SP->mono = (adapter == V_MONOCHROME);
pdc_font = SP->mono ? 14 : (adapter == V_COLOR_8) ? 8 : 12;
#else
VioGetMode(&scrnmode, 0);
PDC_get_keyboard_info();
pdc_font = _get_font();
#endif
SP->lines = PDC_get_rows();
SP->cols = PDC_get_columns();
SP->mouse_wait = PDC_CLICK_PERIOD;
SP->audible = TRUE;
/* This code for preserving the current screen */
if (getenv("PDC_RESTORE_SCREEN"))
{
saved_lines = SP->lines;
saved_cols = SP->cols;
saved_screen = malloc(2 * saved_lines * saved_cols);
if (!saved_screen)
{
SP->_preserve = FALSE;
return OK;
}
#ifdef EMXVIDEO
v_getline(saved_screen, 0, 0, saved_lines * saved_cols);
#else
totchars = saved_lines * saved_cols * 2;
VioReadCellStr((PCH)saved_screen, &totchars, 0, 0, (HVIO)NULL);
#endif
}
SP->_preserve = (getenv("PDC_PRESERVE_SCREEN") != NULL);
can_change = (PDC_color_content(0, &r, &g, &b) == OK);
return OK;
}
/* the core of resize_term() */
int PDC_resize_screen(int nlines, int ncols)
{
#ifndef EMXVIDEO
VIOMODEINFO modeInfo = {0};
USHORT result;
#endif
PDC_LOG(("PDC_resize_screen() - called. Lines: %d Cols: %d\n",
nlines, ncols));
#ifdef EMXVIDEO
return ERR;
#else
modeInfo.cb = sizeof(modeInfo);
/* set most parameters of modeInfo */
VioGetMode(&modeInfo, 0);
modeInfo.fbType = 1;
modeInfo.row = nlines;
modeInfo.col = ncols;
result = VioSetMode(&modeInfo, 0);
LINES = PDC_get_rows();
COLS = PDC_get_columns();
return (result == 0) ? OK : ERR;
#endif
}
void PDC_reset_prog_mode(void)
{
PDC_LOG(("PDC_reset_prog_mode() - called.\n"));
#ifndef EMXVIDEO
PDC_set_keyboard_binary(TRUE);
#endif
}
void PDC_reset_shell_mode(void)
{
PDC_LOG(("PDC_reset_shell_mode() - called.\n"));
#ifndef EMXVIDEO
PDC_set_keyboard_default();
#endif
}
#ifndef EMXVIDEO
static bool _screen_mode_equals(VIOMODEINFO *oldmode)
{
VIOMODEINFO current = {0};
VioGetMode(&current, 0);
return ((current.cb == oldmode->cb) &&
(current.fbType == oldmode->fbType) &&
(current.color == oldmode->color) &&
(current.col == oldmode->col) &&
(current.row == oldmode->row) &&
(current.hres == oldmode->vres) &&
(current.vres == oldmode->vres));
}
#endif
void PDC_restore_screen_mode(int i)
{
#ifndef EMXVIDEO
if (i >= 0 && i <= 2)
{
pdc_font = _get_font();
_set_font(saved_font[i]);
if (!_screen_mode_equals(&saved_scrnmode[i]))
if (VioSetMode(&saved_scrnmode[i], 0) != 0)
{
pdc_font = _get_font();
scrnmode = saved_scrnmode[i];
LINES = PDC_get_rows();
COLS = PDC_get_columns();
}
}
#endif
}
void PDC_save_screen_mode(int i)
{
#ifndef EMXVIDEO
if (i >= 0 && i <= 2)
{
saved_font[i] = pdc_font;
saved_scrnmode[i] = scrnmode;
}
#endif
}
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;
}
bool PDC_can_change_color(void)
{
return can_change;
}
int PDC_color_content(short color, short *red, short *green, short *blue)
{
#ifdef PDCTHUNK
THUNKEDVIO vcr;
USHORT palbuf[4];
unsigned char pal[3];
int rc;
/* Read single DAC register */
palbuf[0] = 8;
palbuf[1] = 0;
palbuf[2] = curstoreal[color];
rc = VioGetState(&palbuf, 0);
if (rc)
return ERR;
vcr.cb = sizeof(vcr);
vcr.type = 3;
vcr.firstcolorreg = palbuf[3];
vcr.numcolorregs = 1;
vcr.colorregaddr = PDCTHUNK(pal);
rc = VioGetState(&vcr, 0);
if (rc)
return ERR;
/* Scale and store */
*red = DIVROUND((unsigned)(pal[0]) * 1000, 63);
*green = DIVROUND((unsigned)(pal[1]) * 1000, 63);
*blue = DIVROUND((unsigned)(pal[2]) * 1000, 63);
return OK;
#else
return ERR;
#endif
}
int PDC_init_color(short color, short red, short green, short blue)
{
#ifdef PDCTHUNK
THUNKEDVIO vcr;
USHORT palbuf[4];
unsigned char pal[3];
int rc;
/* Scale */
pal[0] = DIVROUND((unsigned)red * 63, 1000);
pal[1] = DIVROUND((unsigned)green * 63, 1000);
pal[2] = DIVROUND((unsigned)blue * 63, 1000);
/* Set single DAC register */
palbuf[0] = 8;
palbuf[1] = 0;
palbuf[2] = curstoreal[color];
rc = VioGetState(&palbuf, 0);
if (rc)
return ERR;
vcr.cb = sizeof(vcr);
vcr.type = 3;
vcr.firstcolorreg = palbuf[3];
vcr.numcolorregs = 1;
vcr.colorregaddr = PDCTHUNK(pal);
rc = VioSetState(&vcr, 0);
return rc ? ERR : OK;
#else
return ERR;
#endif
}