| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | |
|---|
| 16 | |
|---|
| 17 | |
|---|
| 18 | |
|---|
| 19 | |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | |
|---|
| 25 | |
|---|
| 26 | |
|---|
| 27 | |
|---|
| 28 | |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | |
|---|
| 33 | |
|---|
| 34 | |
|---|
| 35 | #include <xterm.h> |
|---|
| 36 | #include <data.h> |
|---|
| 37 | #include <fontutils.h> |
|---|
| 38 | |
|---|
| 39 | #include <assert.h> |
|---|
| 40 | |
|---|
| 41 | #define WhichCgsId(flag) (((flag) & BOLD) ? gcCBold : gcCNorm) |
|---|
| 42 | |
|---|
| 43 | |
|---|
| 44 | |
|---|
| 45 | |
|---|
| 46 | |
|---|
| 47 | |
|---|
| 48 | #define curChrSet SCRN_BUF_CSETS(screen, screen->cur_row)[0] |
|---|
| 49 | |
|---|
| 50 | #if OPT_DEC_CHRSET |
|---|
| 51 | |
|---|
| 52 | static void |
|---|
| 53 | repaint_line(XtermWidget xw, unsigned newChrSet) |
|---|
| 54 | { |
|---|
| 55 | register TScreen *screen = &xw->screen; |
|---|
| 56 | int curcol = screen->cur_col; |
|---|
| 57 | int currow = screen->cur_row; |
|---|
| 58 | unsigned len = MaxCols(screen); |
|---|
| 59 | int width = len; |
|---|
| 60 | unsigned oldChrSet = SCRN_BUF_CSETS(screen, currow)[0]; |
|---|
| 61 | |
|---|
| 62 | assert(width > 0); |
|---|
| 63 | |
|---|
| 64 | |
|---|
| 65 | |
|---|
| 66 | |
|---|
| 67 | if (oldChrSet == newChrSet) |
|---|
| 68 | return; |
|---|
| 69 | |
|---|
| 70 | TRACE(("repaint_line(%2d,%2d) (%s -> %s)\n", currow, screen->cur_col, |
|---|
| 71 | visibleChrsetName(oldChrSet), |
|---|
| 72 | visibleChrsetName(newChrSet))); |
|---|
| 73 | HideCursor(); |
|---|
| 74 | |
|---|
| 75 | |
|---|
| 76 | |
|---|
| 77 | |
|---|
| 78 | if (CSET_DOUBLE(newChrSet)) { |
|---|
| 79 | width /= 2; |
|---|
| 80 | if (curcol > width) |
|---|
| 81 | curcol = width; |
|---|
| 82 | } |
|---|
| 83 | |
|---|
| 84 | |
|---|
| 85 | |
|---|
| 86 | |
|---|
| 87 | |
|---|
| 88 | ClearCurBackground(xw, |
|---|
| 89 | CursorY(screen, currow), |
|---|
| 90 | CurCursorX(screen, currow, 0), |
|---|
| 91 | (unsigned) FontHeight(screen), |
|---|
| 92 | len * CurFontWidth(screen, currow)); |
|---|
| 93 | |
|---|
| 94 | |
|---|
| 95 | memset(SCRN_BUF_CSETS(screen, currow), (Char) newChrSet, len); |
|---|
| 96 | |
|---|
| 97 | set_cur_col(screen, 0); |
|---|
| 98 | ScrnUpdate(xw, currow, 0, 1, (int) len, True); |
|---|
| 99 | set_cur_col(screen, curcol); |
|---|
| 100 | } |
|---|
| 101 | #endif |
|---|
| 102 | |
|---|
| 103 | |
|---|
| 104 | |
|---|
| 105 | |
|---|
| 106 | |
|---|
| 107 | void |
|---|
| 108 | xterm_DECDHL(XtermWidget xw GCC_UNUSED, Bool top) |
|---|
| 109 | { |
|---|
| 110 | #if OPT_DEC_CHRSET |
|---|
| 111 | repaint_line(xw, (unsigned) (top ? CSET_DHL_TOP : CSET_DHL_BOT)); |
|---|
| 112 | #else |
|---|
| 113 | (void) top; |
|---|
| 114 | #endif |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | |
|---|
| 118 | |
|---|
| 119 | |
|---|
| 120 | void |
|---|
| 121 | xterm_DECSWL(XtermWidget xw GCC_UNUSED) |
|---|
| 122 | { |
|---|
| 123 | #if OPT_DEC_CHRSET |
|---|
| 124 | repaint_line(xw, CSET_SWL); |
|---|
| 125 | #endif |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | |
|---|
| 129 | |
|---|
| 130 | |
|---|
| 131 | void |
|---|
| 132 | xterm_DECDWL(XtermWidget xw GCC_UNUSED) |
|---|
| 133 | { |
|---|
| 134 | #if OPT_DEC_CHRSET |
|---|
| 135 | repaint_line(xw, CSET_DWL); |
|---|
| 136 | #endif |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | #if OPT_DEC_CHRSET |
|---|
| 140 | static void |
|---|
| 141 | discard_font(XtermWidget xw, int n) |
|---|
| 142 | { |
|---|
| 143 | TScreen *screen = &xw->screen; |
|---|
| 144 | XTermFonts *data = &(screen->double_fonts[n]); |
|---|
| 145 | |
|---|
| 146 | TRACE(("discard_font chrset=%d %s\n", data->chrset, |
|---|
| 147 | (data->fn != 0) ? data->fn : "<no-name>")); |
|---|
| 148 | |
|---|
| 149 | data->chrset = 0; |
|---|
| 150 | data->flags = 0; |
|---|
| 151 | if (data->fn != 0) { |
|---|
| 152 | free(data->fn); |
|---|
| 153 | data->fn = 0; |
|---|
| 154 | } |
|---|
| 155 | (void) xtermCloseFont(xw, data); |
|---|
| 156 | |
|---|
| 157 | screen->fonts_used -= 1; |
|---|
| 158 | while (n < screen->fonts_used) { |
|---|
| 159 | screen->double_fonts[n] = screen->double_fonts[n + 1]; |
|---|
| 160 | ++n; |
|---|
| 161 | } |
|---|
| 162 | } |
|---|
| 163 | |
|---|
| 164 | |
|---|
| 165 | static XTermFonts * |
|---|
| 166 | pushback_font(XtermWidget xw, XTermFonts * source) |
|---|
| 167 | { |
|---|
| 168 | TScreen *screen = &xw->screen; |
|---|
| 169 | XTermFonts *data = screen->double_fonts; |
|---|
| 170 | int n; |
|---|
| 171 | |
|---|
| 172 | if (screen->fonts_used >= screen->cache_doublesize) { |
|---|
| 173 | TRACE(("pushback_font: discard oldest\n")); |
|---|
| 174 | discard_font(xw, screen->fonts_used - 1); |
|---|
| 175 | } else { |
|---|
| 176 | screen->fonts_used += 1; |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | for (n = screen->fonts_used; n > 0; n--) |
|---|
| 180 | data[n] = data[n - 1]; |
|---|
| 181 | data[0] = *source; |
|---|
| 182 | |
|---|
| 183 | TRACE(("pushback_font -> (NEW:%d)\n", screen->fonts_used)); |
|---|
| 184 | |
|---|
| 185 | return data; |
|---|
| 186 | } |
|---|
| 187 | |
|---|
| 188 | int |
|---|
| 189 | xterm_Double_index(XtermWidget xw, unsigned chrset, unsigned flags) |
|---|
| 190 | { |
|---|
| 191 | int n; |
|---|
| 192 | int result = -1; |
|---|
| 193 | TScreen *screen = &xw->screen; |
|---|
| 194 | XTermFonts *data = screen->double_fonts; |
|---|
| 195 | |
|---|
| 196 | flags &= BOLD; |
|---|
| 197 | TRACE(("xterm_Double_index chrset=%#x, flags=%#x\n", chrset, flags)); |
|---|
| 198 | |
|---|
| 199 | for (n = 0; n < screen->fonts_used; n++) { |
|---|
| 200 | if (data[n].chrset == chrset |
|---|
| 201 | && data[n].flags == flags) { |
|---|
| 202 | if (n != 0) { |
|---|
| 203 | XTermFonts save; |
|---|
| 204 | TRACE(("...xterm_Double_index -> %d (OLD:%d)\n", n, screen->fonts_used)); |
|---|
| 205 | save = data[n]; |
|---|
| 206 | while (n > 0) { |
|---|
| 207 | data[n] = data[n - 1]; |
|---|
| 208 | n--; |
|---|
| 209 | } |
|---|
| 210 | data[n] = save; |
|---|
| 211 | } |
|---|
| 212 | result = n; |
|---|
| 213 | break; |
|---|
| 214 | } |
|---|
| 215 | } |
|---|
| 216 | |
|---|
| 217 | return result; |
|---|
| 218 | } |
|---|
| 219 | |
|---|
| 220 | |
|---|
| 221 | |
|---|
| 222 | |
|---|
| 223 | |
|---|
| 224 | GC |
|---|
| 225 | xterm_DoubleGC(XtermWidget xw, |
|---|
| 226 | unsigned chrset, |
|---|
| 227 | unsigned flags, |
|---|
| 228 | GC old_gc, |
|---|
| 229 | int *inxp) |
|---|
| 230 | { |
|---|
| 231 | TScreen *screen = &(xw->screen); |
|---|
| 232 | VTwin *cgsWin = WhichVWin(screen); |
|---|
| 233 | int n; |
|---|
| 234 | char *name; |
|---|
| 235 | XTermFonts *data = 0; |
|---|
| 236 | GC result = 0; |
|---|
| 237 | |
|---|
| 238 | if ((name = xtermSpecialFont(screen, flags, chrset)) != 0) { |
|---|
| 239 | CgsEnum cgsId = WhichCgsId(flags); |
|---|
| 240 | Boolean found = False; |
|---|
| 241 | |
|---|
| 242 | if ((n = xterm_Double_index(xw, chrset, flags)) >= 0) { |
|---|
| 243 | data = &(screen->double_fonts[n]); |
|---|
| 244 | if (data->fn != 0) { |
|---|
| 245 | if (!strcmp(data->fn, name) |
|---|
| 246 | && data->fs != 0) { |
|---|
| 247 | found = True; |
|---|
| 248 | free(name); |
|---|
| 249 | } else { |
|---|
| 250 | discard_font(xw, n); |
|---|
| 251 | } |
|---|
| 252 | } |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | if (!found) { |
|---|
| 256 | XTermFonts temp; |
|---|
| 257 | |
|---|
| 258 | TRACE(("xterm_DoubleGC %s %d: %s\n", |
|---|
| 259 | flags & BOLD ? "BOLD" : "NORM", n, name)); |
|---|
| 260 | |
|---|
| 261 | memset(&temp, 0, sizeof(temp)); |
|---|
| 262 | temp.fn = name; |
|---|
| 263 | temp.chrset = chrset; |
|---|
| 264 | temp.flags = (flags & BOLD); |
|---|
| 265 | |
|---|
| 266 | if (!xtermOpenFont(xw, name, &temp)) { |
|---|
| 267 | |
|---|
| 268 | char *nname = xtermSpecialFont(screen, flags | NORESOLUTION, chrset); |
|---|
| 269 | |
|---|
| 270 | if (nname != 0) { |
|---|
| 271 | found = xtermOpenFont(xw, nname, &temp); |
|---|
| 272 | free(nname); |
|---|
| 273 | } |
|---|
| 274 | } else { |
|---|
| 275 | found = True; |
|---|
| 276 | } |
|---|
| 277 | free(name); |
|---|
| 278 | |
|---|
| 279 | if (found) { |
|---|
| 280 | n = 0; |
|---|
| 281 | data = pushback_font(xw, &temp); |
|---|
| 282 | } |
|---|
| 283 | |
|---|
| 284 | TRACE(("-> %s\n", found ? "OK" : "FAIL")); |
|---|
| 285 | } |
|---|
| 286 | |
|---|
| 287 | if (found) { |
|---|
| 288 | setCgsCSet(xw, cgsWin, cgsId, chrset); |
|---|
| 289 | setCgsFont(xw, cgsWin, cgsId, data); |
|---|
| 290 | setCgsFore(xw, cgsWin, cgsId, getCgsFore(xw, cgsWin, old_gc)); |
|---|
| 291 | setCgsBack(xw, cgsWin, cgsId, getCgsBack(xw, cgsWin, old_gc)); |
|---|
| 292 | result = getCgsGC(xw, cgsWin, cgsId); |
|---|
| 293 | *inxp = n; |
|---|
| 294 | } else if (flags & BOLD) { |
|---|
| 295 | flags &= ~BOLD; |
|---|
| 296 | result = xterm_DoubleGC(xw, chrset, flags, old_gc, inxp); |
|---|
| 297 | } |
|---|
| 298 | } |
|---|
| 299 | |
|---|
| 300 | return result; |
|---|
| 301 | } |
|---|
| 302 | #endif |
|---|