Change-Id: If881ec130833c7e7e62caa3d31e350a531f5bc8e Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Reviewed-on: http://review.coreboot.org/12398 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
		
			
				
	
	
		
			423 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			423 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(¤t, 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
 | |
| }
 |