/* * Copy the parameters (except GC of course) from one cache record to another. */ void copyCgs(XtermWidget xw, VTwin *cgsWin, CgsEnum dstCgsId, CgsEnum srcCgsId) { if (dstCgsId != srcCgsId) { CgsCache *me; if ((me = myCache(xw, cgsWin, srcCgsId)) != 0) { TRACE(("copyCgs from %s to %s\n", traceCgsEnum(srcCgsId), traceCgsEnum(dstCgsId))); TRACE2(("copyCgs from %s (me %p, fg %s, bg %s, cset %s) to %s {{\n", traceCgsEnum(srcCgsId), me, tracePixel(xw, THIS(fg)), tracePixel(xw, THIS(bg)), traceCSet(THIS(cset)), traceCgsEnum(dstCgsId))); setCgsCSet(xw, cgsWin, dstCgsId, THIS(cset)); setCgsFore(xw, cgsWin, dstCgsId, THIS(fg)); setCgsBack(xw, cgsWin, dstCgsId, THIS(bg)); setCgsFont(xw, cgsWin, dstCgsId, THIS(font)); TRACE2(("...copyCgs }}\n")); } } }
/* * Return a GC associated with the given id, allocating if needed. */ GC getCgsGC(XtermWidget xw, VTwin *cgsWin, CgsEnum cgsId) { CgsCache *me; GC result = 0; int j, k; unsigned used = 0; if ((me = myCache(xw, cgsWin, cgsId)) != 0) { TRACE2(("getCgsGC(%s, %s)\n", traceVTwin(xw, cgsWin), traceCgsEnum(cgsId))); if (me->mask != 0) { /* fill in the unchanged fields */ if (!(me->mask & GC_CSet)) NEXT(cset) = 0; /* OPT_DEC_CHRSET */ if (!(me->mask & GCFont)) NEXT(font) = THIS(font); if (!(me->mask & GCForeground)) NEXT(fg) = THIS(fg); if (!(me->mask & GCBackground)) NEXT(bg) = THIS(bg); if (NEXT(font) == 0) { setCgsFont(xw, cgsWin, cgsId, 0); } TRACE2(("...Cgs new data fg=%s, bg=%s, font=%s cset %s\n", tracePixel(xw, NEXT(fg)), tracePixel(xw, NEXT(bg)), traceFont(NEXT(font)), traceCSet(NEXT(cset)))); /* try to find the given data in an already-created GC */ for (j = 0; j < DEPTH; ++j) { if (LIST(j).gc != 0 && SameFont(LIST(j).font, NEXT(font)) && SameCSet(LIST(j).cset, NEXT(cset)) && SameColor(LIST(j).fg, NEXT(fg)) && SameColor(LIST(j).bg, NEXT(bg))) { LINK(j); result = THIS(gc); TRACE2(("getCgsGC existing %p(%d)\n", result, ITEM())); break; } } if (result == 0) { /* try to find an empty slot, to create a new GC */ used = 0; for (j = 0; j < DEPTH; ++j) { if (LIST(j).gc == 0) { LINK(j); result = newCache(xw, cgsWin, cgsId, me); break; } if (used < LIST(j).used) used = LIST(j).used; } } if (result == 0) { /* if none were empty, pick the least-used slot, to modify */ for (j = 0, k = -1; j < DEPTH; ++j) { if (used >= LIST(j).used) { used = LIST(j).used; k = j; } } LINK(k); TRACE2(("...getCgsGC least-used(%d) was %d\n", k, THIS(used))); result = chgCache(xw, cgsId, me, True); } me->next = *(me->data); } else { result = THIS(gc); } me->mask = 0; THIS(used) += 1; TRACE2(("...getCgsGC(%s, %s) gc %p(%d), used %d\n", traceVTwin(xw, cgsWin), traceCgsEnum(cgsId), result, ITEM(), THIS(used))); } return result; }
/* * Lookup/cache a GC for the double-size character display. We save up to * NUM_CHRSET values. */ GC xterm_DoubleGC(XtermWidget xw, unsigned chrset, unsigned attr_flags, unsigned draw_flags, GC old_gc, int *inxp) { TScreen *screen = TScreenOf(xw); VTwin *cgsWin = WhichVWin(screen); char *name; GC result = 0; if ((name = xtermSpecialFont(screen, attr_flags, draw_flags, chrset)) != 0) { CgsEnum cgsId = WhichCgsId(attr_flags); Boolean found = False; XTermFonts *data = 0; int n; if ((n = xterm_Double_index(xw, chrset, attr_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", (attr_flags & BOLD) ? "BOLD" : "NORM", n, name)); memset(&temp, 0, sizeof(temp)); temp.fn = name; temp.chrset = chrset; temp.flags = (attr_flags & BOLD); if (!xtermOpenFont(xw, name, &temp, fwAlways, False)) { /* Retry with * in resolutions */ char *nname = xtermSpecialFont(screen, attr_flags, draw_flags | NORESOLUTION, chrset); if (nname != 0) { found = (Boolean) xtermOpenFont(xw, nname, &temp, fwAlways, False); 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 (attr_flags & BOLD) { UIntClr(attr_flags, BOLD); result = xterm_DoubleGC(xw, chrset, attr_flags, draw_flags, old_gc, inxp); } } return result; }