void redraw_screen(struct terminal *term) { int x, y, p = 0; int cx = term->lcx, cy = term->lcy; unsigned char *a; int attrib = -1; int mode = -1; int l = 0; struct term_spec *s; if (!term->dirty || (term->master && is_blocked())) return; a = init_str(); s = term->spec; for (y = 0; y < term->y; y++) for (x = 0; x < term->x; x++, p++) { if (y == term->y - 1 && x == term->x - 1) break; if (term->screen[p] == term->last_screen[p]) continue; if ((term->screen[p] & 0x3800) == (term->last_screen[p] & 0x3800) && ((term->screen[p] & 0xff) == 0 || (term->screen[p] & 0xff) == 1 || (term->screen[p] & 0xff) == ' ') && ((term->last_screen[p] & 0xff) == 0 || (term->last_screen[p] & 0xff) == 1 || (term->last_screen[p] & 0xff) == ' ') && (x != term->cx || y != term->cy)) continue; term->last_screen[p] = term->screen[p]; if (cx == x && cy == y) goto pc;/*PRINT_CHAR(p)*/ else if (cy == y && x - cx < 10 && x - cx > 0) { int i; for (i = x - cx; i >= 0; i--) PRINT_CHAR(p - i); } else { add_to_str(&a, &l, "\033["); add_num_to_str(&a, &l, y + 1); add_to_str(&a, &l, ";"); add_num_to_str(&a, &l, x + 1); add_to_str(&a, &l, "H"); cx = x; cy = y; pc: PRINT_CHAR(p); } } if (l) { if (s->col) add_to_str(&a, &l, "\033[37;40m"); add_to_str(&a, &l, "\033[0m"); if (s->mode == TERM_LINUX && s->m11_hack) add_to_str(&a, &l, "\033[10m"); if (s->mode == TERM_VT100) add_to_str(&a, &l, "\x0f"); } term->lcx = cx; term->lcy = cy; if (term->cx != term->lcx || term->cy != term->lcy) { term->lcx = term->cx; term->lcy = term->cy; add_to_str(&a, &l, "\033["); add_num_to_str(&a, &l, term->cy + 1); add_to_str(&a, &l, ";"); add_num_to_str(&a, &l, term->cx + 1); add_to_str(&a, &l, "H"); } if (l && term->master) want_draw(); hard_write(term->fdout, a, l); if (l && term->master) done_draw(); mem_free(a); term->dirty = 0; }
int _doprnt (const char *format, va_list ap, FILE *stream) { const char * ptr = format; char specifier[128]; int total_printed = 0; while (*ptr != '\0') { if (*ptr != '%') /* While we have regular characters, print them. */ PRINT_CHAR(*ptr); else /* We got a format specifier! */ { char * sptr = specifier; int wide_width = 0, short_width = 0; *sptr++ = *ptr++; /* Copy the % and move forward. */ while (strchr ("-+ #0", *ptr)) /* Move past flags. */ *sptr++ = *ptr++; if (*ptr == '*') COPY_VA_INT; else while (ISDIGIT(*ptr)) /* Handle explicit numeric value. */ *sptr++ = *ptr++; if (*ptr == '.') { *sptr++ = *ptr++; /* Copy and go past the period. */ if (*ptr == '*') COPY_VA_INT; else while (ISDIGIT(*ptr)) /* Handle explicit numeric value. */ *sptr++ = *ptr++; } while (strchr ("hlL", *ptr)) { switch (*ptr) { case 'h': short_width = 1; break; case 'l': wide_width++; break; case 'L': wide_width = 2; break; default: abort(); } *sptr++ = *ptr++; } switch (*ptr) { case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': case 'c': { /* Short values are promoted to int, so just copy it as an int and trust the C library printf to cast it to the right width. */ if (short_width) PRINT_TYPE(int); else { switch (wide_width) { case 0: PRINT_TYPE(int); break; case 1: PRINT_TYPE(long); break; case 2: default: #if defined(__GNUC__) || defined(HAVE_LONG_LONG) PRINT_TYPE(long long); #else PRINT_TYPE(long); /* Fake it and hope for the best. */ #endif break; } /* End of switch (wide_width) */ } /* End of else statement */ } /* End of integer case */ break; case 'f': case 'e': case 'E': case 'g': case 'G': { if (wide_width == 0) PRINT_TYPE(double); else { #if defined(__GNUC__) || defined(HAVE_LONG_DOUBLE) PRINT_TYPE(long double); #else PRINT_TYPE(double); /* Fake it and hope for the best. */ #endif } } break; case 's': PRINT_TYPE(char *); break; case 'p': PRINT_TYPE(void *); break; case '%': PRINT_CHAR('%'); break; default: abort(); } /* End of switch (*ptr) */ } /* End of else statement */ } return total_printed; }