* weird code, so we have to convert it into an actual rate in bits per
* second.
*/
- if (!fp || tcgetattr(fileno(fp), &c))
- tty->baud = 0;
- else {
+ tty->baud = 0; tty->wd = tty->ht = 0;
+ if (fp && !tcgetattr(fileno(fp), &c)) {
code = cfgetospeed(&c);
for (b = baudtab; b->baud; b++)
if (b->code == code) { tty->baud = b->baud; goto found_baud; }
- tty->baud = 0;
found_baud:
tty_resized(tty);
}
if (acaps&TTACF_INVV) ff |= f&TTAF_INVV;
/* Foreground and background colours. */
- if (acaps&TTACF_FG) {
+ if (!(acaps&TTACF_FG))
+ a_out->fg = 0;
+ else {
clamp_colours(&t, &a_out->fg,
(f&TTAF_FGSPCMASK) >> TTAF_FGSPCSHIFT, a ? a->fg : 0,
acaps);
ff |= t << TTAF_FGSPCSHIFT;
}
- if (acaps&TTACF_BG) {
+ if (!(acaps&TTACF_BG))
+ a_out->bg = 0;
+ else {
clamp_colours(&t, &a_out->bg,
(f&TTAF_BGSPCMASK) >> TTAF_BGSPCSHIFT, a ? a->bg : 0,
acaps);
#undef DEF_BOOLCAP
#undef DEF_INTCAP
#undef DEF_STRCAP
+#define LEN_BOOLCAP(uix, info, cap)
+#define LEN_INTCAP(uix, info, cap)
+#define LEN_STRCAP(uix, info, cap) unsigned info##_cost;
+ ATTRCAPS(LEN_BOOLCAP, LEN_INTCAP, LEN_STRCAP)
+#undef LEN_BOOLCAP
+#undef LEN_INTCAP
+#undef LEN_STRCAP
};
#define TTY_CAPSPFX \
struct tty tty; \
#undef GETINT
#undef GETSTR
+#define COST_BOOLCAP(uix, info, cap_)
+#define COST_INTCAP(uix, info, cap_)
+#define COST_STRCAP(uix, info, cap_) \
+ if (!t->cap.info) t->cap.info##_cost = -1; \
+ else t->cap.info##_cost = \
+ strlen(tgoto(t->cap.info, 0, t->cap.colors - 1));
+ ATTRCAPS(COST_BOOLCAP, COST_INTCAP, COST_STRCAP)
+#undef COST_BOOLCAP
+#undef COST_INTCAP
+#undef COST_STRCAP
+
#define CLEAR_BOOL(uix, info, cap_) t->cap.info = 0;
#define CLEAR_INT(uix, info, cap_) t->cap.info = 0;
#define CLEAR_STR(uix, info, cap_) t->cap.info = 0;
-#define CLEAR_CAPS(caplist) \
+#define CLEARCAPS(caplist) \
do { caplist(CLEAR_BOOL, CLEAR_INT, CLEAR_STR) } while (0)
/* Basic capabilities. */
if (!t->cap.nel) t->cap.nel = "\r\n";
/* Attribute capabilities. */
- if (ops->cap.intcap(&t->tty, CAP_XMC) > 0 || !t->cap.sgr0)
- CLEAR_CAPS(ATTRCAPS);
+ if (ops->cap.intcap(&t->tty, CAP_XMC) > 0)
+ CLEARCAPS(ATTRCAPS);
else {
- if (t->cap.smul) t->tty.acaps |= TTACF_ULINE;
- if (t->cap.bold) t->tty.acaps |= TTACF_BOLD;
- if (t->cap.dim) t->tty.acaps |= TTACF_DIM;
- if (t->cap.sitm) t->tty.acaps |= TTACF_ITAL;
- if (t->cap.rev) t->tty.acaps |= TTACF_INVV;
-
- if (!t->cap.op || (!t->cap.setaf && !t->cap.setab))
- CLEAR_CAPS(COLOURCAPS);
- else {
+ if (t->cap.smul && (t->cap.rmul || t->cap.sgr0))
+ t->tty.acaps |= TTACF_ULINE;
+ if (t->cap.bold && t->cap.sgr0)
+ t->tty.acaps |= TTACF_BOLD;
+ if (t->cap.dim && t->cap.sgr0)
+ t->tty.acaps |= TTACF_DIM;
+ if (t->cap.sitm && (t->cap.ritm || t->cap.sgr0))
+ t->tty.acaps |= TTACF_ITAL;
+ if (t->cap.rev && t->cap.sgr0)
+ t->tty.acaps |= TTACF_INVV;
+
+ if ((t->cap.setaf || t->cap.setab) && (t->cap.op || t->cap.sgr0)) {
if (t->cap.setaf) t->tty.acaps |= TTACF_FG;
if (t->cap.setab) t->tty.acaps |= TTACF_BG;
t->tty.acaps |= TTACF_1BPC;
{ wd = ops->cap.intcap(&t->tty, CAP_WD); if (wd > 0) t->tty.wd = wd; }
if (!t->tty.ht)
{ ht = ops->cap.intcap(&t->tty, CAP_HT); if (ht > 0) t->tty.ht = ht; }
+
+#undef CLEAR_BOOL
+#undef CLEAR_INT
+#undef CLEAR_STR
+#undef CLEARCAPS
}
/* Macros for formatting capabilities. */
const struct tty_capops *ops = (const struct tty_capops *)t->tty.ops;
uint32 diff;
int rc;
+ unsigned c, z, f = 0;
+#define f_clrall 1u
/* Work out what needs doing. */
diff = a->f ^ t->tty.st.attr.f;
* to do that, we need to restore the other active attributes, so we must
* check up front.
*/
- if (((diff&TTAF_LNMASK) && !(a->f&TTAF_LNMASK) && !t->cap.rmul) ||
- ((diff&TTAF_WTMASK) && !(a->f&TTAF_WTMASK)) ||
- ((diff&~a->f&TTAF_ITAL) && !t->cap.ritm) ||
- (diff&~a->f&TTAF_INVV))
- { PUT0(0, sgr0); diff = a->f; }
+
+ c = 0;
+#define CLEARP(mask) ((diff&(mask)) && !(a->f&(mask)))
+#define ADDCOST(cap_) do { \
+ if (t->cap.cap_) c += t->cap.cap_##_cost; \
+ else f |= f_clrall; \
+} while (0)
+ if (CLEARP(TTAF_LNMASK)) ADDCOST(rmul);
+ if (CLEARP(TTAF_WTMASK)) f |= f_clrall;
+ if (diff&~a->f&TTAF_INVV) f |= f_clrall;
+ if (diff&~a->f&TTAF_ITAL) ADDCOST(ritm);
+ if (CLEARP(TTAF_FGSPCMASK) || CLEARP(TTAF_BGSPCMASK)) ADDCOST(op);
+#undef CLEARP
+#undef ADDCOST
+
+ z = 0;
+ switch ((a->f&TTAF_LNMASK) >> TTAF_LNSHIFT) {
+ case TTLN_ULINE: z += t->cap.smul_cost; break;
+ }
+ switch ((a->f&TTAF_WTMASK) >> TTAF_WTSHIFT) {
+ case TTWT_BOLD: z += t->cap.bold_cost; break;
+ case TTWT_DIM: z += t->cap.dim_cost; break;
+ }
+ if (a->f&TTAF_INVV) z += t->cap.rev_cost;
+ if (a->f&TTAF_ITAL) z += t->cap.sitm_cost;
+ if (a->f&TTAF_FGSPCMASK) z += t->cap.setaf_cost;
+ if (a->f&TTAF_BGSPCMASK) z += t->cap.setab_cost;
+
+ if ((t->cap.sgr0 && z + t->cap.sgr0_cost < c) || (f&f_clrall))
+ { PUT0(0, sgr0); diff = a->f; t->tty.st.attr.fg = t->tty.st.attr.bg; }
/* Line style. */
if (diff&TTAF_LNMASK)
}
/* Other text effects. */
+ if (diff&a->f&TTAF_INVV) PUT0(0, rev);
if (diff&TTAF_ITAL) {
if (a->f&TTAF_ITAL) PUT0(0, sitm);
else PUT0(0, ritm);
}
- if (diff&a->f&TTAF_INVV) PUT0(0, rev);
/* Colours. */
if (((diff&TTAF_FGSPCMASK) && !(a->f&TTAF_FGSPCMASK)) ||
rc = 0;
end:
t->tty.st.attr = *a; return (rc);
+
+#undef f_clrall
}
static int caps_setattr(struct tty *tty,
PUTLIT("\33[");
- if (z <= c)
+ if (z < c || (c && !(t->ansi.f&TAF_CNCATTR)))
{ SEMI; diff = a->f; t->tty.st.attr.fg = t->tty.st.attr.bg = 0; }
if (diff&TTAF_LNMASK)
}
}
-
int tty_resized(struct tty *tty)
{
struct winsize ws;