/* 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 }