#include <xterm.h>
#include <data.h>
#include <fontutils.h>
#include <assert.h>
#define WhichCgsId(flag) (((flag) & BOLD) ? gcCBold : gcCNorm)
#define curChrSet SCRN_BUF_CSETS(screen, screen->cur_row)[0]
#if OPT_DEC_CHRSET
static void
repaint_line(XtermWidget xw, unsigned newChrSet)
{
register TScreen *screen = &xw->screen;
int curcol = screen->cur_col;
int currow = screen->cur_row;
unsigned len = MaxCols(screen);
int width = len;
unsigned oldChrSet = SCRN_BUF_CSETS(screen, currow)[0];
assert(width > 0);
if (oldChrSet == newChrSet)
return;
TRACE(("repaint_line(%2d,%2d) (%s -> %s)\n", currow, screen->cur_col,
visibleChrsetName(oldChrSet),
visibleChrsetName(newChrSet)));
HideCursor();
if (CSET_DOUBLE(newChrSet)) {
width /= 2;
if (curcol > width)
curcol = width;
}
ClearCurBackground(xw,
CursorY(screen, currow),
CurCursorX(screen, currow, 0),
(unsigned) FontHeight(screen),
len * CurFontWidth(screen, currow));
memset(SCRN_BUF_CSETS(screen, currow), (Char) newChrSet, len);
set_cur_col(screen, 0);
ScrnUpdate(xw, currow, 0, 1, (int) len, True);
set_cur_col(screen, curcol);
}
#endif
void
xterm_DECDHL(XtermWidget xw GCC_UNUSED, Bool top)
{
#if OPT_DEC_CHRSET
repaint_line(xw, (unsigned) (top ? CSET_DHL_TOP : CSET_DHL_BOT));
#else
(void) top;
#endif
}
void
xterm_DECSWL(XtermWidget xw GCC_UNUSED)
{
#if OPT_DEC_CHRSET
repaint_line(xw, CSET_SWL);
#endif
}
void
xterm_DECDWL(XtermWidget xw GCC_UNUSED)
{
#if OPT_DEC_CHRSET
repaint_line(xw, CSET_DWL);
#endif
}
#if OPT_DEC_CHRSET
static void
discard_font(XtermWidget xw, int n)
{
TScreen *screen = &xw->screen;
XTermFonts *data = &(screen->double_fonts[n]);
TRACE(("discard_font chrset=%d %s\n", data->chrset,
(data->fn != 0) ? data->fn : "<no-name>"));
data->chrset = 0;
data->flags = 0;
if (data->fn != 0) {
free(data->fn);
data->fn = 0;
}
(void) xtermCloseFont(xw, data);
screen->fonts_used -= 1;
while (n < screen->fonts_used) {
screen->double_fonts[n] = screen->double_fonts[n + 1];
++n;
}
}
static XTermFonts *
pushback_font(XtermWidget xw, XTermFonts * source)
{
TScreen *screen = &xw->screen;
XTermFonts *data = screen->double_fonts;
int n;
if (screen->fonts_used >= screen->cache_doublesize) {
TRACE(("pushback_font: discard oldest\n"));
discard_font(xw, screen->fonts_used - 1);
} else {
screen->fonts_used += 1;
}
for (n = screen->fonts_used; n > 0; n--)
data[n] = data[n - 1];
data[0] = *source;
TRACE(("pushback_font -> (NEW:%d)\n", screen->fonts_used));
return data;
}
int
xterm_Double_index(XtermWidget xw, unsigned chrset, unsigned flags)
{
int n;
int result = -1;
TScreen *screen = &xw->screen;
XTermFonts *data = screen->double_fonts;
flags &= BOLD;
TRACE(("xterm_Double_index chrset=%#x, flags=%#x\n", chrset, flags));
for (n = 0; n < screen->fonts_used; n++) {
if (data[n].chrset == chrset
&& data[n].flags == flags) {
if (n != 0) {
XTermFonts save;
TRACE(("...xterm_Double_index -> %d (OLD:%d)\n", n, screen->fonts_used));
save = data[n];
while (n > 0) {
data[n] = data[n - 1];
n--;
}
data[n] = save;
}
result = n;
break;
}
}
return result;
}
GC
xterm_DoubleGC(XtermWidget xw,
unsigned chrset,
unsigned flags,
GC old_gc,
int *inxp)
{
TScreen *screen = &(xw->screen);
VTwin *cgsWin = WhichVWin(screen);
int n;
char *name;
XTermFonts *data = 0;
GC result = 0;
if ((name = xtermSpecialFont(screen, flags, chrset)) != 0) {
CgsEnum cgsId = WhichCgsId(flags);
Boolean found = False;
if ((n = xterm_Double_index(xw, chrset, flags)) >= 0) {
data = &(screen->double_fonts[n]);
if (data->fn != 0) {
if (!strcmp(data->fn, name)
&& data->fs != 0) {
found = True;
free(name);
} else {
discard_font(xw, n);
}
}
}
if (!found) {
XTermFonts temp;
TRACE(("xterm_DoubleGC %s %d: %s\n",
flags & BOLD ? "BOLD" : "NORM", n, name));
memset(&temp, 0, sizeof(temp));
temp.fn = name;
temp.chrset = chrset;
temp.flags = (flags & BOLD);
if (!xtermOpenFont(xw, name, &temp)) {
char *nname = xtermSpecialFont(screen, flags | NORESOLUTION, chrset);
if (nname != 0) {
found = xtermOpenFont(xw, nname, &temp);
free(nname);
}
} else {
found = True;
}
free(name);
if (found) {
n = 0;
data = pushback_font(xw, &temp);
}
TRACE(("-> %s\n", found ? "OK" : "FAIL"));
}
if (found) {
setCgsCSet(xw, cgsWin, cgsId, chrset);
setCgsFont(xw, cgsWin, cgsId, data);
setCgsFore(xw, cgsWin, cgsId, getCgsFore(xw, cgsWin, old_gc));
setCgsBack(xw, cgsWin, cgsId, getCgsBack(xw, cgsWin, old_gc));
result = getCgsGC(xw, cgsWin, cgsId);
*inxp = n;
} else if (flags & BOLD) {
flags &= ~BOLD;
result = xterm_DoubleGC(xw, chrset, flags, old_gc, inxp);
}
}
return result;
}
#endif