/******************************************************************************
* 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 <vchat.h>
#include <proto_common.h>
#include <sys/ioctl.h>
/*** 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));
}
syntax highlighted by Code2HTML, v. 0.9.1