void _change_color(short newcolor, int (*outc)(char)) { #ifndef PC6300PLUS { _Color_pair *ptp = cur_term->_pairs_tbl; /* pairs table pointer */ _Color_pair *cur_pair = &cur_term->_cur_pair; /* MORE: we may have to change some stuff, depending on whether */ /* HP terminals will be changing the background, or not */ if (newcolor == 0) { if (orig_pair) (void) tputs(tparm_p0(orig_pair), 1, outc); if (set_a_background || set_a_foreground || set_background || set_foreground) { cur_pair->background = -1; cur_pair->foreground = -1; } return; } /* if we are on HP type terminal, just send an escape sequence */ /* to use desired color pair (we could have done some optimization: */ /* check if both the foreground and background of newcolor match */ /* the ones of cur_term->_cur_pair. but that will happen only when */ /* two color pairs are defined exacly the same, and probably not */ /* worth the effort). */ if (set_color_pair) (void) tputs(tparm_p1(set_color_pair, newcolor), 1, outc); /* on Tek model we can do some optimization. */ else { if (ptp[newcolor].background != cur_pair->background) { if (set_a_background) (void) tputs(tparm_p1(set_a_background, ptp[newcolor].background), 1, outc); else if (set_background) (void) tputs(tparm_p1(set_background, Oldcolors[ptp[newcolor].background]), 1, outc); cur_pair->background = ptp[newcolor].background; } if (ptp[newcolor].foreground != cur_pair->foreground) { if (set_a_foreground) (void) tputs(tparm_p1(set_a_foreground, ptp[newcolor].foreground), 1, outc); else if (set_foreground) (void) tputs(tparm_p1(set_foreground, Oldcolors[ptp[newcolor].foreground]), 1, outc); cur_pair->foreground = ptp[newcolor].foreground; } } } #else { /* the following code is for PC6300 PLUS: it uses BOLD terminfo */ /* entry for turning on colors, and SGR0 for turning them off. */ /* Every time a new color-pair is used, we are forced to do an */ /* ioctl read, and the send 'enter_bold_mode' escape sequence. */ /* This could be improved by using */ /* DIM, UNDERLINE, and REVERSE in addition to BOLD */ struct console con; _Color_pair *ptp = cur_term->_pairs_tbl; /* pairs table pointer */ back = ptp[newcolor].background; fore = ptp[newcolor].foreground; (void) fflush(SP->term_file); ioctl(cur_term->Filedes, CONIOGETDATA, &con); #define BOLD 4 con.l[con.page].colors[BOLD] = ((back + back + (fore > 5)) * 8 + fore) & 0177; ioctl(cur_term->Filedes, CONIOSETDATA, &con); (void) tputs(enter_bold_mode, 1, outc); } #endif }
int wrefresh(WINDOW *win) { short *bnsch, *ensch; SLK_MAP *slk; int wx, wy, nc, boty, clby, idby, *hs, curwin; curwin = (win == curscr); /* don't allow curscr refresh if the screen was just created */ if (curwin && curscr->_sync) return (OK); /* go thru _stdbody */ if (!curwin && (win != _virtscr)) (void) wnoutrefresh(win); /* if there is typeahead */ if ((_INPUTPENDING = _chkinput()) == TRUE) { if (curwin) curscr->_clear = TRUE; return (OK); } if (curwin || curscr->_clear) _virtscr->_clear = TRUE; /* save curscr cursor coordinates */ cy = curscr->_cury; cx = curscr->_curx; /* to simplify code in some cases */ marks = _MARKS; color_marks = _COLOR_MARKS; scrli = curscr->_maxy; scrco = curscr->_maxx; slk = SP->slk; outchcount = 0; /* make sure we're in program mode */ if (SP->fl_endwin) { /* If endwin is equal to 2 it means we just did a newscreen. */ if (SP->fl_endwin == TRUE) { (void) reset_prog_mode(); if (SP->kp_state) (void) tputs(keypad_xmit, 1, _outch); if (slk) (*_do_slk_tch)(); if (SP->fl_meta) (void) tputs(meta_on, 1, _outch); if (cur_term->_cursorstate != 1) _PUTS(cur_term->cursor_seq[cur_term-> _cursorstate], 0); } _PUTS(enter_ca_mode, 1); (void) tputs(ena_acs, 1, _outch); if (exit_attribute_mode) _PUTS(tparm_p0(exit_attribute_mode), 1); else /* * If there is no exit_attribute mode, then vidupdate * could only possibly turn off one of the below three * so that's all we ask it turn off. */ vidupdate(A_NORMAL, (A_ALTCHARSET | A_STANDOUT | A_UNDERLINE), _outch); SP->fl_endwin = FALSE; #ifdef _VR2_COMPAT_CODE _endwin = (char) FALSE; #endif /* _VR2_COMPAT_CODE */ } /* clear the screen if required */ if (_virtscr->_clear) { /* SS: colors */ if (back_color_erase) _turn_off_background(); _PUTS(clear_screen, scrli); cy = cx = curscr->_curx = curscr->_cury = 0; /* _sync indicates that this a new screen */ if (!curscr->_sync) (void) werase(curscr); else { nc = scrco / BITSPERBYTE - (scrco % BITSPERBYTE ? 0 : 1); wy = scrli - 1; bnsch = _BEGNS; ensch = _ENDNS; hs = _CURHASH; for (; wy >= 0; --wy) { *bnsch++ = scrco; *ensch++ = -1; *hs++ = 0; if (marks) for (wx = nc; wx >= 0; --wx) marks[wy][wx] = 0; } } _virtscr->_clear = curscr->_sync = curscr->_clear = FALSE; if (slk) (*_do_slk_tch)(); /* pretend _virtscr has been totally changed */ (void) wtouchln(_virtscr, 0, scrli, -1); _VIRTTOP = 0; _VIRTBOT = scrli - 1; /* will not do clear-eod or ins/del lines */ clby = idby = scrli; } else clby = idby = -1; /* Software soft labels; if _changed == 2, slk's are in clear mode. */ if (slk && slk->_win && (slk->_changed == TRUE)) (*_do_slk_noref)(); /* do line updating */ _virtscr->_clear = FALSE; wy = _VIRTTOP; boty = _VIRTBOT + 1; bnsch = _virtscr->_firstch + wy; ensch = _virtscr->_lastch + wy; for (; wy < boty; ++wy, ++bnsch, ++ensch) { /* this line is up-to-date */ if (*bnsch >= scrco) goto next; /* there is type-ahead */ if (!curwin && (_INPUTPENDING = _chkinput()) == TRUE) { /* LINTED */ _VIRTTOP = (short) wy; goto done; } if (clby < 0) { /* now we have to work, check for ceod */ clby = _getceod(wy, boty); /* check for insert/delete lines */ if (_virtscr->_use_idl) idby = (*_setidln)(); } /* try clear-to-eod */ if (wy == clby) _useceod(wy, boty); /* try ins/del lines */ if (wy == idby) { curscr->_cury = cy; curscr->_curx = cx; (*_useidln)(); cy = curscr->_cury; cx = curscr->_curx; } if (*bnsch < scrco) _updateln(wy); next: *bnsch = _INFINITY; *ensch = -1; } /* do hardware soft labels; if _changed == 2, */ /* slk's are in clear mode. */ if (slk && (slk->_changed == TRUE) && !(slk->_win)) (*_do_slk_ref)(); /* move cursor */ wy = _virtscr->_cury; wx = _virtscr->_curx; if (wy != cy || wx != cx) { (void) mvcur(cy, cx, wy, wx); /* LINTED */ cy = (short) wy; /* LINTED */ cx = (short) wx; } /* reset the flags */ curscr->_clear = FALSE; _virtscr->_use_idl = FALSE; _virtscr->_use_idc = TRUE; _INPUTPENDING = FALSE; /* virtual image is now up-to-date */ _VIRTTOP = scrli; _VIRTBOT = -1; done : curscr->_cury = cy; curscr->_curx = cx; (void) fflush(SP->term_file); return (outchcount); }
int _change_video(chtype newmode, chtype oldmode, int (*outc)(char)) { int rc = 0; /* If you have set_attributes let the terminfo writer */ /* worry about it. */ if (!set_attributes) { /* * The trick is that we want to pre-process the new and oldmode * so that we now know what they will really translate to on * the physical screen. * In the case where some attributes are being faked * we get rid of the attributes being asked for and just have * STANDOUT mode set. Therefore, if STANDOUT and UNDERLINE were * on the screen but UNDERLINE was being faked to STANDOUT; and * the new mode is just UNDERLINE, we will get rid of any faked * modes and be left with and oldmode of STANDOUT and a new mode * of STANDOUT, in which case the check for newmode and oldmode * being equal will be true. * * * This test is similar to the concept explained above. * counter is the maximum attributes allowed on a terminal. * For instance, on an hp/tvi950 without set_attributes * the last video sequence sent will be the one the terminal * will be in (on that spot). Therefore, in setupterm.c * if ceol_standout_glitch or magic_cookie_glitch is set * max_attributes is set to 1. This is because on those terminals * only one attribute can be on at once. So, we pre-process the * oldmode and the newmode and only leave the bits that are * significant. In other words, if on an hp you ask for STANDOUT * and UNDERLINE it will become only STANDOUT since that is the * first bit that is looked at. If then the user goes from * STANDOUT and UNDERLINE to STANDOUT and REVERSE the oldmode will * become STANDOUT and the newmode will become STANDOUT. * * This also helps the code below in that on a hp or tvi950 only * one bit will ever be set so that no code has to be added to * cut out early in case two attributes were asked for. */ chtype check_faked, modes[2]; int counter = max_attributes, i, j, tempmode; int k = (cur_term->sgr_mode == oldmode) ? 1 : 2; modes[0] = newmode; modes[1] = oldmode; while (k-- > 0) { if ((check_faked = (modes[k] & cur_term->sgr_faked)) != A_NORMAL) { modes[k] &= ~check_faked; modes[k] |= A_STANDOUT; } if ((j = counter) >= 0) { tempmode = A_NORMAL; if (j > 0) { for (i = 0; i < NUM_ATTRIBUTES; i++) { if (modes[k] & bit_attributes[i]) { tempmode |= bit_attributes[i]; if (--j == 0) break; } } } modes[k] = tempmode; } } newmode = modes[0]; oldmode = modes[1]; } if (newmode == oldmode) return (rc); #ifdef DEBUG if (outf) fprintf(outf, "vidupdate oldmode=%o, newmode=%o\n", oldmode, newmode); #endif if (set_attributes) { (void) tputs(tparm(set_attributes, newmode & A_STANDOUT, newmode & A_UNDERLINE, newmode & A_REVERSE, newmode & A_BLINK, newmode & A_DIM, newmode & A_BOLD, newmode & A_INVIS, newmode & A_PROTECT, newmode & A_ALTCHARSET), 1, outc); rc = -1; } else { chtype turn_on, turn_off; int i; /* * If we are going to turn something on anyway and we are * on a glitchy terminal, don't bother turning it off * since by turning something on you turn everything else off. */ if ((ceol_standout_glitch || magic_cookie_glitch >= 0) && ((turn_on = ((oldmode ^ newmode) & newmode)) != A_NORMAL)) { goto turn_on_code; } if ((turn_off = (oldmode & newmode) ^ oldmode) != A_NORMAL) { /* * Check for things to turn off. * First see if we are going to turn off something * that doesn't have a specific turn off capability. * * Then check to see if, even though there may be a specific * turn off sequence, this terminal doesn't have one or * the turn off sequence also turns off something else. */ if ((turn_off & ~(A_ALTCHARSET | A_STANDOUT | A_UNDERLINE)) || (turn_off != (turn_off & cur_term->check_turn_off))) { (void) tputs(tparm_p0(exit_attribute_mode), 1, outc); rc = -1; oldmode = A_NORMAL; } else { for (i = 0; i < NUM_OF_SPECIFIC_TURN_OFFS; i++) { if (turn_off & bit_attributes[i]) { (void) tputs(tparm_p0 (cur_term->turn_off_seq[i]), 1, outc); oldmode &= ~bit_attributes[i]; rc = -1; } } } } if ((turn_on = ((oldmode ^ newmode) & newmode)) != A_NORMAL) { turn_on_code: /* Check for modes to turn on. */ for (i = 0; i < NUM_ATTRIBUTES; i++) if (turn_on & bit_attributes[i]) { (void) tputs(tparm_p0(cur_term->turn_on_seq[i]), 1, outc); rc = -1; /* * Keep turning off the bit(s) that we just * sent to the screen. As soon as turn_on * reaches A_NORMAL we don't have to turn * anything else on and we can * break out of the loop. */ if ((turn_on &= ~bit_attributes[i]) == A_NORMAL) break; } } if (magic_cookie_glitch > 0) (void) tputs(cursor_left, 1, outc); } cur_term->sgr_mode = newmode; return (rc); }