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