/****************************************************************************** * This file is part of a software distribution, which is furnished under the * * terms of a license. Use of this software by any means is subject to this * * license and signifies the acceptance of the licensing terms stated * * therein. Please see the file LICENSE in the top-level directory of this * * software distribution for detailed copyright disclaimers and licensing * * terms. * ****************************************************************************** * Copryight (c) by Andreas S. Wetzel - All rights reserved. * ******************************************************************************/ /* $Id: screen.c,v 1.2 2001/03/19 14:54:01 mickey Exp $ */ #include #include #include /*** Globals ***/ #define PADTIME 1 int in_chat_window = 0; /*** Externals ***/ extern char nlstr[]; extern VP vp; extern ED *ed; extern VTCAP vtcap; /*** Code ***/ void screen_init(void) { vlock(LOCK, (V_IO | V_TIMER | V_WINCH)); cls(); update_status(1); scroll_reg(1, vtcap.rows - 2); mv(1, vtcap.rows); in_chat_window = 0; vlock(UNLOCK, (V_IO | V_TIMER | V_WINCH)); } void cprintf(int win, char *fmt, ...) { va_list ap; u_int strindex; u_int space; u_int in_line; u_int wrapdist; u_int indent; int fg; int bg; unsigned char c; unsigned char x; unsigned char tmp[SVMSGBUF]; /* * Lockout all signals that may annoy us here */ vlock(LOCK, (V_IO | V_TIMER | V_WINCH)); pbc_disable(); va_start(ap, fmt); vsprintf(tmp, fmt, ap); tmp[SVMSGBUF - 1] = '\0'; /* * Compute number of * columns to indent */ strindex = wrapdist = space = in_line = indent = 0; if(vp.indent && tmp[0] == '(') { int i; int flg = 0; int sz = 1; for(i = 1; i < 20; i++) { if(tmp[i] == ')') /*** LEFT BRACKET ***/ { ++sz; flg |= 0x01; } else if(tmp[i] == CSI) /*** CSI ***/ { flg |= 0x02; } else if(flg & 0x02) /*** TEXT ATTRIBUTE ***/ { flg &= ~0x02; } else if(tmp[i] == ' ' && flg) /*** FINAL SPACE ***/ { indent = ++sz; break; } else if(tmp[i] == ' ' || tmp[i] == '\n' || tmp[i] == '\0') { sz = 0; break; } else /*** TEXT ***/ { ++sz; flg &= ~0x01; } } } /* * Do word wrapping */ if(vp.word_wrap && win == chat) { strindex = in_line = space = wrapdist = 0; while(tmp[strindex] != '\0') { switch(tmp[strindex]) { case CSI: strindex += 2; break; case ' ': space = strindex++; wrapdist = 0; ++in_line; break; case '\n': space = wrapdist = 0; in_line = indent; ++strindex; break; default: ++strindex; ++in_line; ++wrapdist; break; } /* * Will we have to wrap the line? */ if(in_line > (vtcap.cols - 1)) { /* * If we have a space in the current line * and the distance of the space relative * to the current position is less or equal * than one third of the total columns of * a display line, wrap this line at the * space. Otherwise simply break the line * at the current position. */ if(space > 0 && wrapdist <= (vtcap.cols / 3)) { tmp[space] = '\n'; in_line = (wrapdist + indent); } else { wrapdist = in_line = 0; } space = 0; } } } strindex = 0; /* * Output string in window */ if(win == chat) { if(!in_chat_window) { mv(1, vtcap.rows - 2); in_chat_window = 0xff; } printf("%s", nlstr); if(vp.logswitch) { fprintf(vp.logfl, "%s", nlstr); vp.logcnt += strlen(nlstr); } } while((c = tmp[strindex++]) != '\0') { switch(c) { case CSI: x = tmp[strindex++]; if((fg = (x >= C_FG_BLK && x <= C_FG_WHT) ? (x - C_FG_BLK) : -1) != -1) { if(HAS_COLOR) { if(vtcap.bold && vp.hicolor) tputs(vtcap.bold, 1, (void *)outc); printf("%s", tparm(vtcap.set_fg_color, fg)); } else { switch(fg) { case 2: if(vtcap.dim) tputs(vtcap.dim, 1, (void *)outc); else if(vtcap.bold) tputs(vtcap.bold, 1, (void *)outc); break; case 3: if(vtcap.bold) tputs(vtcap.bold, 1, (void *)outc); else if(vtcap.underline) tputs(vtcap.underline, 1, (void *)outc); break; default: break; } } } else if((bg = (x >= C_BG_BLK && x <= C_BG_WHT) ? (x - C_BG_BLK) : -1) != -1) { if(HAS_COLOR) { if(vtcap.bold && vp.hicolor) tputs(vtcap.bold, 1, (void *)outc); printf("%s", tparm(vtcap.set_bg_color, bg)); } else { if(bg == 4) { if(vtcap.reverse) tputs(vtcap.reverse, 1, (void *)outc); } } } else if(x == C_OFF && vtcap.off) tputs(vtcap.off, 1, (void *)outc); else if(x == C_BOLD && vtcap.bold) tputs(vtcap.bold, 1, (void *)outc); else if(x == C_UL && vtcap.underline) tputs(vtcap.underline, 1, (void *)outc); else if(x == C_DIM && vtcap.dim) tputs(vtcap.dim, 1, (void *)outc); else if(x == C_BLINK && vtcap.blink) tputs(vtcap.blink, 1, (void *)outc); break; case '\n': printf("%s", nlstr); if(vp.logswitch && win == chat) { fprintf(vp.logfl, "%s", nlstr); vp.logcnt += strlen(nlstr); fflush(vp.logfl); } vsleep(0, PADTIME); if(tmp[strindex] != '\0' && indent) { printf("%*s", indent, " "); if(vp.logswitch && win == chat) { fprintf(vp.logfl, "%*s", indent, " "); vp.logcnt += indent; } } break; default: putchar(c); if(vp.logswitch && win == chat) { fprintf(vp.logfl, "%c", c); ++vp.logcnt; } break; } } pbc_enable(); va_end(ap); /* * Release locked out signals */ vlock(UNLOCK, (V_IO | V_TIMER | V_WINCH)); if(vp.logswitch) fflush(vp.logfl); } void cputnchars(u_char *buf, size_t size) { u_int strindex; u_int space; u_int in_line; u_int wrapdist; u_int indent = 0; int fg; int bg; unsigned char c; unsigned char x; /* * Lockout all signals that may annoy us here */ vlock(LOCK, (V_IO | V_TIMER | V_WINCH)); pbc_disable(); /* * Compute number of * columns to indent */ strindex = in_line = indent = 0; if(vp.indent && *buf == '(') { int i; u_char sz = 1; u_char flg = 0; for(i = 1; i < (size <= 20) ? size : 20; i++) { if(*(buf + i) == ')') /*** LEFT BRACKET ***/ { ++sz; flg |= 0x01; } else if(*(buf + i) == CSI) /*** CSI ***/ { flg |= 0x02; } else if(flg & 0x02) /*** TEXT ATTRIBUTE ***/ { flg &= ~0x02; } else if(*(buf + i) == ' ' && flg) /*** FINAL SPACE ***/ { indent = ++sz; break; } else if(*(buf + i) == ' ' || *(buf + i) == '\n' || *(buf + i) == '\0') { sz = 0; break; } else /*** TEXT ***/ { ++sz; flg &= ~0x01; } } } /* * Do word wrapping */ if(vp.word_wrap) { strindex = in_line = space = wrapdist = 0; while(strindex < size) { switch(*(buf + strindex)) { case CSI: strindex += 2; break; case ' ': space = strindex++; wrapdist = 0; ++in_line; break; case '\n': space = wrapdist = 0; in_line = indent; ++strindex; break; default: ++strindex; ++in_line; ++wrapdist; break; } /* * Will we have to wrap the line at this point? */ if(in_line > (vtcap.cols - 1)) { /* * If we have a space in the current line * and the distance of the space relative * to the current position is less or equal * than one third of the total columns of * a display line, wrap this line at the * space. Otherwise simply break the line * at the current position. */ if(space > 0 && wrapdist <= (vtcap.cols / 3)) { *(buf + space) = '\n'; in_line = (wrapdist + indent); } else { wrapdist = in_line = 0; } space = 0; } } } strindex = 0; /* * Output string in window */ if(!in_chat_window) { mv(1, vtcap.rows - 2); in_chat_window = 0xff; } printf("%s", nlstr); if(vp.logswitch) { fprintf(vp.logfl, "%s", nlstr); vp.logcnt += strlen(nlstr); } while(strindex < size) { c = *(buf + strindex++); switch(c) { case CSI: x = *(buf + strindex++); if((fg = (x >= C_FG_BLK && x <= C_FG_WHT) ? (x - C_FG_BLK) : -1) != -1) { if(HAS_COLOR) { if(vtcap.bold && vp.hicolor) tputs(vtcap.bold, 1, (void *)outc); tputs(tparm(vtcap.set_fg_color, fg), 1, (void *)outc); } else { switch(fg) { case 2: if(vtcap.dim) tputs(vtcap.dim, 1, (void *)outc); else if(vtcap.bold) tputs(vtcap.bold, 1, (void *)outc); break; case 3: if(vtcap.bold) tputs(vtcap.bold, 1, (void *)outc); else if(vtcap.underline) tputs(vtcap.underline, 1, (void *)outc); break; default: break; } } } else if((bg = (x >= C_BG_BLK && x <= C_BG_WHT) ? (x - C_BG_BLK) : -1) != -1) { if(HAS_COLOR) { if(vtcap.bold && vp.hicolor) tputs(vtcap.bold, 1, (void *)outc); tputs(tparm(vtcap.set_bg_color, bg), 1, (void *)outc); } else { if(bg == 4) { if(vtcap.reverse) tputs(vtcap.reverse, 1, (void *)outc); } } } else if(x == C_OFF && vtcap.off) tputs(vtcap.off, 1, (void *)outc); else if(x == C_BOLD && vtcap.bold) tputs(vtcap.bold, 1, (void *)outc); else if(x == C_UL && vtcap.underline) tputs(vtcap.underline, 1, (void *)outc); else if(x == C_DIM && vtcap.dim) tputs(vtcap.dim, 1, (void *)outc); else if(x == C_BLINK && vtcap.blink) tputs(vtcap.blink, 1, (void *)outc); break; case '\n': printf("%s", nlstr); if(vp.logswitch) { fprintf(vp.logfl, "%s", nlstr); vp.logcnt += strlen(nlstr); fflush(vp.logfl); } vsleep(0, PADTIME); if(strindex < size && indent) { printf("%*s", indent, " "); if(vp.logswitch) { fprintf(vp.logfl, "%*s", indent, " "); vp.logcnt += indent; } } break; default: putchar(c); if(vp.logswitch) { fprintf(vp.logfl, "%c", c); ++vp.logcnt; } break; } } pbc_enable(); /* * Release locked out signals */ vlock(UNLOCK, (V_IO | V_TIMER | V_WINCH)); if(vp.logswitch) fflush(vp.logfl); } int real_len(char *s) { int ret = 0; u_char c; while((c = *s++) != '\0') { if(c == CSI) { ++s; } else { ++ret; } } return(ret); } /* * * Low level screen functions * */ int outc(u_char x) { putchar(x); return(0); } void mv(int x, int y) { --x; --y; tputs((char *)tgoto(vtcap.pos, x, y), 1, (void *)outc); } void cls(void) { tputs(vtcap.cls, 1, (void *)outc); } void keymode(int which) { if(vtcap.ck_app && vtcap.ck_pos) { switch(which) { case 0x1: tputs(vtcap.ck_app, 1, (void *)outc); break; default: tputs(vtcap.ck_pos, 1, (void *)outc); break; } } } void scroll_reg(int start, int ende) { --start; --ende; printf("%s", tparm(vtcap.scr_reg, start, ende)); } void put_back_cursor(void) { vlock(LOCK, (V_IO | V_TIMER | V_WINCH)); pbc_disable(); if(in_chat_window) { mv(ED_SCRPOS, vtcap.rows); in_chat_window = 0; } vlock(UNLOCK, (V_IO | V_TIMER | V_WINCH)); } void clear_input(void) { vlock(LOCK, (V_IO | V_TIMER | V_WINCH)); mv(1, vtcap.rows); in_chat_window = 0; if(vtcap.clear2eol) tputs(vtcap.clear2eol, 1, (void *)outc); else if(vtcap.clear2eod) tputs(vtcap.clear2eod, 1, (void *)outc); vlock(UNLOCK, (V_IO | V_TIMER | V_WINCH)); }