diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2022-11-07 11:15:29 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2022-11-07 11:15:29 +0000 |
commit | 48931cfb42d376110ff0e1c51f8eddb02c0ddff9 (patch) | |
tree | b50bdaeb83ef5d91067856f190327cd7ccaf12af /app | |
parent | c8f3aac0b6fc15e33b24d8f4966d1f032984471b (diff) |
Update xterm to version 374 ok tb@
Diffstat (limited to 'app')
72 files changed, 2722 insertions, 1740 deletions
diff --git a/app/xterm/MANIFEST b/app/xterm/MANIFEST index a576c438d..da49b7225 100644 --- a/app/xterm/MANIFEST +++ b/app/xterm/MANIFEST @@ -1,4 +1,4 @@ -MANIFEST for xterm, version xterm-372 +MANIFEST for xterm, version xterm-374 -------------------------------------------------------------------------------- MANIFEST this file 256colres.h resource-definitions for 256-color mode @@ -79,7 +79,7 @@ ptydata.c functions to manipulate data read from pty ptyx.h structure-definitions for 'xterm' resize.c program to compute/modify xterm's window size resize.man manual page for 'resize' -run-tic.sh run tic, filtering out harmless messages +run-tic.in run tic, filtering out harmless messages (template) screen.c VT100 screen update functions scrollback.c manage scrollback (a big FIFO) scrollbar.c VT100 scrollbar support functions diff --git a/app/xterm/NEWS b/app/xterm/NEWS index 77ca74a98..fc2ea323a 100644 --- a/app/xterm/NEWS +++ b/app/xterm/NEWS @@ -1,9 +1,24 @@ The NEWS file was generated from xterm.log.html, which serves as the changelog for xterm. -------------------------------------------------------------------------------- - Patch #372 - 2022/03/09 + Patch #374 - 2022/10/10 - * amend allocation/freeing of scrollback lines, eliminating an - adjustment for status-line added in patch #371 (report/testcase by - Rajeev V. Pillai). + * eliminate use of grep aliases from vttests scripts. + * amend discussion of DECSDM versus Sixel Scrolling in ctlseqs.ms + (reports by Hayaki Saito, Ben Wong). + * change default for sixelScrolling resource to better match + VT330/VT340 DECSDM setting (patch by Ben Wong). + * fix some gcc and coverity warnings. + * improve memory usage for OSC 52 (report by David Leadbeater). + * fix regression in xterm-373 change adding resources + xftTrackMemUsage to xftMaxGlyphMemory, which did not first cache + the server's resource-settings (report/testcase by Gabor Hauzer, as + well as Debian #1021243). + * fix regression in xterm-373 change for status-line vs alternate + screen (report by Rajeev V. Pillai). + * configure script improvements: + + modify CF_XOPEN_SOURCE to handle more special cases of Linux + (reports by Adam Sampson, Sven Joachim). + + modify checks for egrep/fgrep aliases to work around warning + messages from GNU grep 3.8 diff --git a/app/xterm/THANKS b/app/xterm/THANKS index 32ec45ad9..fdf040cf9 100644 --- a/app/xterm/THANKS +++ b/app/xterm/THANKS @@ -1,4 +1,4 @@ --- $XTermId: THANKS,v 1.33 2022/02/22 21:42:29 tom Exp $ +-- $XTermId: THANKS,v 1.35 2022/09/12 21:10:13 tom Exp $ -- vile:txtmode fk=utf-8 There's no AUTHORS file in this distribution; it would be redundant since I (Thomas E. Dickey) have done more than 80% of the work on xterm since 1996. @@ -39,10 +39,12 @@ Bertram Felgenhauer Bill Nottingham Bjarni Ingi Gislason Bob Maynard +Boian Bonev Brad Town Bradd W Szonye Bram Moolenaar Branden Robinson +Brendan O' Dea Bruno Haible Cade Foster Caetano Jimenez Carezzato @@ -200,6 +202,7 @@ Rajesh Mandalemula Richard Braakman Richard Griswold Richard Tollerton +Richard de Boer Rob Braun Robert Brady Robert Earl @@ -209,6 +212,7 @@ Romain Francoise Ross Combs Ross Paterson Ryan Johnson +Ryan Schmidt Sam Stephenson Samuel Thibault Scott Sewall diff --git a/app/xterm/Tekproc.c b/app/xterm/Tekproc.c index 19c7ba4e7..dd24882d3 100644 --- a/app/xterm/Tekproc.c +++ b/app/xterm/Tekproc.c @@ -1,7 +1,7 @@ -/* $XTermId: Tekproc.c,v 1.246 2021/12/27 18:07:35 tom Exp $ */ +/* $XTermId: Tekproc.c,v 1.249 2022/10/06 19:41:47 tom Exp $ */ /* - * Copyright 2001-2020,2021 by Thomas E. Dickey + * Copyright 2001-2021,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -1337,9 +1337,9 @@ TekEnq(TekWidget tw, if (tekscr->gin_terminator == GIN_TERM_EOT) cplot[len++] = '\004'; #ifdef VMS - tt_write(cplot + adj, len - adj); + tt_write(cplot + adj, (size_t) (len - adj)); #else /* VMS */ - v_write(screen->respond, cplot + adj, (unsigned) (len - adj)); + v_write(screen->respond, cplot + adj, (size_t) (len - adj)); #endif /* VMS */ } @@ -2015,6 +2015,7 @@ TekSimulatePageButton(TekWidget tw, Bool reset) void TekCopy(TekWidget tw) { +#ifdef ALLOWLOGGING if (tw != 0) { TekScreen *tekscr = TekScreenOf(tw); TScreen *screen = TScreenOf(tw->vt); @@ -2052,6 +2053,9 @@ TekCopy(TekWidget tw) close(tekcopyfd); } } +#else + (void) tw; +#endif /* ALLOWLOGGING */ } /*ARGSUSED*/ diff --git a/app/xterm/button.c b/app/xterm/button.c index 1a24f177a..fae8fbd9b 100644 --- a/app/xterm/button.c +++ b/app/xterm/button.c @@ -1,7 +1,7 @@ -/* $XTermId: button.c,v 1.638 2021/11/26 01:27:25 tom Exp $ */ +/* $XTermId: button.c,v 1.642 2022/10/06 16:52:06 tom Exp $ */ /* - * Copyright 1999-2020,2021 by Thomas E. Dickey + * Copyright 1999-2021,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -2332,7 +2332,7 @@ base64_flush(TScreen *screen) * Translate ISO-8859-1 or UTF-8 data to NRCS. */ static void -ToNational(XtermWidget xw, Char *buffer, unsigned *length) +ToNational(XtermWidget xw, Char *buffer, size_t *length) { TScreen *screen = TScreenOf(xw); DECNRCM_codes gsetL = screen->gsets[screen->curgl]; @@ -2346,7 +2346,7 @@ ToNational(XtermWidget xw, Char *buffer, unsigned *length) memset(data, 0, sizeof(*data)); data->next = data->buffer; data->last = data->buffer + *length; - memcpy(data->buffer, buffer, (size_t) *length); + memcpy(data->buffer, buffer, *length); p = buffer; while (data->next < data->last) { unsigned chr, out, gl, gr; @@ -2365,14 +2365,14 @@ ToNational(XtermWidget xw, Char *buffer, unsigned *length) } *p++ = (Char) ((out < 256) ? out : ' '); } - *length = (unsigned) (p - buffer); + *length = (size_t) (p - buffer); free(data); } else #endif { Char *p; - for (p = buffer; (int) (p - buffer) < (int) *length; ++p) { + for (p = buffer; (size_t) (p - buffer) < *length; ++p) { unsigned gl, gr; unsigned chr = *p; unsigned out = chr; @@ -2387,7 +2387,7 @@ ToNational(XtermWidget xw, Char *buffer, unsigned *length) } static void -_qWriteSelectionData(XtermWidget xw, Char *lag, unsigned length) +_qWriteSelectionData(XtermWidget xw, Char *lag, size_t length) { TScreen *screen = TScreenOf(xw); @@ -2409,7 +2409,9 @@ _qWriteSelectionData(XtermWidget xw, Char *lag, unsigned length) Char buf[64]; unsigned x = 0; - TRACE(("convert to base64 %d:%s\n", length, visibleChars(p, length))); + TRACE(("convert to base64 %lu:%s\n", + (unsigned long) length, + visibleChars(p, length))); /* * Handle the case where the selection is from _this_ xterm, which @@ -2497,7 +2499,7 @@ _WriteSelectionData(XtermWidget xw, Char *line, size_t length) #if OPT_PASTE64 if (screen->base64_paste) { - _qWriteSelectionData(xw, lag, (unsigned) (end - lag)); + _qWriteSelectionData(xw, lag, (size_t) (end - lag)); base64_flush(screen); } else #endif @@ -2507,14 +2509,14 @@ _WriteSelectionData(XtermWidget xw, Char *line, size_t length) for (cp = line; cp != end; cp++) { if (*cp == '\n') { *cp = '\r'; - _qWriteSelectionData(xw, lag, (unsigned) (cp - lag + 1)); + _qWriteSelectionData(xw, lag, (size_t) (cp - lag + 1)); lag = cp + 1; } } } if (lag != end) { - _qWriteSelectionData(xw, lag, (unsigned) (end - lag)); + _qWriteSelectionData(xw, lag, (size_t) (end - lag)); } } #ifdef VMS @@ -5666,6 +5668,7 @@ getDataFromScreen(XtermWidget xw, XEvent *event, String method, CELL *start, CEL return result; } +#if OPT_EXEC_SELECTION /* * Split-up the format before substituting data, to avoid quoting issues. * The resource mechanism has a limited ability to handle escapes. We take @@ -5753,6 +5756,7 @@ tokenizeFormat(String format) return result; } +#endif /* OPT_EXEC_SELECTION */ static void formatVideoAttrs(XtermWidget xw, char *buffer, CELL *cell) @@ -5935,7 +5939,7 @@ expandFormat(XtermWidget xw, return result; } -#if OPT_EXEC_XTERM +#if OPT_EXEC_SELECTION /* execute the command after forking. The main process frees its data */ static void executeCommand(pid_t pid, char **argv) @@ -6039,7 +6043,7 @@ HandleExecSelectable(Widget w, } } } -#endif /* OPT_EXEC_XTERM */ +#endif /* OPT_EXEC_SELECTION */ static void reallyInsertFormatted(Widget w, char *format, char *data, CELL *start, CELL *finish) diff --git a/app/xterm/charclass.c b/app/xterm/charclass.c index 4381db3d8..bf753f616 100644 --- a/app/xterm/charclass.c +++ b/app/xterm/charclass.c @@ -1,7 +1,7 @@ -/* $XTermId: charclass.c,v 1.44 2021/02/02 00:19:32 tom Exp $ */ +/* $XTermId: charclass.c,v 1.45 2022/09/23 23:28:44 tom Exp $ */ /* - * Copyright 2002-2020,2021 by Thomas E. Dickey + * Copyright 2002-2021,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -141,7 +141,10 @@ init_classtab(void) SetCharacterClassRange(0x17d4, 0x17dc, IDENT); /* Khmer punctuation */ SetCharacterClassRange(0x1800, 0x180a, IDENT); /* Mongolian punctuation */ SetCharacterClassRange(0x2000, 0x200a, BLANK); /* spaces */ - SetCharacterClassRange(0x200b, 0x27ff, IDENT); /* punctuation and symbols */ + SetCharacterClassRange(0x200b, 0x200f, CNTRL); /* formatting */ + SetCharacterClassRange(0x2010, 0x27ff, IDENT); /* punctuation and symbols */ + SetCharacterClassRange(0x202a, 0x202e, CNTRL); /* formatting */ + SetCharacterClassRange(0x2060, 0x206f, CNTRL); /* formatting */ SetCharacterClassRange(0x2070, 0x207f, U_SUP); /* superscript */ SetCharacterClassRange(0x2080, 0x208f, U_SUB); /* subscript */ SetCharacterClassRange(0x3000, 0x3000, BLANK); /* ideographic space */ @@ -152,10 +155,12 @@ init_classtab(void) SetCharacterClassRange(0xac00, 0xd7a3, U_HAN); /* Hangul Syllables */ SetCharacterClassRange(0xf900, 0xfaff, U_CJK); /* CJK Ideographs */ SetCharacterClassRange(0xfe30, 0xfe6b, IDENT); /* punctuation forms */ + SetCharacterClassRange(0xfeff, 0xfeff, CNTRL); /* formatting */ SetCharacterClassRange(0xff00, 0xff0f, IDENT); /* half/fullwidth ASCII */ SetCharacterClassRange(0xff1a, 0xff20, IDENT); /* half/fullwidth ASCII */ SetCharacterClassRange(0xff3b, 0xff40, IDENT); /* half/fullwidth ASCII */ SetCharacterClassRange(0xff5b, 0xff64, IDENT); /* half/fullwidth ASCII */ + SetCharacterClassRange(0xfff9, 0xfffb, CNTRL); /* formatting */ TRACE((TRACE_R " init_classtab\n")); return; diff --git a/app/xterm/charproc.c b/app/xterm/charproc.c index 07dd84902..a570707bf 100644 --- a/app/xterm/charproc.c +++ b/app/xterm/charproc.c @@ -1,4 +1,4 @@ -/* $XTermId: charproc.c,v 1.1888 2022/02/22 09:00:26 Vladimir.A.Pavlov Exp $ */ +/* $XTermId: charproc.c,v 1.1906 2022/10/10 15:42:50 tom Exp $ */ /* * Copyright 1999-2021,2022 by Thomas E. Dickey @@ -384,10 +384,10 @@ static XtActionsRec actionsList[] = { { "scroll-lock", HandleScrollLock }, #endif #if OPT_SELECTION_OPS -#if OPT_EXEC_XTERM +#if OPT_EXEC_SELECTION { "exec-formatted", HandleExecFormatted }, { "exec-selectable", HandleExecSelectable }, -#endif /* OPT_EXEC_XTERM */ +#endif { "insert-formatted", HandleInsertFormatted }, { "insert-selectable", HandleInsertSelectable }, #endif @@ -733,12 +733,16 @@ static XtResource xterm_resources[] = "1000x1000"), #endif +#if OPT_ISO_COLORS && OPT_WIDE_ATTRS && OPT_SGR2_HASH + Bres(XtNfaintIsRelative, XtCFaintIsRelative, screen.faint_relative, False), +#endif + #if OPT_SHIFT_FONTS Bres(XtNshiftFonts, XtCShiftFonts, misc.shift_fonts, True), #endif #if OPT_SIXEL_GRAPHICS - Bres(XtNsixelScrolling, XtCSixelScrolling, screen.sixel_scrolling, False), + Bres(XtNsixelScrolling, XtCSixelScrolling, screen.sixel_scrolling, True), Bres(XtNsixelScrollsRight, XtCSixelScrollsRight, screen.sixel_scrolls_right, False), #endif @@ -816,6 +820,12 @@ static XtResource xterm_resources[] = #if OPT_RENDERFONT Bres(XtNforceXftHeight, XtCForceXftHeight, screen.force_xft_height, False), + Ires(XtNxftMaxGlyphMemory, XtCXftMaxGlyphMemory, + screen.xft_max_glyph_memory, 0), + Ires(XtNxftMaxUnrefFonts, XtCXftMaxUnrefFonts, + screen.xft_max_unref_fonts, 0), + Bres(XtNxftTrackMemUsage, XtCXftTrackMemUsage, + screen.xft_track_mem_usage, DEF_TRACK_USAGE), #define RES_FACESIZE(n) Dres(XtNfaceSize #n, XtCFaceSize #n, misc.face_size[n], "0.0") RES_FACESIZE(1), RES_FACESIZE(2), @@ -2271,7 +2281,7 @@ typedef enum { SLnone = 0, /* no status-line timer needed */ SLclock = 1, /* status-line updates once/second */ SLcoords = 2, /* status-line shows cursor-position */ - SLwritten = 3 /* status-line may need asynchonous repainting */ + SLwritten = 3 /* status-line may need asynchronous repainting */ } SL_MODE; #define SL_BUFSIZ 80 @@ -4051,8 +4061,11 @@ doparsing(XtermWidget xw, unsigned c, struct ParseState *sp) } reply.a_param[count++] = (ParmType) value; - if (sp->private_function - && screen->vtXX_level >= 4) { /* VT420 */ + if (sp->private_function && + (screen->vtXX_level >= 4 || + (screen->terminal_id >= 330 && + screen->vtXX_level >= 3))) { + /* VT330 (not VT320) and VT420 */ reply.a_param[count++] = 1; } reply.a_final = 'R'; @@ -5721,7 +5734,7 @@ static Char *v_bufend; /* end of physical buffer */ or generated by us in response to a query ESC sequence. */ void -v_write(int f, const Char *data, unsigned len) +v_write(int f, const Char *data, size_t len) { TRACE2(("v_write(%d:%s)\n", len, visibleChars(data, len))); if (v_bufstr == NULL) { @@ -5736,10 +5749,11 @@ v_write(int f, const Char *data, unsigned len) } } if_DEBUG({ - fprintf(stderr, "v_write called with %u bytes (%ld left over)", - len, (long) (v_bufptr - v_bufstr)); + fprintf(stderr, "v_write called with %lu bytes (%lu left over)", + (unsigned long) len, + (unsigned long) (v_bufptr - v_bufstr)); if (len > 1 && len < 10) - fprintf(stderr, " \"%.*s\"", len, (const char *) data); + fprintf(stderr, " \"%.*s\"", (int) len, (const char *) data); fprintf(stderr, "\n"); }); @@ -5783,12 +5797,12 @@ v_write(int f, const Char *data, unsigned len) if (v_bufend < v_bufptr + len) { /* still won't fit: get more space */ /* Don't use XtRealloc because an error is not fatal. */ - unsigned size = (unsigned) (v_bufptr - v_buffer); + size_t size = (size_t) (v_bufptr - v_buffer); v_buffer = TypeRealloc(Char, size + len, v_buffer); if (v_buffer) { if_DEBUG({ - fprintf(stderr, "expanded buffer to %u\n", - size + len); + fprintf(stderr, "expanded buffer to %lu\n", + (unsigned long) (size + len)); }); v_bufstr = v_buffer; v_bufptr = v_buffer + size; @@ -5829,9 +5843,9 @@ v_write(int f, const Char *data, unsigned len) #ifdef VMS riten = tt_write(v_bufstr, - ((v_bufptr - v_bufstr <= VMS_TERM_BUFFER_SIZE) - ? v_bufptr - v_bufstr - : VMS_TERM_BUFFER_SIZE)); + (size_t) ((v_bufptr - v_bufstr <= VMS_TERM_BUFFER_SIZE) + ? v_bufptr - v_bufstr + : VMS_TERM_BUFFER_SIZE)); if (riten == 0) return (riten); #else /* VMS */ @@ -5864,9 +5878,9 @@ v_write(int f, const Char *data, unsigned len) */ if (v_bufend - v_bufptr > 1024) { /* arbitrary hysteresis */ /* save pointers across realloc */ - int start = (int) (v_bufstr - v_buffer); - int size = (int) (v_bufptr - v_buffer); - unsigned allocsize = (unsigned) (size ? size : 1); + size_t start = (size_t) (v_bufstr - v_buffer); + size_t size = (size_t) (v_bufptr - v_buffer); + size_t allocsize = (size ? size : 1); v_buffer = TypeRealloc(Char, allocsize, v_buffer); if (v_buffer) { @@ -5874,7 +5888,7 @@ v_write(int f, const Char *data, unsigned len) v_bufptr = v_buffer + size; v_bufend = v_buffer + allocsize; if_DEBUG({ - fprintf(stderr, "shrunk buffer to %u\n", allocsize); + fprintf(stderr, "shrunk buffer to %lu\n", (unsigned long) allocsize); }); } else { /* should we print a warning if couldn't return memory? */ @@ -7034,12 +7048,12 @@ dpmodes(XtermWidget xw, BitFunc func) } break; #if OPT_SIXEL_GRAPHICS - case srm_DECSDM: /* sixel scrolling */ + case srm_DECSDM: /* sixel display mode (no scrolling) */ if (optSixelGraphics(screen)) { /* FIXME: VT24x did not scroll sixel graphics */ (*func) (&xw->keyboard.flags, MODE_DECSDM); - TRACE(("DECSET/DECRST DECSDM %s (resource default is %d)\n", + TRACE(("DECSET/DECRST DECSDM %s (resource default is %s)\n", BtoS(xw->keyboard.flags & MODE_DECSDM), - TScreenOf(xw)->sixel_scrolling)); + BtoS(!TScreenOf(xw)->sixel_scrolling))); update_decsdm(); } break; @@ -7385,7 +7399,7 @@ savemodes(XtermWidget xw) DoSM(DP_X_LRMM, LEFT_RIGHT); break; #if OPT_SIXEL_GRAPHICS - case srm_DECSDM: /* sixel scrolling */ + case srm_DECSDM: /* sixel display mode (no scroll) */ DoSM(DP_DECSDM, xw->keyboard.flags & MODE_DECSDM); update_decsdm(); break; @@ -7748,7 +7762,7 @@ restoremodes(XtermWidget xw) } break; #if OPT_SIXEL_GRAPHICS - case srm_DECSDM: /* sixel scrolling */ + case srm_DECSDM: /* sixel display mode (no scroll) */ bitcpy(&xw->keyboard.flags, screen->save_modes[DP_DECSDM], MODE_DECSDM); update_decsdm(); break; @@ -8652,7 +8666,13 @@ SwitchBufs(XtermWidget xw, int toBuf, Bool clearFirst) HideCursor(xw); rows = MaxRows(screen); - SwitchBufPtrs(screen, toBuf); +#if OPT_STATUS_LINE + if (IsStatusShown(screen) && (rows > 0)) { + /* avoid clearing the status-line in this function */ + --rows; + } +#endif + SwitchBufPtrs(xw, toBuf); if ((top = INX2ROW(screen, 0)) < rows) { if (screen->scroll_amt) { @@ -8682,10 +8702,26 @@ CheckBufPtrs(TScreen *screen) * Swap buffer line pointers between alternate and regular screens. */ void -SwitchBufPtrs(TScreen *screen, int toBuf) +SwitchBufPtrs(XtermWidget xw, int toBuf) { + TScreen *screen = TScreenOf(xw); + if (CheckBufPtrs(screen)) { - screen->visbuf = screen->editBuf_index[toBuf]; +#if OPT_STATUS_LINE + if (IsStatusShown(screen) + && (screen->visbuf != screen->editBuf_index[toBuf])) { + LineData *oldLD; + LineData *newLD; + int row = MaxRows(screen); + + oldLD = getLineData(screen, row); + screen->visbuf = screen->editBuf_index[toBuf]; + newLD = getLineData(screen, row); + + copyLineData(newLD, oldLD); + } else +#endif + screen->visbuf = screen->editBuf_index[toBuf]; } } @@ -8715,7 +8751,7 @@ VTRun(XtermWidget xw) #if OPT_TEK4014 if (Tpushb > Tpushback) { - fillPtyData(xw, VTbuffer, (char *) Tpushback, (int) (Tpushb - Tpushback)); + fillPtyData(xw, VTbuffer, (char *) Tpushback, (size_t) (Tpushb - Tpushback)); Tpushb = Tpushback; } #endif @@ -10189,6 +10225,9 @@ VTInitialize(Widget wrequest, for (i = 0; i <= fontMenu_lastBuiltin; ++i) { init_Dres2(misc.face_size, i); } + init_Ires(screen.xft_max_glyph_memory); + init_Ires(screen.xft_max_unref_fonts); + init_Bres(screen.xft_track_mem_usage); #define ALLOC_FONTLIST(name,which,field) \ init_Sres(misc.default_xft.field);\ @@ -10297,6 +10336,9 @@ VTInitialize(Widget wrequest, #if OPT_DIRECT_COLOR init_Bres(screen.direct_color); #endif +#if OPT_WIDE_ATTRS && OPT_SGR2_HASH + init_Bres(screen.faint_relative); +#endif TRACE(("...will fake resources for color%d to color%d\n", MIN_ANSI_COLORS, @@ -10439,6 +10481,11 @@ VTInitialize(Widget wrequest, #if OPT_RENDERFONT init_Ires(misc.limit_fontsets); wnew->work.max_fontsets = (unsigned) wnew->misc.limit_fontsets; + if (wnew->work.max_fontsets > 255) { + xtermWarning("limiting number of fontsets to 255 (was %u)\n", + wnew->work.max_fontsets); + wnew->work.max_fontsets = 255; + } init_Sres(misc.render_font_s); wnew->work.render_font = @@ -10588,9 +10635,12 @@ VTInitialize(Widget wrequest, BtoS(wnew->keyboard.flags & MODE_DECBKM))); #if OPT_SIXEL_GRAPHICS + /* Sixel scrolling is opposite of Sixel Display Mode */ init_Bres(screen.sixel_scrolling); if (screen->sixel_scrolling) - wnew->keyboard.flags |= MODE_DECSDM; + UIntClr(wnew->keyboard.flags, MODE_DECSDM); + else + UIntSet(wnew->keyboard.flags, MODE_DECSDM); TRACE(("initialized DECSDM %s\n", BtoS(wnew->keyboard.flags & MODE_DECSDM))); #endif @@ -11121,6 +11171,9 @@ VTDestroy(Widget w GCC_UNUSED) TRACE_FREE_LEAK(xw->misc.localefilter); #endif + TRACE_FREE_LEAK(xw->misc.cdXtraScroll_s); + TRACE_FREE_LEAK(xw->misc.tiXtraScroll_s); + #if OPT_RENDERFONT TRACE_FREE_LEAK(xw->misc.default_xft.f_n); #if OPT_WIDE_CHARS @@ -13234,10 +13287,12 @@ ReallyReset(XtermWidget xw, Bool full, Bool saved) screen->pointer_mode = screen->pointer_mode0; #if OPT_SIXEL_GRAPHICS if (TScreenOf(xw)->sixel_scrolling) - xw->keyboard.flags |= MODE_DECSDM; + UIntClr(xw->keyboard.flags, MODE_DECSDM); + else + UIntSet(xw->keyboard.flags, MODE_DECSDM); TRACE(("full reset DECSDM to %s (resource default is %s)\n", BtoS(xw->keyboard.flags & MODE_DECSDM), - BtoS(TScreenOf(xw)->sixel_scrolling))); + BtoS(!TScreenOf(xw)->sixel_scrolling))); #endif #if OPT_GRAPHICS diff --git a/app/xterm/configure.in b/app/xterm/configure.in index ee3fed407..897a1b6c2 100644 --- a/app/xterm/configure.in +++ b/app/xterm/configure.in @@ -1,4 +1,4 @@ -dnl $XTermId: configure.in,v 1.383 2022/02/20 14:18:05 tom Exp $ +dnl $XTermId: configure.in,v 1.390 2022/10/10 16:33:01 tom Exp $ dnl dnl ----------------------------------------------------------------------------- dnl this file is part of xterm @@ -104,6 +104,7 @@ AC_CHECK_FUNCS( \ waitpid \ wcswidth \ wcwidth ) +CF_MKSTEMP CF_UTMP CF_STRUCT_LASTLOG CF_POSIX_SAVED_IDS @@ -443,8 +444,8 @@ if test "$cf_tic_prog" = yes ; then fi SET_TERMINFO= if test -n "$TERMINFO_DIR" ; then - TERMINFO_DIR='$(DESTDIR)'$TERMINFO_DIR - SET_TERMINFO='TERMINFO=$(TERMINFO_DIR)' + TERMINFO_DIR='${DESTDIR}'$TERMINFO_DIR + SET_TERMINFO='TERMINFO=${TERMINFO_DIR}' fi no_ticprog= else @@ -633,6 +634,16 @@ CF_ARG_DISABLE(boxchars, AC_MSG_RESULT($enable_boxchars) test "$enable_boxchars" = no && AC_DEFINE(OPT_BOX_CHARS,0,[Define to 0 to disable fallback-support for box chars]) +AC_MSG_CHECKING(if you want to allow spawning commands to process selections) +CF_ARG_DISABLE(exec-selection, + [ --disable-exec-selection disable "exec-formatted" and "exec-selection" actions], + [enable_exec_selection=no], + [enable_exec_selection=yes]) +AC_MSG_RESULT($enable_exec_selection) +if test "$enable_exec_selection" = no ; then + AC_DEFINE(OPT_EXEC_SELECTION,0,[Define to 0 to disable "exec-selection" action]) +fi + AC_MSG_CHECKING(if you want to allow spawning new xterms) CF_ARG_ENABLE(exec-xterm, [ --enable-exec-xterm enable "spawn-new-terminal" action], @@ -1193,5 +1204,5 @@ then fi ### output xtermcfg.h, etc -AC_CONFIG_FILES([Makefile df-install minstall:minstall.in]) +AC_CONFIG_FILES([Makefile df-install minstall:minstall.in run-tic.sh:run-tic.in]) AC_OUTPUT diff --git a/app/xterm/ctlseqs.ms b/app/xterm/ctlseqs.ms index d1031b761..445bd0dae 100644 --- a/app/xterm/ctlseqs.ms +++ b/app/xterm/ctlseqs.ms @@ -1,9 +1,9 @@ .\"#! troff -ms $1 -*- Nroff -*- .\" "Xterm Control Sequences" document -.\" $XTermId: ctlseqs.ms,v 1.636 2021/12/26 21:57:14 tom Exp $ +.\" $XTermId: ctlseqs.ms,v 1.641 2022/10/10 14:18:26 tom Exp $ .\" .\" -.\" Copyright 1996-2020,2021 by Thomas E. Dickey +.\" Copyright 1996-2021,2022 by Thomas E. Dickey .\" .\" All Rights Reserved .\" @@ -69,8 +69,8 @@ .\" .ds XT XTerm .ds xt xterm -.ds LF Patch #371 -.ds RF 2021/12/26 +.ds LF Patch #374 +.ds RF 2022/10/10 .\" .if n .pl 9999v \" no page breaks in nroff .ND @@ -346,7 +346,7 @@ X Consortium (1994) Thomas Dickey .AI XFree86 Project (1996-2006) -invisible-island.net (2006-2021) +invisible-island.net (2006-2022) updated for \*(XT \*(LF (\*(RF) .AU . @@ -1341,7 +1341,7 @@ This may be disabled by the \fBtiteInhibit\fP resource. \*(Ps = \*6\*7 \(-> Backarrow key sends backspace (DECBKM), VT340, VT420. This sets the \fBbackarrowKey\fP resource to \*(``true\*(''. \*(Ps = \*6\*9 \(-> Enable left and right margin mode (DECLRMM), VT420 and up. - \*(Ps = \*8\*0 \(-> Disable \fISixel Scrolling\fP (DECSDM). + \*(Ps = \*8\*0 \(-> Enable \fISixel Display Mode\fP (DECSDM), VT330, VT340, VT382. \*(Ps = \*9\*5 \(-> Do not clear screen when DECCOLM is set/reset (DECNCSM), VT510 and up. \*(Ps = \*1\*0\*0\*0 \(-> Send Mouse X & Y on button press and release. @@ -1476,7 +1476,9 @@ This is normally disabled by a compile-time option. This sets the \fBbackarrowKey\fP resource to \*(``false\*(''. \*(Ps = \*6\*9 \(-> Disable left and right margin mode (DECLRMM), VT420 and up. - \*(Ps = \*8\*0 \(-> Enable \fISixel Scrolling\fP (DECSDM). + \*(Ps = \*8\*0 \(-> Disable \fISixel Display Mode\fP (DECSDM), VT330, VT340, VT382. +Turns on ``Sixel Scrolling''. +See the section \fBSixel Graphics\fP and mode \*8\*4\*5\*2. \*(Ps = \*9\*5 \(-> Clear screen when DECCOLM is set/reset (DECNCSM), VT510 and up. \*(Ps = \*1\*0\*0\*0 \(-> Don't send Mouse X & Y on button press and @@ -3218,6 +3220,12 @@ the program will receive: .br followed by the pasted text, followed by \*(Es\*([[\*2\*0\*1\*~. +.br +For background and discussion, see the FAQ: +.ID 2 +.\" https://invisible-island.net/xterm/xterm-paste64.html +\fIXTerm - bracketed-paste\fP +.DE . .Sh "Title Modes" .LP @@ -3598,24 +3606,23 @@ using the \fBdecTerminalID\fP or \fBdecGraphicsID\fP resource, -it supports Sixel Graphics controls, a palleted bitmap graphics system +it supports Sixel Graphics controls, a paletted bitmap graphics system using sets of six vertical pixels as the basic element. .St .IP \\*(Cs\\*(Ps\\*s\\*c -Send Device Attributes (Primary DA), \fI\*(xt\fP. +Send Device Attributes (Primary DA), DEC graphics terminals, \fI\*(xt\fP. \fI\*(xt\fP responds to Send Device Attributes (Primary DA) with these additional codes: \*(Ps = \*4 \(-> Sixel graphics. .iP .IP \\*(Cs\\*?\\*(Pm\\*s\\*h -Set Mode, \fI\*(xt\fP. -\fI\*(xt\fP has these additional private Set Mode values: - \*(Ps = \*8\*0 \(-> Sixel scrolling. - \*(Ps = \*1\*0\*7\*0 \(-> use private color registers for each graphic. - \*(Ps = \*8\*4\*5\*2 \(-> Sixel scrolling leaves cursor to right of graphic. +Set Mode (with corresponding Reset Mode \*(Cs\*?\*(Pm\*s\*l): + \*(Ps = \*8\*0 \(-> Sixel Display Mode (DECSDM), VT330, VT340, VT382. + \*(Ps = \*1\*0\*7\*0 \(-> use private color registers for each graphic, \fI\*(xt\fP. + \*(Ps = \*8\*4\*5\*2 \(-> Sixel scrolling leaves cursor to right of graphic, RLogin, \fI\*(xt\fP. .iP .IP \\*(Dc\\*(Pa\\*s\\*;\\*(Pb\\*s\\*;\\*(Ph\\*s\\*q\\*s\\*(Ps..\\*(Ps\fP\\*s\\*(ST -Send SIXEL image, DEC graphics terminals, \fI\*(xt\fP. +Send SIXEL image, DEC graphics terminals, VT330, VT340, VT382. See: .ID 3 \fIVT330/VT340 Programmer Reference Manual Volume 2:\fP @@ -3905,11 +3912,50 @@ Sometimes the manuals are simply incorrect. For example, testing a DEC VT420 in 1996 showed that the documented code for a valid or invalid response to DECRQSS was reversed. .IP -The VT420 test results were incorporated into \fIvttest\fP program. +The VT420 test results were incorporated into the \fIvttest\fP program. At the time, DEC STD 070 was not available, but it also agrees with \fIvttest\fP. Later, documentation for the DEC VT525 was shown to have the same flaw. .bP +The VT330/VT340 reference manual for graphics programming +documents sixel graphics in some detail in chapter 14. +Overlooked in the first edition, the second edition mentions +.\" https://vt100.net/docs/vt3xx-gp/chapter14.html#S14.4 +\fISixel Scrolling\fP. +The VT382 Kanji and Thai manuals provide less information, +about sixel graphics, +but do mention DECSDM. +They differ in their comment about the private mode +DECSDM (\*(Cs\*?\*8\*0\*h), +which each manual agrees should \fIset\fP the Sixel Scrolling feature. +The VT330/VT340 graphics programming manual (second edition, March 1988) says +.RS 5 +.sp +When sixel display mode is set, the \fISixel Scrolling\fP feature is enabled. +.br +When sixel display mode is reset, the \fISixel Scrolling\fP feature is disabled. +.RE +.IP +while the VT382 Kanji manual (page 6-6, undated) says +.RS +.sp +Disable sixel scroll +.RE +.sp +and the VT382 Thai manual (page C-30, August 1989) says +.RS +.sp +No Sixel scrolling +.RE +.IP +The standard (DEC STD 070) in chapter 9 (August 3, 1990) +states on page 17 that video devices will scroll +when advancing the Sixel active position past the bottom margin, +but on page 19, in the section on deviations, +states that VT125 and VT240 did not scroll in this situation. +The standard does not mention VT330/VT340 or VT382. +Nor does it document DECSDM. +.bP Not all details are clear even in DEC STD 070 (which is more than twice the length of the VT520 programmer's reference manual, @@ -4010,7 +4056,7 @@ Digital Equipment Corporation \fIProgrammer Reference Manual\fP. .br Digital Equipment Corporation -(EK-VT382-RM-001). +(EK-VT382-RM-001, undated). .bP .\" https://vt100.net/dec/ek-vt38t-ug-001.pdf \fIVT382 Thai Display Terminal\fP @@ -4174,38 +4220,7 @@ hard reset (RIS). .IP Both the VT220 manual and DEC STD 070 (which documents levels 1-4 in detail) state that it is a soft reset, e.g., DECSTR. -.bP -The VT330/VT340 reference manual for graphics programming -documents sixel scrolling in some detail in chapter 14. -The VT382 Kanji and Thai manuals provide less information, -but differ in their comment about the private mode -DECSDM (\*(Cs\*?\*8\*0\*h), -which each manual agrees should \fIset\fP the Sixel Scrolling feature. -However, the VT330/VT340 manual says -.RS -.IP -When sixel display mode is set, the Sixel Scrolling feature is enabled. -.RE -.IP -while the VT382 Kanji manual (page 6-6) says -.RS -.IP -Disable sixel scroll -.RE -.IP -and the VT382 Thai manual (page C-30) says -.RS -.IP -No Sixel scrolling -.RE -.IP -The standard (DEC STD 070) in chapter 9 (August 3, 1990) -states on page 17 that video devices will scroll -when advancing the Sixel active position past the bottom margin, -but on page 19, in the section on deviations, -states that VT125 and VT240 did not scroll in this situation. -The standard does not mention VT330/VT340 or VT382. -Nor does it document DECSDM. +. .LP Here are the relevant standards: .bP diff --git a/app/xterm/ctlseqs.txt b/app/xterm/ctlseqs.txt index c425ed534..5e9761165 100644 --- a/app/xterm/ctlseqs.txt +++ b/app/xterm/ctlseqs.txt @@ -20,8 +20,8 @@ Thomas Dickey XFree86 Project (1996-2006) - invisible-island.net (2006-2021) - updated for XTerm Patch #371 (2021/12/26) + invisible-island.net (2006-2022) + updated for XTerm Patch #374 (2022/10/10) @@ -793,7 +793,8 @@ CSI ? Pm h VT420. This sets the backarrowKey resource to "true". Ps = 6 9 -> Enable left and right margin mode (DECLRMM), VT420 and up. - Ps = 8 0 -> Disable Sixel Scrolling (DECSDM). + Ps = 8 0 -> Enable Sixel Display Mode (DECSDM), VT330, + VT340, VT382. Ps = 9 5 -> Do not clear screen when DECCOLM is set/reset (DECNCSM), VT510 and up. Ps = 1 0 0 0 -> Send Mouse X & Y on button press and @@ -922,7 +923,9 @@ CSI ? Pm l VT420. This sets the backarrowKey resource to "false". Ps = 6 9 -> Disable left and right margin mode (DECLRMM), VT420 and up. - Ps = 8 0 -> Enable Sixel Scrolling (DECSDM). + Ps = 8 0 -> Disable Sixel Display Mode (DECSDM), VT330, + VT340, VT382. Turns on ``Sixel Scrolling''. See the section + Sixel Graphics and mode 8 4 5 2 . Ps = 9 5 -> Clear screen when DECCOLM is set/reset (DECNCSM), VT510 and up. Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and @@ -2387,6 +2390,10 @@ in text. When bracketed paste mode is set, the program will receive: ESC [ 2 0 0 ~ , followed by the pasted text, followed by ESC [ 2 0 1 ~ . +For background and discussion, see the FAQ: + + XTerm - bracketed-paste + Title Modes @@ -2724,25 +2731,26 @@ Sixel Graphics If xterm is configured as VT240, VT241, VT330, VT340 or VT382 using the decTerminalID or decGraphicsID resource, it supports Sixel Graphics -controls, a palleted bitmap graphics system using sets of six vertical +controls, a paletted bitmap graphics system using sets of six vertical pixels as the basic element. -CSI Ps c Send Device Attributes (Primary DA), xterm. xterm responds to - Send Device Attributes (Primary DA) with these additional - codes: +CSI Ps c Send Device Attributes (Primary DA), DEC graphics terminals, + xterm. xterm responds to Send Device Attributes (Primary DA) + with these additional codes: Ps = 4 -> Sixel graphics. CSI ? Pm h - Set Mode, xterm. xterm has these additional private Set Mode - values: - Ps = 8 0 -> Sixel scrolling. + Set Mode (with corresponding Reset Mode CSI ? Pm l ): + Ps = 8 0 -> Sixel Display Mode (DECSDM), VT330, VT340, + VT382. Ps = 1 0 7 0 -> use private color registers for each - graphic. + graphic, xterm. Ps = 8 4 5 2 -> Sixel scrolling leaves cursor to right of - graphic. + graphic, RLogin, xterm. DCS Pa ; Pb ; Ph q Ps..Ps ST - Send SIXEL image, DEC graphics terminals, xterm. See: + Send SIXEL image, DEC graphics terminals, VT330, VT340, VT382. + See: VT330/VT340 Programmer Reference Manual Volume 2: Graphics Programming @@ -2962,11 +2970,40 @@ o Sometimes the manuals are simply incorrect. For example, testing a DEC VT420 in 1996 showed that the documented code for a valid or invalid response to DECRQSS was reversed. - The VT420 test results were incorporated into vttest program. At - the time, DEC STD 070 was not available, but it also agrees with + The VT420 test results were incorporated into the vttest program. + At the time, DEC STD 070 was not available, but it also agrees with vttest. Later, documentation for the DEC VT525 was shown to have the same flaw. +o The VT330/VT340 reference manual for graphics programming documents + sixel graphics in some detail in chapter 14. Overlooked in the + first edition, the second edition mentions Sixel Scrolling. The + VT382 Kanji and Thai manuals provide less information, about sixel + graphics, but do mention DECSDM. They differ in their comment about + the private mode DECSDM (CSI ? 8 0 h ), which each manual agrees + should set the Sixel Scrolling feature. The VT330/VT340 graphics + programming manual (second edition, March 1988) says + + When sixel display mode is set, the Sixel Scrolling feature is + enabled. + When sixel display mode is reset, the Sixel Scrolling feature is + disabled. + + while the VT382 Kanji manual (page 6-6, undated) says + + Disable sixel scroll + + and the VT382 Thai manual (page C-30, August 1989) says + + No Sixel scrolling + + The standard (DEC STD 070) in chapter 9 (August 3, 1990) states on + page 17 that video devices will scroll when advancing the Sixel + active position past the bottom margin, but on page 19, in the + section on deviations, states that VT125 and VT240 did not scroll in + this situation. The standard does not mention VT330/VT340 or VT382. + Nor does it document DECSDM. + o Not all details are clear even in DEC STD 070 (which is more than twice the length of the VT520 programmer's reference manual, and almost three times longer than the VT420 reference manual). @@ -3018,7 +3055,7 @@ o VT330/VT340 Programmer Reference Manual o VT382 Kanji Display Terminal Programmer Reference Manual. - Digital Equipment Corporation (EK-VT382-RM-001). + Digital Equipment Corporation (EK-VT382-RM-001, undated). o VT382 Thai Display Terminal Installing and Using Manual. @@ -3138,31 +3175,6 @@ o The VT320, VT420, VT520 manuals claim that DECSCL does a hard reset Both the VT220 manual and DEC STD 070 (which documents levels 1-4 in detail) state that it is a soft reset, e.g., DECSTR. -o The VT330/VT340 reference manual for graphics programming documents - sixel scrolling in some detail in chapter 14. The VT382 Kanji and - Thai manuals provide less information, but differ in their comment - about the private mode DECSDM (CSI ? 8 0 h ), which each manual - agrees should set the Sixel Scrolling feature. However, the - VT330/VT340 manual says - - When sixel display mode is set, the Sixel Scrolling - feature is enabled. - - while the VT382 Kanji manual (page 6-6) says - - Disable sixel scroll - - and the VT382 Thai manual (page C-30) says - - No Sixel scrolling - - The standard (DEC STD 070) in chapter 9 (August 3, 1990) states on - page 17 that video devices will scroll when advancing the Sixel - active position past the bottom margin, but on page 19, in the - section on deviations, states that VT125 and VT240 did not scroll in - this situation. The standard does not mention VT330/VT340 or VT382. - Nor does it document DECSDM. - Here are the relevant standards: o Additional Controls for Use with American National Standard Code for @@ -3280,44 +3292,44 @@ o The SCOSC/SCORC control sequences for saving/restoring the cursor be used in termcap for vi, for example, to turn off saving of lines, but restore whatever the original state was on exit. - while the SCOSC/SCORC pair was added in 1995 by XFree86 (and + while the SCOSC/SCORC pair was added in 1995 by XFree86 (and documented long afterwards). - The SCO ANSI console terminal descriptions did not use these - controls (they used the VT100-compatible SC/RC pair). SCOSC/SCORC - were an artifact of DOS 2.00 (January 1983), by Microsoft and later + The SCO ANSI console terminal descriptions did not use these + controls (they used the VT100-compatible SC/RC pair). SCOSC/SCORC + were an artifact of DOS 2.00 (January 1983), by Microsoft and later supported by SCO and other vendors. - The SCOSC/SCORC pair is considered a private mode because the final + The SCOSC/SCORC pair is considered a private mode because the final characters (s and u ) fall in the range from "`" to "~" (octal 0140 - to octal 0176). Other private control sequences can be constructed + to octal 0176). Other private control sequences can be constructed by using octets 074 to 077 (characters "<", "=", ">", or "?") at the beginning of the parameter string. The XTSAVE and XTRESTORE controls use "?") in this manner. Because the XTSAVE and XTRESTORE controls are private, other - terminals may behave differently. For example, DEC (a contributor - to the early xterm as well as a manufacturer of terminals) used an - incompatible private control in one of its terminals more than five + terminals may behave differently. For example, DEC (a contributor + to the early xterm as well as a manufacturer of terminals) used an + incompatible private control in one of its terminals more than five years later (for the VT420 PCTerm, announced in February 1992). - In that model of the VT420, CSI ? Pm; Pc r selects the PC TERM - emulation mode. When this mode is enabled, the keyboard sends scan - codes rather than characters (analogous to X keyboard events). The - first parameter of this private control enables or disables PC TERM + In that model of the VT420, CSI ? Pm; Pc r selects the PC TERM + emulation mode. When this mode is enabled, the keyboard sends scan + codes rather than characters (analogous to X keyboard events). The + first parameter of this private control enables or disables PC TERM mode, while the second selects a character set. An ambiguity arises if an application omits the second parameter. In that special case, - it cannot be distinguished from XTRESTORE. DEC did not take this + it cannot be distinguished from XTRESTORE. DEC did not take this into account when designing the feature. - If there were potential users, xterm could accommodate this by a - resource setting. In retrospect (thirty years later), there have - been no uses of PC TERM, while the XTRESTORE feature is still in + If there were potential users, xterm could accommodate this by a + resource setting. In retrospect (thirty years later), there have + been no uses of PC TERM, while the XTRESTORE feature is still in use. o The aixterm manual page gives the format of the control sequence for - foreground and background colors 8-15, but does not specify what - those colors are. That is implied by the description's mention of + foreground and background colors 8-15, but does not specify what + those colors are. That is implied by the description's mention of HFT: The aixterm command provides a standard terminal type for @@ -3327,7 +3339,7 @@ o The aixterm manual page gives the format of the control sequence for the -v flag. Unlike xterm, there are no resource names for the 16 colors, leaving - the reader to assume that the mapping is hard-coded. The control - sequences for colors 8-15 are not specified by ECMA-48, but rather - (as done in other instances by xterm) chosen to not conflict with + the reader to assume that the mapping is hard-coded. The control + sequences for colors 8-15 are not specified by ECMA-48, but rather + (as done in other instances by xterm) chosen to not conflict with current or future standards. diff --git a/app/xterm/cursor.c b/app/xterm/cursor.c index 3234b7b66..6e22c0d6f 100644 --- a/app/xterm/cursor.c +++ b/app/xterm/cursor.c @@ -1,4 +1,4 @@ -/* $XTermId: cursor.c,v 1.82 2022/02/13 18:20:53 tom Exp $ */ +/* $XTermId: cursor.c,v 1.83 2022/09/23 08:13:43 tom Exp $ */ /* * Copyright 2002-2021,2022 by Thomas E. Dickey @@ -378,13 +378,14 @@ CursorSave(XtermWidget xw) * DEC 070 does mention the ANSI color text extension saying that it, too, is * saved/restored. */ +#define ALL_FLAGS (IFlags)(~0) #define DECSC_FLAGS (ATTRIBUTES|ORIGIN|PROTECTED) /* * Restore Cursor and Attributes */ -void -CursorRestore2(XtermWidget xw, SavedCursor * sc) +static void +CursorRestoreFlags(XtermWidget xw, SavedCursor * sc, IFlags our_flags) { TScreen *screen = TScreenOf(xw); @@ -399,8 +400,8 @@ CursorRestore2(XtermWidget xw, SavedCursor * sc) resetCharsets(screen); } - UIntClr(xw->flags, DECSC_FLAGS); - UIntSet(xw->flags, sc->flags & DECSC_FLAGS); + UIntClr(xw->flags, our_flags); + UIntSet(xw->flags, sc->flags & our_flags); if ((xw->flags & ORIGIN)) { CursorSet(screen, sc->row - screen->top_marg, @@ -421,11 +422,23 @@ CursorRestore2(XtermWidget xw, SavedCursor * sc) #endif } +/* + * Use this entrypoint for the status-line. + */ +void +CursorRestore2(XtermWidget xw, SavedCursor * sc) +{ + CursorRestoreFlags(xw, sc, ALL_FLAGS); +} + +/* + * Use this entrypoint for the VT100 window. + */ void CursorRestore(XtermWidget xw) { TScreen *screen = TScreenOf(xw); - CursorRestore2(xw, &screen->sc[screen->whichBuf]); + CursorRestoreFlags(xw, &screen->sc[screen->whichBuf], DECSC_FLAGS); } /* diff --git a/app/xterm/doublechr.c b/app/xterm/doublechr.c index a802e32b9..3b5bcd33e 100644 --- a/app/xterm/doublechr.c +++ b/app/xterm/doublechr.c @@ -1,7 +1,7 @@ -/* $XTermId: doublechr.c,v 1.104 2020/12/10 19:43:26 tom Exp $ */ +/* $XTermId: doublechr.c,v 1.107 2022/05/05 22:23:43 tom Exp $ */ /* - * Copyright 1997-2019,2020 by Thomas E. Dickey + * Copyright 1997-2021,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -342,19 +342,19 @@ xterm_DoubleGC(XTermDraw * params, GC old_gc, int *inxp) /* * Like xterm_DoubleGC(), but returning an Xft font. */ -XftFont * +XTermXftFonts * xterm_DoubleFT(XTermDraw * params, unsigned chrset, unsigned attr_flags) { - XftFont *result; + XTermXftFonts *result; TScreen *screen = TScreenOf(params->xw); unsigned num = (chrset & CSET_DWL); if ((attr_flags &= BOLD) != 0) num |= 4; - if ((result = screen->double_xft_fonts[num]) == 0) { - result = getDoubleXftFont(params, chrset, attr_flags); - screen->double_xft_fonts[num] = result; + result = &screen->double_xft_fonts[num]; + if (XftFp(result) == NULL) { + getDoubleXftFont(params, result, chrset, attr_flags); } return result; } @@ -366,8 +366,9 @@ freeall_DoubleFT(XtermWidget xw) unsigned num; for (num = 0; num < XtNumber(screen->double_xft_fonts); ++num) { - closeCachedXft(screen, screen->double_xft_fonts[num]); - screen->double_xft_fonts[num] = 0; + closeCachedXft(screen, XftFp(&screen->double_xft_fonts[num])); + XftFp(&screen->double_xft_fonts[num]) = NULL; + XftIs(&screen->double_xft_fonts[num]) = xcEmpty; } } #endif /* OPT_RENDERFONT */ diff --git a/app/xterm/fontutils.c b/app/xterm/fontutils.c index 1646b4be0..1ac797bd3 100644 --- a/app/xterm/fontutils.c +++ b/app/xterm/fontutils.c @@ -1,4 +1,4 @@ -/* $XTermId: fontutils.c,v 1.712 2022/02/23 00:46:08 tom Exp $ */ +/* $XTermId: fontutils.c,v 1.743 2022/10/06 23:48:16 tom Exp $ */ /* * Copyright 1998-2021,2022 by Thomas E. Dickey @@ -51,6 +51,16 @@ #include <stdio.h> #include <ctype.h> +#define USE_FC_COLOR 0 +#if OPT_RENDERFONT +#if XftVersion > 20304 +#undef USE_FC_COLOR +#define USE_FC_COLOR 1 +#endif +#endif + +#define FcOK(func) (func == FcResultMatch) + #define NoFontWarning(data) (data)->warn = fwAlways #define SetFontWidth(screen,dst,src) (dst)->f_width = (src) @@ -159,8 +169,24 @@ static void save2FontList(XtermWidget, const char *, XtermFontNames *, static void fillInFaceSize(XtermWidget, int); #endif -#if OPT_SHIFT_FONTS -static int lookupOneFontSize(XtermWidget, int); +#if OPT_REPORT_FONTS && OPT_TRACE +static void +report_fonts(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + va_end(ap); +#if OPT_TRACE + va_start(ap, fmt); + TraceVA(fmt, ap); + va_end(ap); +#endif +} + +#define ReportFonts report_fonts +#else +#define ReportFonts printf #endif #if OPT_TRACE @@ -240,7 +266,7 @@ setupPackedFonts(XtermWidget xw) for (e = 0; e < fMAX; ++e) { XTermXftFonts *data = getMyXftFont(xw, e, screen->menu_font_number); if (data != 0) { - if (data->map.mixed) { + if (data->font_info.mixed) { screen->allow_packing = True; break; } @@ -559,7 +585,7 @@ italic_font_name(FontNameProperties *props, const char *slant) static Boolean open_italic_font(XtermWidget xw, int n, FontNameProperties *fp, XTermFonts * data) { - static const char *slant[] = + static const char *const slant[] = { "o", "i" @@ -577,9 +603,9 @@ open_italic_font(XtermWidget xw, int n, FontNameProperties *fp, XTermFonts * dat result = (data->fs != 0); #if OPT_REPORT_FONTS if (resource.reportFonts) { - printf("opened italic version of %s:\n\t%s\n", - whichFontEnum((VTFontEnum) n), - name); + ReportFonts("opened italic version of %s:\n\t%s\n", + whichFontEnum((VTFontEnum) n), + name); } #endif } @@ -1157,12 +1183,12 @@ xtermFreeFontInfo(XTermFonts * target) static void reportXCharStruct(const char *tag, XCharStruct * cs) { - printf("\t\t%s:\n", tag); - printf("\t\t\tlbearing: %d\n", cs->lbearing); - printf("\t\t\trbearing: %d\n", cs->rbearing); - printf("\t\t\twidth: %d\n", cs->width); - printf("\t\t\tascent: %d\n", cs->ascent); - printf("\t\t\tdescent: %d\n", cs->descent); + ReportFonts("\t\t%s:\n", tag); + ReportFonts("\t\t\tlbearing: %d\n", cs->lbearing); + ReportFonts("\t\t\trbearing: %d\n", cs->rbearing); + ReportFonts("\t\t\twidth: %d\n", cs->width); + ReportFonts("\t\t\tascent: %d\n", cs->ascent); + ReportFonts("\t\t\tdescent: %d\n", cs->descent); } static void @@ -1182,18 +1208,20 @@ reportOneVTFont(const char *tag, last_char = (fs->max_byte1 * 256) + fs->max_char_or_byte2; } - printf("\t%s: %s\n", tag, NonNull(fnt->fn)); - printf("\t\tall chars: %s\n", fs->all_chars_exist ? "yes" : "no"); - printf("\t\tdefault char: %d\n", fs->default_char); - printf("\t\tdirection: %d\n", fs->direction); - printf("\t\tascent: %d\n", fs->ascent); - printf("\t\tdescent: %d\n", fs->descent); - printf("\t\tfirst char: %u\n", first_char); - printf("\t\tlast char: %u\n", last_char); - printf("\t\tmaximum-chars: %u\n", countGlyphs(fs)); + ReportFonts("\t%s: %s\n", tag, NonNull(fnt->fn)); + ReportFonts("\t\tall chars: %s\n", (fs->all_chars_exist + ? "yes" + : "no")); + ReportFonts("\t\tdefault char: %d\n", fs->default_char); + ReportFonts("\t\tdirection: %d\n", fs->direction); + ReportFonts("\t\tascent: %d\n", fs->ascent); + ReportFonts("\t\tdescent: %d\n", fs->descent); + ReportFonts("\t\tfirst char: %u\n", first_char); + ReportFonts("\t\tlast char: %u\n", last_char); + ReportFonts("\t\tmaximum-chars: %u\n", countGlyphs(fs)); if (FontLacksMetrics(fnt)) { - printf("\t\tmissing-chars: ?\n"); - printf("\t\tpresent-chars: ?\n"); + ReportFonts("\t\tmissing-chars: ?\n"); + ReportFonts("\t\tpresent-chars: ?\n"); } else { unsigned missing = 0; unsigned ch; @@ -1202,12 +1230,12 @@ reportOneVTFont(const char *tag, ++missing; } } - printf("\t\tmissing-chars: %u\n", missing); - printf("\t\tpresent-chars: %u\n", countGlyphs(fs) - missing); + ReportFonts("\t\tmissing-chars: %u\n", missing); + ReportFonts("\t\tpresent-chars: %u\n", countGlyphs(fs) - missing); } - printf("\t\tmin_byte1: %d\n", fs->min_byte1); - printf("\t\tmax_byte1: %d\n", fs->max_byte1); - printf("\t\tproperties: %d\n", fs->n_properties); + ReportFonts("\t\tmin_byte1: %d\n", fs->min_byte1); + ReportFonts("\t\tmax_byte1: %d\n", fs->max_byte1); + ReportFonts("\t\tproperties: %d\n", fs->n_properties); reportXCharStruct("min_bounds", &(fs->min_bounds)); reportXCharStruct("max_bounds", &(fs->max_bounds)); /* TODO: report fs->properties and fs->per_char */ @@ -1221,9 +1249,9 @@ reportVTFontInfo(XtermWidget xw, int fontnum) TScreen *screen = TScreenOf(xw); if (fontnum) { - printf("Loaded VTFonts(font%d)\n", fontnum); + ReportFonts("Loaded VTFonts(font%d)\n", fontnum); } else { - printf("Loaded VTFonts(default)\n"); + ReportFonts("Loaded VTFonts(default)\n"); } reportOneVTFont("fNorm", GetNormalFont(screen, fNorm)); @@ -2351,22 +2379,22 @@ xtermSetCursorBox(TScreen *screen) #if OPT_RENDERFONT -#define CACHE_XFT(dst,src) if (src.font != 0) {\ - int err = checkXftWidth(xw, &(dst[fontnum]), &src);\ +#define CACHE_XFT(data) if (XftFp(data) != NULL) {\ + int err = checkXftWidth(xw, data);\ TRACE(("Xft metrics %s[%d] = %d (%d,%d)%s advance %d, actual %d%s%s\n",\ - #dst,\ + #data,\ fontnum,\ - src.font->height,\ - src.font->ascent,\ - src.font->descent,\ - ((src.font->ascent + src.font->descent) > src.font->height ? "*" : ""),\ - src.font->max_advance_width,\ - dst[fontnum].map.min_width,\ - dst[fontnum].map.mixed ? " mixed" : "",\ + XftFp(data)->height,\ + XftFp(data)->ascent,\ + XftFp(data)->descent,\ + ((XftFp(data)->ascent + XftFp(data)->descent) > XftFp(data)->height ? "*" : ""),\ + XftFp(data)->max_advance_width,\ + data->font_info.min_width,\ + data->font_info.mixed ? " mixed" : "",\ err ? " ERROR" : ""));\ if (err) {\ - xtermCloseXft(screen, &src);\ - memset((&dst[fontnum]), 0, sizeof(dst[fontnum]));\ + xtermCloseXft(screen, data);\ + memset((data), 0, sizeof(*data));\ failed += err;\ }\ } @@ -2398,12 +2426,12 @@ xtermXftFirstChar(XftFont *xft) static FcChar32 xtermXftLastChar(XftFont *xft) { - FcChar32 this, last, next; + FcChar32 temp, last, next; FcChar32 map[FC_CHARSET_MAP_SIZE]; int i; last = FcCharSetFirstPage(xft->charset, map, &next); - while ((this = FcCharSetNextPage(xft->charset, map, &next)) != FC_CHARSET_DONE) - last = this; + while ((temp = FcCharSetNextPage(xft->charset, map, &next)) != FC_CHARSET_DONE) + last = temp; last &= (FcChar32) ~ 0xff; for (i = FC_CHARSET_MAP_SIZE - 1; i >= 0; i--) { if (map[i]) { @@ -2435,7 +2463,7 @@ convertToUTF8(Char *buffer, int c) static void dumpXft(XtermWidget xw, XTermXftFonts *data) { - XftFont *xft = data->font; + XftFont *xft = XftFp(data); TScreen *screen = TScreenOf(xw); VTwin *win = WhichVWin(screen); @@ -2504,7 +2532,7 @@ dumpXft(XtermWidget xw, XTermXftFonts *data) */ #ifdef FC_COLOR #define GetFcBool(pattern, what) \ - (FcPatternGetBool(pattern, what, 0, &fcbogus) == FcResultMatch) + FcOK(FcPatternGetBool(pattern, what, 0, &fcbogus)) static Boolean isBogusXft(XftFont *font) @@ -2514,7 +2542,9 @@ isBogusXft(XftFont *font) FcBool fcbogus; if (GetFcBool(font->pattern, FC_COLOR) && fcbogus) { TRACE(("...matched color-bitmap font\n")); +#if !USE_FC_COLOR result = True; +#endif } else if (GetFcBool(font->pattern, FC_OUTLINE) && !fcbogus) { TRACE(("...matched non-outline font\n")); /* This is legal for regular bitmap fonts - fontconfig attempts to @@ -2549,11 +2579,11 @@ checkedXftWidth(Display *dpy, { Boolean result = False; - if (FcCharSetHasChar(source->font->charset, c)) { + if (FcCharSetHasChar(XftFp(source)->charset, c)) { XGlyphInfo extents; result = True; - XftTextExtents32(dpy, source->font, &c, 1, &extents); + XftTextExtents32(dpy, XftFp(source), &c, 1, &extents); if (*width < extents.width && extents.width <= limit) { *width = extents.width; } @@ -2562,11 +2592,11 @@ checkedXftWidth(Display *dpy, } static int -checkXftWidth(XtermWidget xw, XTermXftFonts *target, XTermXftFonts *source) +checkXftWidth(XtermWidget xw, XTermXftFonts *data) { FcChar32 c; - FcChar32 last = xtermXftLastChar(source->font); - Dimension limit = (Dimension) source->font->max_advance_width; + FcChar32 last = xtermXftLastChar(XftFp(data)); + Dimension limit = (Dimension) XftFp(data)->max_advance_width; Dimension width = 0; Dimension width2 = 0; int failed = 0; @@ -2574,10 +2604,8 @@ checkXftWidth(XtermWidget xw, XTermXftFonts *target, XTermXftFonts *source) Cardinal n; #endif - target->font = source->font; - target->pattern = source->pattern; - target->map.min_width = 0; - target->map.max_width = limit; + data->font_info.min_width = 0; + data->font_info.max_width = limit; #if OPT_WIDE_CHARS /* @@ -2586,7 +2614,7 @@ checkXftWidth(XtermWidget xw, XTermXftFonts *target, XTermXftFonts *source) */ for (n = 0; n < XtNumber(unicode_boxes) - 1; ++n) { if (!checkedXftWidth(XtDisplay(xw), - source, + data, limit, &width2, unicode_boxes[n].code)) { width2 = 0; @@ -2628,10 +2656,10 @@ checkXftWidth(XtermWidget xw, XTermXftFonts *target, XTermXftFonts *source) for (c = 32; c < 256; ++c) { if (CharWidth(TScreenOf(xw), c) <= 0) continue; - if (FcCharSetHasChar(source->font->charset, c)) { + if (FcCharSetHasChar(XftFp(data)->charset, c)) { (void) checkedXftWidth(XtDisplay(xw), - source, - target->map.max_width, + data, + data->font_info.max_width, &width, c); } } @@ -2643,17 +2671,20 @@ checkXftWidth(XtermWidget xw, XTermXftFonts *target, XTermXftFonts *source) if (width == 0) { failed = 1; if (last >= 256) { - width = target->map.max_width; + width = data->font_info.max_width; } } - target->map.min_width = width; - target->map.mixed = (target->map.max_width >= (target->map.min_width + 1)); + data->font_info.min_width = width; + data->font_info.mixed = (data->font_info.max_width >= + (data->font_info.min_width + 1)); return failed; } #if OPT_REPORT_FONTS static void reportXftFonts(XtermWidget xw, + XTermXftFonts *fontData, + int fontNum, XftFont *fp, const char *name, const char *tag, @@ -2666,23 +2697,24 @@ reportXftFonts(XtermWidget xw, FcChar32 ch; unsigned missing = 0; - printf("Loaded XftFonts(%s[%s])\n", name, tag); + ReportFonts("Loaded XftFonts(%s[%s])\n", name, tag); for (ch = first_char; ch <= last_char; ++ch) { - if (xtermXftMissing(xw, fp, ch)) { + if (xtermXftMissing(xw, fontData, fontNum, fp, ch)) { ++missing; } } - printf("\t\tfirst char: %u\n", first_char); - printf("\t\tlast char: %u\n", last_char); - printf("\t\tmissing-chars: %u\n", missing); - printf("\t\tpresent-chars: %u\n", (last_char - first_char) + 1 - missing); + ReportFonts("\t\tfirst char: %u\n", first_char); + ReportFonts("\t\tlast char: %u\n", last_char); + ReportFonts("\t\tmissing-chars: %u\n", missing); + ReportFonts("\t\tpresent-chars: %u\n", ((last_char - first_char) + + 1 - missing)); if (XftNameUnparse(match, buffer, (int) sizeof(buffer))) { char *target; char *source = buffer; while ((target = strtok(source, ":")) != 0) { - printf("\t%s\n", target); + ReportFonts("\t%s\n", target); source = 0; } } @@ -2690,7 +2722,7 @@ reportXftFonts(XtermWidget xw, } } #else -#define reportXftFonts(xw, result, name, tag, match) /* empty */ +#define reportXftFonts(xw, fontData, fontNum, result, name, tag, match) /* empty */ #endif /* OPT_REPORT_FONTS */ /* @@ -2706,10 +2738,10 @@ Boolean maybeXftCache(XtermWidget xw, XftFont *font) { Boolean result = False; - if (font != 0) { + if (font != NULL) { TScreen *screen = TScreenOf(xw); ListXftFonts *p; - for (p = screen->list_xft_fonts; p != 0; p = p->next) { + for (p = screen->list_xft_fonts; p != NULL; p = p->next) { if (p->font == font) { result = True; break; @@ -2717,7 +2749,7 @@ maybeXftCache(XtermWidget xw, XftFont *font) } if (!result) { p = TypeXtMalloc(ListXftFonts); - if (p != 0) { + if (p != NULL) { p->font = font; p->next = screen->list_xft_fonts; screen->list_xft_fonts = p; @@ -2751,8 +2783,13 @@ closeCachedXft(TScreen *screen, XftFont *font) } } -static XftFont * -xtermOpenXft(XtermWidget xw, const char *name, XftPattern *pat, const char *tag) +static void +xtermOpenXft(XtermWidget xw, + XTermXftFonts *fontData, + int fontNum, + const char *name, + XftPattern *pat, + const char *tag) { TScreen *screen = TScreenOf(xw); Display *dpy = screen->display; @@ -2771,18 +2808,22 @@ xtermOpenXft(XtermWidget xw, const char *name, XftPattern *pat, const char *tag) Boolean maybeReopened = False; result = XftFontOpenPattern(dpy, match); #ifdef FC_COLOR - if (result != 0) { + if (result != NULL) { if (isBogusXft(result)) { XftFontClose(dpy, result); - result = 0; + result = NULL; maybeReopened = True; } } #endif - if (result != 0) { + if (result != NULL) { TRACE(("...matched %s font\n", tag)); + if (fontData->fs_size <= (unsigned) fontNum) + fontData->fs_size = (unsigned) (fontNum + 1); + XftFpN(fontData, fontNum) = result; + XftIsN(fontData, fontNum) = xcOpened; if (!maybeXftCache(xw, result)) { - reportXftFonts(xw, result, name, tag, match); + reportXftFonts(xw, fontData, fontNum, result, name, tag, match); } } else { TRACE(("...could not open %s font\n", tag)); @@ -2799,7 +2840,10 @@ xtermOpenXft(XtermWidget xw, const char *name, XftPattern *pat, const char *tag) } } } - return result; + if (result == NULL) { + XftFpN(fontData, fontNum) = NULL; + XftIsN(fontData, fontNum) = xcEmpty; + } } #if OPT_SHIFT_FONTS @@ -2829,9 +2873,9 @@ dimSquareRoot(double value) #ifdef DEBUG_XFT static void -trace_xft_glyph(TScreen *screen, XftFont *font, FT_Face face, int code, const char *name) +trace_xft_glyph(XtermWidget xw, XTermXftFonts *data, FT_Face face, int code, const char *name) { - if (!XftGlyphExists(screen->display, font, code)) { + if (xtermXftMissing(xw, data, 0, XftFp(data), code)) { TRACE(("Xft glyph U+%04X missing :%s\n", code, name)); } else if (FT_Load_Char(face, code, FT_LOAD_RENDER) == 0) { FT_GlyphSlot g = face->glyph; @@ -2845,16 +2889,16 @@ trace_xft_glyph(TScreen *screen, XftFont *font, FT_Face face, int code, const ch #if OPT_WIDE_CHARS static void -trace_xft_line_drawing(TScreen *screen, XftFont *font, FT_Face face) +trace_xft_line_drawing(XtermWidget xw, XTermXftFonts *data, FT_Face face) { int n; for (n = 0; unicode_boxes[n].code != 0; ++n) { - trace_xft_glyph(screen, font, face, unicode_boxes[n].code, + trace_xft_glyph(xw, data, face, unicode_boxes[n].code, unicode_boxes[n].name); } } #else -#define trace_xft_line_drawing(screen, font, face) /* nothing */ +#define trace_xft_line_drawing(xw, data, face) /* nothing */ #endif #endif /* DEBUG_XFT */ @@ -2864,7 +2908,7 @@ trace_xft_line_drawing(TScreen *screen, XftFont *font, FT_Face face) */ #if OPT_BOX_CHARS static void -linedrawing_gaps(XtermWidget xw, XftFont *font) +linedrawing_gaps(XtermWidget xw, XTermXftFonts *data) { Boolean broken; @@ -2872,12 +2916,12 @@ linedrawing_gaps(XtermWidget xw, XftFont *font) TScreen *screen = TScreenOf(xw); int n; FT_Face face; - face = XftLockFace(font); + face = XftLockFace(XftFp(data)); broken = False; for (n = 0; unicode_boxes[n].code; ++n) { unsigned code = unicode_boxes[n].code; - if (!XftGlyphExists(screen->display, font, code)) { + if (xtermXftMissing(xw, data, 0, XftFp(data), code)) { TRACE(("Xft glyph U+%04X is missing\n", code)); broken = True; break; @@ -2901,7 +2945,7 @@ linedrawing_gaps(XtermWidget xw, XftFont *font) if (code == 0x2502) { unsigned r, c; unsigned mids = 0, ends = 0; - unsigned char *data = g->bitmap.buffer; + unsigned char *buffer = g->bitmap.buffer; switch (g->bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: @@ -2914,11 +2958,11 @@ linedrawing_gaps(XtermWidget xw, XftFont *font) unsigned xx = 0; switch (g->bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: - xx = (unsigned) ((data[k + (c / 8)] + xx = (unsigned) ((buffer[k + (c / 8)] >> (c % 8)) & 1); break; case FT_PIXEL_MODE_GRAY: - xx = data[k + c]; + xx = buffer[k + c]; break; } sum += xx; @@ -2988,9 +3032,9 @@ linedrawing_gaps(XtermWidget xw, XftFont *font) break; } } - XftUnlockFace(font); + XftUnlockFace(XftFp(data)); #else - (void) font; + (void) data; broken = True; #endif @@ -3007,9 +3051,10 @@ linedrawing_gaps(XtermWidget xw, XftFont *font) * rule. */ static void -setRenderFontsize(XtermWidget xw, VTwin *win, XftFont *font, const char *tag) +setRenderFontsize(XtermWidget xw, VTwin *win, XTermXftFonts *data, const char *tag) { - if (font != 0) { + XftFont *font = XftFp(data); + if (font != NULL) { TScreen *screen = TScreenOf(xw); int width, height, ascent, descent; #ifdef DEBUG_XFT @@ -3026,11 +3071,11 @@ setRenderFontsize(XtermWidget xw, VTwin *win, XftFont *font, const char *tag) metrics = size->metrics; is_fixed = FT_IS_FIXED_WIDTH(face); scalable = FT_IS_SCALABLE(face); - trace_xft_line_drawing(screen, font, face); + trace_xft_line_drawing(xw, data, face); for (n = 32; n < 127; ++n) { char name[80]; sprintf(name, "letter \"%c\"", n); - trace_xft_glyph(screen, font, face, n, name); + trace_xft_glyph(xw, data, face, n, name); } XftUnlockFace(font); @@ -3122,7 +3167,7 @@ setRenderFontsize(XtermWidget xw, VTwin *win, XftFont *font, const char *tag) } #if OPT_BOX_CHARS if (!screen->broken_box_chars && (tag == 0)) { - linedrawing_gaps(xw, font); + linedrawing_gaps(xw, data); } #endif } @@ -3146,29 +3191,27 @@ checkFontInfo(int value, const char *tag, int failed) void xtermCloseXft(TScreen *screen, XTermXftFonts *pub) { - if (pub->font != 0) { + if (XftFp(pub) != NULL) { Cardinal n; - closeCachedXft(screen, pub->font); - pub->font = 0; - if (pub->pattern) { XftPatternDestroy(pub->pattern); - pub->pattern = 0; + pub->pattern = NULL; } if (pub->fontset) { XftFontSetDestroy(pub->fontset); - pub->fontset = 0; + pub->fontset = NULL; } - for (n = 0; n < pub->limit; ++n) { - if (pub->cache[n].font) { - closeCachedXft(screen, pub->cache[n].font); - pub->cache[n].font = 0; + for (n = 0; n < pub->fs_size; ++n) { + if (XftFpN(pub, n) != NULL) { + closeCachedXft(screen, XftFpN(pub, n)); + XftFpN(pub, n) = NULL; + XftIsN(pub, n) = xcEmpty; } } - free(pub->cache); - pub->cache = NULL; + FreeAndNull(pub->font_map.per_font); + memset(pub, 0, sizeof(*pub)); } } @@ -3242,18 +3285,19 @@ xtermComputeFontInfo(XtermWidget xw, */ if (UsingRenderFont(xw) && fontnum >= 0) { String face_name = getFaceName(xw, False); - XTermXftFonts norm = screen->renderFontNorm[fontnum]; - XTermXftFonts bold = screen->renderFontBold[fontnum]; - XTermXftFonts ital = screen->renderFontItal[fontnum]; - XTermXftFonts btal = screen->renderFontBtal[fontnum]; + XTermXftFonts *norm = &(screen->renderFontNorm[fontnum]); + XTermXftFonts *bold = &(screen->renderFontBold[fontnum]); + XTermXftFonts *ital = &(screen->renderFontItal[fontnum]); + XTermXftFonts *btal = &(screen->renderFontBtal[fontnum]); #if OPT_RENDERWIDE - XTermXftFonts wnorm = screen->renderWideNorm[fontnum]; - XTermXftFonts wbold = screen->renderWideBold[fontnum]; - XTermXftFonts wital = screen->renderWideItal[fontnum]; - XTermXftFonts wbtal = screen->renderWideBtal[fontnum]; + XTermXftFonts *wnorm = &(screen->renderWideNorm[fontnum]); + XTermXftFonts *wbold = &(screen->renderWideBold[fontnum]); + XTermXftFonts *wital = &(screen->renderWideItal[fontnum]); + XTermXftFonts *wbtal = &(screen->renderWideBtal[fontnum]); #endif - if (norm.font == 0 && !IsEmpty(face_name)) { + if (XftFp(norm) == 0 && !IsEmpty(face_name)) { + Work *work = &(xw->work); XftPattern *pat; double face_size; @@ -3261,9 +3305,33 @@ xtermComputeFontInfo(XtermWidget xw, fontnum, face_name, xw->misc.face_size[fontnum])); - TRACE(("Using Xft %d\n", XftVersion)); + TRACE(("Using Xft %d\n", XftGetVersion())); TRACE(("Using FontConfig %d\n", FC_VERSION)); + if (work->xft_defaults == NULL) { + FcInit(); + work->xft_defaults = FcPatternCreate(); + XftDefaultSubstitute(screen->display, + XScreenNumberOfScreen(XtScreen(xw)), + work->xft_defaults); + if (screen->xft_max_glyph_memory > 0) { + FcPatternAddInteger(work->xft_defaults, + XFT_MAX_GLYPH_MEMORY, + screen->xft_max_glyph_memory); + } + if (screen->xft_max_unref_fonts > 0) { + FcPatternAddInteger(work->xft_defaults, + XFT_MAX_UNREF_FONTS, + screen->xft_max_unref_fonts); + } +#ifdef XFT_TRACK_MEM_USAGE + FcPatternAddBool(work->xft_defaults, + XFT_TRACK_MEM_USAGE, + screen->xft_track_mem_usage); +#endif + XftDefaultSet(screen->display, work->xft_defaults); + } + fillInFaceSize(xw, fontnum); face_size = (double) xw->misc.face_size[fontnum]; @@ -3273,11 +3341,18 @@ xtermComputeFontInfo(XtermWidget xw, * normal pattern. */ #ifdef FC_COLOR +#if USE_FC_COLOR +#define NormXftPattern \ + XFT_FAMILY, XftTypeString, "mono", \ + FC_OUTLINE, XftTypeBool, FcTrue, \ + XFT_SIZE, XftTypeDouble, face_size +#else #define NormXftPattern \ XFT_FAMILY, XftTypeString, "mono", \ FC_COLOR, XftTypeBool, FcFalse, \ FC_OUTLINE, XftTypeBool, FcTrue, \ XFT_SIZE, XftTypeDouble, face_size +#endif #else #define NormXftPattern \ XFT_FAMILY, XftTypeString, "mono", \ @@ -3286,16 +3361,16 @@ xtermComputeFontInfo(XtermWidget xw, #define BoldXftPattern(norm) \ XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD, \ - XFT_CHAR_WIDTH, XftTypeInteger, norm.font->max_advance_width + XFT_CHAR_WIDTH, XftTypeInteger, XftFp(norm)->max_advance_width #define ItalXftPattern(norm) \ XFT_SLANT, XftTypeInteger, XFT_SLANT_ITALIC, \ - XFT_CHAR_WIDTH, XftTypeInteger, norm.font->max_advance_width + XFT_CHAR_WIDTH, XftTypeInteger, XftFp(norm)->max_advance_width #define BtalXftPattern(norm) \ XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD, \ XFT_SLANT, XftTypeInteger, XFT_SLANT_ITALIC, \ - XFT_CHAR_WIDTH, XftTypeInteger, norm.font->max_advance_width + XFT_CHAR_WIDTH, XftTypeInteger, XftFp(norm)->max_advance_width #if OPT_WIDE_ATTRS #define HAVE_ITALICS 1 @@ -3311,16 +3386,16 @@ xtermComputeFontInfo(XtermWidget xw, freeall_DoubleFT(xw); #endif if ((pat = XftNameParse(face_name)) != 0) { -#define OPEN_XFT(name, tag) name.font = xtermOpenXft(xw, face_name, name.pattern, tag) - norm.pattern = XftPatternDuplicate(pat); - XftPatternBuild(norm.pattern, +#define OPEN_XFT(data, tag) xtermOpenXft(xw, data, 0, face_name, data->pattern, tag) + norm->pattern = XftPatternDuplicate(pat); + XftPatternBuild(norm->pattern, NormXftPattern, (void *) 0); OPEN_XFT(norm, "normal"); - if (norm.font != 0) { - bold.pattern = XftPatternDuplicate(pat); - XftPatternBuild(bold.pattern, + if (XftFp(norm) != 0) { + bold->pattern = XftPatternDuplicate(pat); + XftPatternBuild(bold->pattern, NormXftPattern, BoldXftPattern(norm), (void *) 0); @@ -3328,14 +3403,14 @@ xtermComputeFontInfo(XtermWidget xw, #if HAVE_ITALICS if (FIND_ITALICS) { - ital.pattern = XftPatternDuplicate(pat); - XftPatternBuild(ital.pattern, + ital->pattern = XftPatternDuplicate(pat); + XftPatternBuild(ital->pattern, NormXftPattern, ItalXftPattern(norm), (void *) 0); OPEN_XFT(ital, "italic"); - btal.pattern = XftPatternDuplicate(pat); - XftPatternBuild(btal.pattern, + btal->pattern = XftPatternDuplicate(pat); + XftPatternBuild(btal->pattern, NormXftPattern, BtalXftPattern(norm), (void *) 0); @@ -3354,61 +3429,60 @@ xtermComputeFontInfo(XtermWidget xw, } } - CACHE_XFT(screen->renderFontNorm, norm); + CACHE_XFT(norm); - CACHE_XFT(screen->renderFontBold, bold); - if (norm.font != 0 && !bold.font) { + CACHE_XFT(bold); + if (XftFp(norm) != 0 && !XftFp(bold)) { noUsableXft(xw, "bold"); - XftPatternDestroy(bold.pattern); - bold.pattern = XftPatternDuplicate(pat); - XftPatternBuild(bold.pattern, + XftPatternDestroy(bold->pattern); + bold->pattern = XftPatternDuplicate(pat); + XftPatternBuild(bold->pattern, NormXftPattern, (void *) 0); OPEN_XFT(bold, "bold"); failed = 0; - CACHE_XFT(screen->renderFontBold, bold); + CACHE_XFT(bold); } #if HAVE_ITALICS - CACHE_XFT(screen->renderFontItal, ital); - if (norm.font != 0 && !ital.font) { + CACHE_XFT(ital); + if (XftFp(norm) != 0 && !XftFp(ital)) { noUsableXft(xw, "italic"); - XftPatternDestroy(ital.pattern); - ital.pattern = XftPatternDuplicate(pat); - XftPatternBuild(ital.pattern, + XftPatternDestroy(ital->pattern); + ital->pattern = XftPatternDuplicate(pat); + XftPatternBuild(ital->pattern, NormXftPattern, (void *) 0); OPEN_XFT(ital, "italics"); failed = 0; - CACHE_XFT(screen->renderFontItal, ital); + CACHE_XFT(ital); } - CACHE_XFT(screen->renderFontBtal, btal); - if (norm.font != 0 && !btal.font) { + CACHE_XFT(btal); + if (XftFp(norm) != 0 && !XftFp(btal)) { noUsableXft(xw, "bold italic"); - XftPatternDestroy(btal.pattern); - btal.pattern = XftPatternDuplicate(pat); - XftPatternBuild(btal.pattern, + XftPatternDestroy(btal->pattern); + btal->pattern = XftPatternDuplicate(pat); + XftPatternBuild(btal->pattern, NormXftPattern, (void *) 0); OPEN_XFT(btal, "bold-italics"); failed = 0; - CACHE_XFT(screen->renderFontBtal, btal); + CACHE_XFT(btal); } #endif XftPatternDestroy(pat); } else { failed = 1; } -#undef OPEN_XFT /* * See xtermXftDrawString(). A separate double-width font is nice * to have, but not essential. */ #if OPT_RENDERWIDE - if (norm.font != 0 && screen->wide_chars) { - int char_width = norm.font->max_advance_width * 2; + if (XftFp(norm) != 0 && screen->wide_chars) { + int char_width = XftFp(norm)->max_advance_width * 2; double aspect = ((FirstItemOf(xw->work.fonts.xft.list_w) - || screen->renderFontNorm[fontnum].map.mixed) + || screen->renderFontNorm[fontnum].font_info.mixed) ? 1.0 : 2.0); @@ -3426,16 +3500,15 @@ xtermComputeFontInfo(XtermWidget xw, if (!IsEmpty(face_name) && (pat = XftNameParse(face_name)) != 0) { -#define OPEN_XFT(name, tag) name.font = xtermOpenXft(xw, face_name, name.pattern, tag) - wnorm.pattern = XftPatternDuplicate(pat); - XftPatternBuild(wnorm.pattern, + wnorm->pattern = XftPatternDuplicate(pat); + XftPatternBuild(wnorm->pattern, WideXftPattern, (void *) 0); OPEN_XFT(wnorm, "wide"); - if (wnorm.font != 0) { - wbold.pattern = XftPatternDuplicate(pat); - XftPatternBuild(wbold.pattern, + if (XftFp(wnorm) != 0) { + wbold->pattern = XftPatternDuplicate(pat); + XftPatternBuild(wbold->pattern, WideXftPattern, BoldXftPattern(wnorm), (void *) 0); @@ -3443,54 +3516,54 @@ xtermComputeFontInfo(XtermWidget xw, #if HAVE_ITALICS if (FIND_ITALICS) { - wital.pattern = XftPatternDuplicate(pat); - XftPatternBuild(wital.pattern, + wital->pattern = XftPatternDuplicate(pat); + XftPatternBuild(wital->pattern, WideXftPattern, ItalXftPattern(wnorm), (void *) 0); OPEN_XFT(wital, "wide-italic"); } - CACHE_XFT(screen->renderWideBtal, wbtal); - if (!wbtal.font) { + CACHE_XFT(wbtal); + if (!XftFp(wbtal)) { noUsableXft(xw, "wide bold"); - XftPatternDestroy(wbtal.pattern); - wbtal.pattern = XftPatternDuplicate(pat); - XftPatternBuild(wbtal.pattern, + XftPatternDestroy(wbtal->pattern); + wbtal->pattern = XftPatternDuplicate(pat); + XftPatternBuild(wbtal->pattern, WideXftPattern, (void *) 0); OPEN_XFT(wbtal, "wide-bold-italics"); failed = 0; - CACHE_XFT(screen->renderWideBtal, wbtal); + CACHE_XFT(wbtal); } #endif } - CACHE_XFT(screen->renderWideNorm, wnorm); + CACHE_XFT(wnorm); - CACHE_XFT(screen->renderWideBold, wbold); - if (wnorm.font != 0 && !wbold.font) { + CACHE_XFT(wbold); + if (XftFp(wnorm) != 0 && !XftFp(wbold)) { noUsableXft(xw, "wide-bold"); - XftPatternDestroy(wbold.pattern); - wbold.pattern = XftPatternDuplicate(pat); - XftPatternBuild(bold.pattern, + XftPatternDestroy(wbold->pattern); + wbold->pattern = XftPatternDuplicate(pat); + XftPatternBuild(bold->pattern, WideXftPattern, (void *) 0); OPEN_XFT(wbold, "wide-bold"); failed = 0; - CACHE_XFT(screen->renderWideBold, bold); + CACHE_XFT(bold); } - CACHE_XFT(screen->renderWideItal, wital); - if (wnorm.font != 0 && !wital.font) { + CACHE_XFT(wital); + if (XftFp(wnorm) != 0 && !XftFp(wital)) { noUsableXft(xw, "wide-italic"); - XftPatternDestroy(wital.pattern); - wital.pattern = XftPatternDuplicate(pat); - XftPatternBuild(wital.pattern, + XftPatternDestroy(wital->pattern); + wital->pattern = XftPatternDuplicate(pat); + XftPatternBuild(wital->pattern, WideXftPattern, (void *) 0); OPEN_XFT(wital, "wide-italic"); failed = 0; - CACHE_XFT(screen->renderWideItal, wital); + CACHE_XFT(wital); } XftPatternDestroy(pat); @@ -3499,28 +3572,28 @@ xtermComputeFontInfo(XtermWidget xw, } #endif /* OPT_RENDERWIDE */ } - if (norm.font == 0) { + if (XftFp(norm) == 0) { TRACE(("...no TrueType font found for number %d, disable menu entry\n", fontnum)); xw->work.render_font = False; update_font_renderfont(); /* now we will fall through into the bitmap fonts */ } else { setBrokenBoxChars(xw, False); - setRenderFontsize(xw, win, norm.font, NULL); - setRenderFontsize(xw, win, bold.font, "bold"); - setRenderFontsize(xw, win, ital.font, "ital"); - setRenderFontsize(xw, win, btal.font, "btal"); + setRenderFontsize(xw, win, norm, NULL); + setRenderFontsize(xw, win, bold, "bold"); + setRenderFontsize(xw, win, ital, "ital"); + setRenderFontsize(xw, win, btal, "btal"); #if OPT_BOX_CHARS setupPackedFonts(xw); if (screen->force_packed) { XTermXftFonts *use = &(screen->renderFontNorm[fontnum]); - SetFontHeight(screen, win, use->font->ascent + use->font->descent); - SetFontWidth(screen, win, use->map.min_width); + SetFontHeight(screen, win, XftFp(use)->ascent + XftFp(use)->descent); + SetFontWidth(screen, win, use->font_info.min_width); TRACE(("...packed TrueType font %dx%d vs %d\n", win->f_height, win->f_width, - use->map.max_width)); + use->font_info.max_width)); } #endif DUMP_XFT(xw, &(screen->renderFontNorm[fontnum])); @@ -3645,7 +3718,7 @@ xtermMissingChar(unsigned ch, XTermFonts * font) TRACE2(("xtermMissingChar %#04x (!exists)\n", ch)); result = True; } - if (ch < KNOWN_MISSING) { + if (ch < MaxUChar) { font->known_missing[ch] = (Char) (result ? 2 : 1); } return result; @@ -3830,7 +3903,7 @@ xtermDrawBoxChar(XTermDraw * params, static const struct { const int mode; /* 1=y, 2=x, 3=both */ - const short *data; + const short *const data; } lines[] = { { 0, 0 }, /* 00 (unused) */ @@ -4061,33 +4134,41 @@ xtermDrawBoxChar(XTermDraw * params, * cases where double-width glyphs are stuffed into a single-width outline. */ static Boolean -foundXftGlyph(XtermWidget xw, XftFont *font, unsigned wc) +foundXftGlyph(XtermWidget xw, XTermXftFonts *data, int fontNum, unsigned wc) { + XftFont *font = XftFpN(data, fontNum); TScreen *screen = TScreenOf(xw); Boolean result = False; - if (font != 0 && XftGlyphExists(screen->display, font, wc)) { - int expect; - - if ((expect = CharWidth(screen, wc)) > 0) { - XGlyphInfo gi; - int actual; + if (font != 0) { + if (!xtermXftMissing(xw, data, fontNum, font, wc)) { + int expect; - XftTextExtents32(screen->display, font, &wc, 1, &gi); - /* - * Some (more than a few) fonts are sloppy; allow 10% outside - * the bounding box to accommodate them. - */ - actual = ((gi.xOff * 10) >= (11 * FontWidth(screen))) ? 2 : 1; - if (actual <= expect) { - /* allow double-cell if wcwidth agrees */ + if (XftIsN(data, fontNum) == xcBogus) { + ; + } else if (XftIsN(data, fontNum) == xcOpened) { result = True; + } else if ((expect = CharWidth(screen, wc)) > 0) { + XGlyphInfo gi; + int actual; + + XftTextExtents32(screen->display, font, &wc, 1, &gi); + /* + * Some (more than a few) fonts are sloppy; allow 10% outside + * the bounding box to accommodate them. + */ + actual = ((gi.xOff * 10) >= (11 * FontWidth(screen))) ? 2 : 1; + if (actual <= expect) { + /* allow double-cell if wcwidth agrees */ + result = True; + } else { + XftIsN(data, fontNum) = xcBogus; + TRACE(("SKIP U+%04X %d vs %d (%d vs %d)\n", + wc, gi.xOff, FontWidth(screen), actual, expect)); + } } else { - TRACE(("SKIP U+%04X %d vs %d (%d vs %d)\n", - wc, gi.xOff, FontWidth(screen), actual, expect)); + result = True; } - } else { - result = True; } } return result; @@ -4096,12 +4177,13 @@ foundXftGlyph(XtermWidget xw, XftFont *font, unsigned wc) static void markXftOpened(XtermWidget xw, XTermXftFonts *which, Cardinal n, unsigned wc) { - if (which->cache[n].usage != xcOpened) { + if (XftIsN(which, n) != xcOpened) { which->opened++; - which->cache[n].usage = xcOpened; + XftIsN(which, n) = xcOpened; /* XFT_DEBUG=3 will show useful context for this */ if (getenv("XFT_DEBUG") != 0) { - printf("xterm: matched U+%04X in fontset #%d [%u:%u]\n", + printf("%s: matched U+%04X in fontset #%d [%u:%u]\n", + ProgramName, wc, n + 1, which->opened, xw->work.max_fontsets); @@ -4109,159 +4191,254 @@ markXftOpened(XtermWidget xw, XTermXftFonts *which, Cardinal n, unsigned wc) } } +static char ** +xftData2List(XtermWidget xw, XTermXftFonts *fontData) +{ + TScreen *screen = TScreenOf(xw); + VTFontList *lists = &xw->work.fonts.xft; + char **result = NULL; + int n = screen->menu_font_number; + + if (fontData == &screen->renderFontNorm[n]) + result = lists->list_n; + else if (fontData == &screen->renderFontBold[n]) + result = lists->list_b; + else if (fontData == &screen->renderFontItal[n]) + result = lists->list_i; + else if (fontData == &screen->renderFontBtal[n]) + result = lists->list_bi; +#if OPT_RENDERWIDE + if (fontData == &screen->renderWideNorm[n]) + result = lists->list_w; + else if (fontData == &screen->renderWideBold[n]) + result = lists->list_wb; + else if (fontData == &screen->renderWideItal[n]) + result = lists->list_wi; + else if (fontData == &screen->renderWideBtal[n]) + result = lists->list_wbi; +#endif + return result; +} + +static FcPattern * +mergeXftStyle(XtermWidget xw, FcPattern * myPattern, XTermXftFonts *fontData) +{ + TScreen *screen = TScreenOf(xw); + Display *dpy = screen->display; + XftFont *given = XftFp(fontData); + XftResult mStatus; + int iValue; + double dValue; + + if (FcOK(FcPatternGetInteger(fontData->pattern, XFT_WEIGHT, 0, &iValue))) { + FcPatternAddInteger(myPattern, XFT_WEIGHT, iValue); + } + if (FcOK(FcPatternGetInteger(fontData->pattern, XFT_SLANT, 0, &iValue))) { + FcPatternAddInteger(myPattern, XFT_SLANT, iValue); + } + if (FcOK(FcPatternGetDouble(fontData->pattern, FC_ASPECT, 0, &dValue))) { + FcPatternAddDouble(myPattern, FC_ASPECT, dValue); + } + if (FcOK(FcPatternGetDouble(fontData->pattern, XFT_SIZE, 0, &dValue))) { + FcPatternAddDouble(myPattern, XFT_SIZE, dValue); + } + FcPatternAddBool(myPattern, FC_SCALABLE, FcTrue); + FcPatternAddInteger(myPattern, XFT_SPACING, XFT_MONO); + FcPatternAddInteger(myPattern, FC_CHAR_WIDTH, given->max_advance_width); +#ifdef FC_COLOR +#if !USE_FC_COLOR + FcPatternAddBool(myPattern, FC_COLOR, FcFalse); +#endif + FcPatternAddBool(myPattern, FC_OUTLINE, FcTrue); +#endif + + FcConfigSubstitute(NULL, myPattern, FcMatchPattern); + XftDefaultSubstitute(dpy, DefaultScreen(dpy), myPattern); + + return FcFontMatch(NULL, myPattern, &mStatus); +} + /* * Check if the given character has a glyph known to Xft. If it is missing, * try first to replace the font with a fallback that provides the glyph. + * + * Return -1 if nothing is found. Otherwise, return the index in the cache. */ -XftFont * -findXftGlyph(XtermWidget xw, XftFont *given, unsigned wc) +int +findXftGlyph(XtermWidget xw, XTermXftFonts *fontData, unsigned wc) { TScreen *screen = TScreenOf(xw); - XTermXftFonts *which = 0; - XftFont *result = 0; - /* workaround for interface changes... */ - int fontnum = screen->menu_font_number; - static int table[] = - { - offsetof(TScreen, renderFontNorm), - offsetof(TScreen, renderFontBold), - offsetof(TScreen, renderFontItal), - offsetof(TScreen, renderFontBtal), -#if OPT_RENDERWIDE - offsetof(TScreen, renderWideNorm), - offsetof(TScreen, renderWideBold), - offsetof(TScreen, renderWideItal), - offsetof(TScreen, renderWideBtal), -#endif - }; + XftFont *given; + XftFont *actual = NULL; Cardinal n; FcResult status; - const char *tag = 0; + int result = -1; + + /* sanity-check */ + if (fontData == NULL) + return result; + given = XftFp(fontData); /* if fontsets are not wanted, just leave */ if (xw->work.max_fontsets == 0) { - return 0; + return result; } /* ignore codes in private use areas */ if ((wc >= 0xe000 && wc <= 0xf8ff) || (wc >= 0xf0000 && wc <= 0xffffd) || (wc >= 0x100000 && wc <= 0x10fffd)) { - return 0; + return result; } /* the end of the BMP is reserved for non-characters */ if (wc >= 0xfff0 && wc <= 0xffff) { - return 0; + return result; } - for (n = 0; n < XtNumber(table); ++n) { - XTermXftFonts *check = (XTermXftFonts *) ((void *) ((char *) screen - + table[n])); - if (check[fontnum].font == given) { - which = &check[fontnum]; - tag = whichFontEnum((VTFontEnum) n); - break; - } - } - if (which != 0) { - if (which->fontset == 0) { - FcFontSet *sortedFonts; - FcPattern *myPattern; - int j; + /* initialize on the first call */ + if (fontData->fontset == NULL) { + FcFontSet *sortedFonts; + FcPattern *myPattern; + int j; + char **my_list; - myPattern = FcPatternDuplicate(which->pattern); + myPattern = FcPatternDuplicate(fontData->pattern); - FcPatternAddBool(myPattern, FC_SCALABLE, FcTrue); - FcPatternAddInteger(myPattern, FC_CHAR_WIDTH, given->max_advance_width); + FcPatternAddBool(myPattern, FC_SCALABLE, FcTrue); + FcPatternAddInteger(myPattern, FC_CHAR_WIDTH, given->max_advance_width); - FcConfigSubstitute(FcConfigGetCurrent(), - myPattern, - FcMatchPattern); - FcDefaultSubstitute(myPattern); + FcConfigSubstitute(FcConfigGetCurrent(), + myPattern, + FcMatchPattern); + FcDefaultSubstitute(myPattern); - which->fontset = FcFontSetCreate(); + sortedFonts = FcFontSort(NULL, myPattern, FcTrue, NULL, &status); - sortedFonts = FcFontSort(0, myPattern, FcTrue, 0, &status); + fontData->fontset = FcFontSetCreate(); - if (!sortedFonts || sortedFonts->nfont <= 0) { - xtermWarning("did not find any usable TrueType font\n"); - return 0; - } - which->limit = (unsigned) sortedFonts->nfont; - which->cache = TypeCallocN(XTermXftCache, (which->limit + 1)); - for (j = 0; j < sortedFonts->nfont; j++) { - FcPattern *font_pattern; - - font_pattern = FcFontRenderPrepare(FcConfigGetCurrent(), - myPattern, - sortedFonts->fonts[j]); - if (font_pattern) - FcFontSetAdd(which->fontset, font_pattern); - } - - FcFontSetSortDestroy(sortedFonts); - FcPatternDestroy(myPattern); + if (fontData->fontset == 0 || !sortedFonts || sortedFonts->nfont <= 0) { + xtermWarning("did not find any usable TrueType font\n"); + return 0; } - if (which->fontset != 0) { - XftFont *check; - Cardinal empty = which->limit; - - for (n = 0; n < which->limit; ++n) { - XftCache usage = which->cache[n].usage; - if (usage == xcEmpty) { - if (empty > n) - empty = n; - } else if (usage == xcOpened - || (usage == xcUnused - && (which->opened < xw->work.max_fontsets))) { - check = which->cache[n].font; - if (foundXftGlyph(xw, check, wc)) { - markXftOpened(xw, which, n, wc); - result = check; - TRACE_FALLBACK(xw, "old", wc, (int) n, result); - break; + + /* + * Check if there are additional fonts in the XtermFontNames.xft for + * this font-data. + */ + if ((my_list = xftData2List(xw, fontData)) != NULL + && *++my_list != NULL) { + for (j = 0; my_list[j] != NULL; ++j) { + FcPattern *extraPattern; + if ((extraPattern = XftNameParse(my_list[j])) != 0) { + FcPattern *match; + + match = mergeXftStyle(xw, extraPattern, fontData); + + if (match != NULL) { + FcFontSetAdd(fontData->fontset, match); } + FcPatternDestroy(extraPattern); } } + } - if ((result == 0) - && (empty < which->limit) - && (which->opened < xw->work.max_fontsets)) { - FcPattern *myPattern = 0; - FcPattern *myReport = 0; + for (j = 0; j < sortedFonts->nfont; j++) { + FcPattern *font_pattern; - for (n = empty; n < which->limit; ++n) { - if (which->cache[n].usage >= xcBogus) - continue; - if (resource.reportFonts) { - myReport = FcPatternDuplicate(which->fontset->fonts[n]); - } - myPattern = FcPatternDuplicate(which->fontset->fonts[n]); - check = XftFontOpenPattern(screen->display, myPattern); - closeCachedXft(screen, which->cache[n].font); - (void) maybeXftCache(xw, check); - which->cache[n].font = check; - which->cache[n].usage = xcBogus; - if (check == 0) - continue; /* shouldn't happen... */ + font_pattern = FcFontRenderPrepare(FcConfigGetCurrent(), + myPattern, + sortedFonts->fonts[j]); + if (font_pattern) { + FcFontSetAdd(fontData->fontset, font_pattern); + } + } + + FcFontSetSortDestroy(sortedFonts); + FcPatternDestroy(myPattern); + + fontData->fs_size = (unsigned) fontData->fontset->nfont; + } + + { + XftFont *check; + Cardinal empty = fontData->fs_size; + + for (n = 1; n <= fontData->fs_size; ++n) { + XTermXftState usage = XftIsN(fontData, n); + if (usage == xcEmpty) { + if (empty > n) + empty = n; + } else if (usage == xcOpened + || (usage == xcUnused + && (fontData->opened < xw->work.max_fontsets))) { + check = XftFpN(fontData, n); + if (foundXftGlyph(xw, fontData, (int) n, wc)) { + markXftOpened(xw, fontData, n, wc); + actual = check; + result = (int) n; + TRACE_FALLBACK(xw, "old", wc, result, actual); + break; + } + } + } + + if ((actual == NULL) + && (empty <= fontData->fs_size) + && (fontData->opened < xw->work.max_fontsets)) { + FcPattern *myPattern = NULL; + FcPattern *myReport = NULL; + + if (empty == 0) /* should not happen */ + empty++; + for (n = empty; n < fontData->fs_size; ++n) { + unsigned nn = n - 1; + if (XftIsN(fontData, n) != xcEmpty) { + continue; + } + if (resource.reportFonts) { + if (myReport != NULL) + FcPatternDestroy(myReport); + myReport = FcPatternDuplicate(fontData->fontset->fonts[nn]); + } + myPattern = FcPatternDuplicate(fontData->fontset->fonts[nn]); + check = XftFontOpenPattern(screen->display, myPattern); + (void) maybeXftCache(xw, check); + if (fontData->fs_size <= n) + fontData->fs_size = (n + 1); + XftFpN(fontData, n) = check; + if (check == NULL) { + ; /* shouldn't happen... */ + } else #ifdef FC_COLOR - if (isBogusXft(check)) { - continue; - } + if (isBogusXft(check)) { + XftIsN(fontData, n) = xcBogus; + } else #endif - if (foundXftGlyph(xw, check, wc)) { - markXftOpened(xw, which, n, wc); - reportXftFonts(xw, check, "fallback", tag, myReport); - result = check; - TRACE_FALLBACK(xw, "new", wc, (int) n, result); - break; + if (foundXftGlyph(xw, fontData, (int) n, wc)) { + char tag[80]; + if (resource.reportFonts) { + sprintf(tag, "%s#%d", + whichXftFonts(xw, fontData), + n + 1); + } else { + tag[0] = '\0'; } + markXftOpened(xw, fontData, n, wc); + reportXftFonts(xw, fontData, (int) n, check, + "fallback", tag, myReport); + actual = check; + result = (int) n; + TRACE_FALLBACK(xw, "new", wc, result, actual); + break; + } else { /* - * The slot is opened, but we are not using it. + * The slot is opened, but we are not using it yet. */ - which->cache[n].usage = xcUnused; + XftIsN(fontData, n) = xcUnused; } } + if (myReport != NULL) + FcPatternDestroy(myReport); } } return result; @@ -4274,20 +4451,69 @@ findXftGlyph(XtermWidget xw, XftFont *given, unsigned wc) * see xc/lib/Xft/xftglyphs.c */ Bool -xtermXftMissing(XtermWidget xw, XftFont *font, unsigned wc) +xtermXftMissing(XtermWidget xw, + XTermXftFonts *data, + int fontNum, /* 0=primary, 1+ is fallback */ + XftFont *font, /* actual font if no data */ + unsigned wc) { - Bool result = False; + Bool result = True; - if (font != 0) { - TScreen *screen = TScreenOf(xw); - if (!XftGlyphExists(screen->display, font, wc)) { -#if OPT_WIDE_CHARS - TRACE2(("xtermXftMissing %d (dec=%#x, ucs=%#x)\n", - wc, ucs2dec(screen, wc), dec2ucs(screen, wc))); -#else - TRACE2(("xtermXftMissing %d\n", wc)); -#endif - result = True; + (void) xw; + if (data != NULL && font != NULL) { + XTermFontMap *font_map = &(data->font_map); + /* + * Each fallback font has one chance to be scanned/cached. + * We record in per_font[] the index of the first font containing a + * given glyph. + */ + if (font_map->depth <= fontNum) { + FcChar32 last = (xtermXftLastChar(font) | 255) + 1; + FcChar32 base; + FcChar32 nextPage; + FcChar32 map[FC_CHARSET_MAP_SIZE]; + unsigned added = 0; + unsigned actual = 0; + + font_map->depth = (fontNum + 1); + /* allocate space */ + if (last > font_map->last_char) { + font_map->per_font = realloc(font_map->per_font, last); + memset(font_map->per_font + font_map->last_char, 0, (last - font_map->last_char)); + font_map->last_char = last; + } + + /* scan new font */ + base = FcCharSetFirstPage(font->charset, map, &nextPage); + do { + unsigned row; + unsigned col; + FcChar32 bits; + for (row = 0; row < FC_CHARSET_MAP_SIZE; ++row) { + bits = map[row]; + for (col = 0; col < 32; ++col) { + if ((bits & 1) != 0) { + actual++; + if (!font_map->per_font[base]) { + font_map->per_font[base] = (Char) font_map->depth; + ++added; + } + } + bits >>= 1; + ++base; + } + } + } while ((base = FcCharSetNextPage(font->charset, map, + &nextPage)) != FC_CHARSET_DONE); + TRACE(("xtermXftMissing U+%04X #%-3d %6u added vs %6u of %6ld %s\n", + wc, + font_map->depth, + added, actual, + font_map->last_char + 1, + whichXftFonts(xw, data))); + } + if (wc < font_map->last_char) { + result = (font_map->per_font[wc] != (fontNum + 1)); } } return result; @@ -4748,6 +4974,9 @@ xtermGetFont(const char *param) { int fontnum; + if (param == NULL) + param = ""; + switch (param[0]) { case 'd': case 'D': @@ -4787,7 +5016,7 @@ xtermGetFont(const char *param) fontnum = -1; break; } - TRACE(("xtermGetFont(%s) ->%d\n", NonNull(param), fontnum)); + TRACE(("xtermGetFont(%s) ->%d\n", param, fontnum)); return fontnum; } @@ -5120,7 +5349,7 @@ save2FontList(XtermWidget xw, } } if (success) { - next = realloc(*list, sizeof(char *) * (count + 2)); + next = (char **) realloc(*list, sizeof(char *) * (count + 2)); if (next != 0) { #if OPT_RENDERFONT if (use_ttf) { @@ -5378,11 +5607,9 @@ getDoubleFont(TScreen *screen, int which) } #if OPT_RENDERFONT -XftFont * -getDoubleXftFont(XTermDraw * params, unsigned chrset, unsigned attr_flags) +void +getDoubleXftFont(XTermDraw * params, XTermXftFonts *data, unsigned chrset, unsigned attr_flags) { - XftFont *result = 0; - XtermWidget xw = params->xw; TScreen *screen = TScreenOf(xw); XftPattern *top_pattern; @@ -5393,17 +5620,22 @@ getDoubleXftFont(XTermDraw * params, unsigned chrset, unsigned attr_flags) && (top_pattern = XftNameParse(face_name)) != 0) { double face_size = (double) xw->misc.face_size[fontnum]; XftPattern *sub_pattern = XftPatternDuplicate(top_pattern); + const char *category = "doublesize"; switch (chrset) { case CSET_DHL_TOP: - /* FALLTHRU */ + category = "DHL_TOP"; + goto double_high; case CSET_DHL_BOT: + category = "DHL_BOT"; + double_high: face_size *= 2; XftPatternBuild(sub_pattern, NormXftPattern, (void *) 0); break; case CSET_DWL: + category = "DWL"; XftPatternBuild(sub_pattern, NormXftPattern, FC_ASPECT, XftTypeDouble, 2.0, @@ -5415,9 +5647,8 @@ getDoubleXftFont(XTermDraw * params, unsigned chrset, unsigned attr_flags) XFT_WEIGHT, XftTypeInteger, XFT_WEIGHT_BOLD, (void *) 0); } - result = xtermOpenXft(xw, face_name, sub_pattern, "doublesize"); + xtermOpenXft(xw, data, 0, face_name, sub_pattern, category); } - return result; } #endif #endif /* OPT_DEC_CHRSET */ @@ -5485,13 +5716,55 @@ getMyXftFont(XtermWidget xw, int which, int fontnum) return result; } +const char * +whichXftFonts(XtermWidget xw, XTermXftFonts *data) +{ + TScreen *screen = TScreenOf(xw); + const char *result = "?"; +#define CHECK(name) ((data >= &(screen->name[0])) && (data < &(screen->name[NMENUFONTS]))) result = #name + if CHECK + (renderFontNorm); + else if CHECK + (renderFontBold); +#if OPT_WIDE_ATTRS || OPT_RENDERWIDE + else if CHECK + (renderFontItal); + else if CHECK + (renderFontBtal); +#endif +#if OPT_WIDE_CHARS + else if CHECK + (renderWideNorm); + else if CHECK + (renderWideBold); + else if CHECK + (renderWideItal); + else if CHECK + (renderWideBtal); +#endif +#if OPT_DEC_CHRSET +#if OPT_RENDERFONT + else { + int n; + for (n = 0; n < NUM_CHRSET; ++n) { + if (data == &screen->double_xft_fonts[n]) { + result = "double_xft_fonts"; + break; + } + } + } +#endif +#endif /* OPT_DEC_CHRSET */ + return result; +} + XftFont * getXftFont(XtermWidget xw, VTFontEnum which, int fontnum) { XTermXftFonts *data = getMyXftFont(xw, (int) which, fontnum); XftFont *result = 0; if (data != 0) - result = data->font; + result = XftFp(data); return result; } #endif diff --git a/app/xterm/fontutils.h b/app/xterm/fontutils.h index 2267f2462..a9c4da785 100644 --- a/app/xterm/fontutils.h +++ b/app/xterm/fontutils.h @@ -1,7 +1,7 @@ -/* $XTermId: fontutils.h,v 1.137 2021/02/25 23:03:24 tom Exp $ */ +/* $XTermId: fontutils.h,v 1.140 2022/05/05 22:24:02 tom Exp $ */ /* - * Copyright 1998-2020,2021 by Thomas E. Dickey + * Copyright 1998-2021,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -112,7 +112,7 @@ extern char *xtermSpecialFont (XTermDraw * /* params */); */ #if OPT_WIDE_CHARS #define CheckedKnownMissing(font, ch) \ - (((ch) < KNOWN_MISSING) && ((font)->known_missing[(Char)(ch)] > 0)) + (((ch) < MaxUChar) && ((font)->known_missing[(Char)(ch)] > 0)) #else #define CheckedKnownMissing(font, ch) \ ((font)->known_missing[(Char)(ch)] > 0) @@ -146,14 +146,15 @@ extern void xtermSaveVTFonts (XtermWidget /* xw */); #if OPT_RENDERFONT extern Boolean maybeXftCache(XtermWidget /* xw */, XftFont * /* font */); -extern Bool xtermXftMissing (XtermWidget /* xw */, XftFont * /* font */, unsigned /* wc */); +extern Bool xtermXftMissing (XtermWidget /* xw */, XTermXftFonts * /* fontData */, int /* fontNum */, XftFont * /* font */, unsigned /* wc */); extern XTermXftFonts *getMyXftFont (XtermWidget /* xw */, int /* which */, int /* fontnum */); -extern XftFont *findXftGlyph (XtermWidget /* xw */, XftFont * /* given */, unsigned /* wc */); +extern const char * whichXftFonts(XtermWidget /* xw */, XTermXftFonts * /* data */); +extern int findXftGlyph (XtermWidget /* xw */, XTermXftFonts * /* fontData */, unsigned /* wc */); extern XftFont *getXftFont (XtermWidget /* xw */, VTFontEnum /* which */, int /* fontnum */); extern void closeCachedXft (TScreen * /* screen */, XftFont * /* font */); extern void xtermCloseXft (TScreen * /* screen */, XTermXftFonts * /* pub */); #if OPT_DEC_CHRSET -extern XftFont * getDoubleXftFont(XTermDraw * /* params */, unsigned /* chrset */, unsigned /* attr_flags */); +extern void getDoubleXftFont(XTermDraw * /* params */, XTermXftFonts * /* fontData */, unsigned /* chrset */, unsigned /* attr_flags */); #endif #endif diff --git a/app/xterm/graphics.c b/app/xterm/graphics.c index 77658fa24..9d7d6a4f4 100644 --- a/app/xterm/graphics.c +++ b/app/xterm/graphics.c @@ -1,4 +1,4 @@ -/* $XTermId: graphics.c,v 1.117 2022/02/24 09:28:54 tom Exp $ */ +/* $XTermId: graphics.c,v 1.118 2022/05/16 23:35:50 tom Exp $ */ /* * Copyright 2013-2021,2022 by Ross Combs @@ -816,7 +816,7 @@ save_allocated_color(const ColorRegister *reg, XtermWidget xw, Pixel *pix) } else { *pix = xcolor.pixel; - if (!(new_color = malloc(sizeof(*new_color)))) { + if (!(new_color = TypeMalloc(AllocatedColorRegister))) { TRACE(("unable to save pixel %lu\n", (unsigned long) *pix)); return 0; } else { @@ -1252,8 +1252,8 @@ AllocGraphicsBuffer(TScreen *screen, int const refresh_h = nrows * FontHeight(screen); ColorRegister *buffer; - if (!(buffer = malloc(sizeof(ColorRegister) * - (unsigned) refresh_w * (unsigned) refresh_h))) { + if (!(buffer = TypeMallocN(ColorRegister, + (unsigned) refresh_w * (unsigned) refresh_h))) { TRACE(("unable to allocate %dx%d buffer for graphics refresh\n", refresh_w, refresh_h)); } else { @@ -1577,7 +1577,7 @@ refresh_graphics(XtermWidget xw, free(buffer); return; } - imgdata = malloc((size_t) (image_h * (unsigned) image->bytes_per_line)); + imgdata = TypeMallocN(char, (size_t)(image_h * (unsigned)image->bytes_per_line)); if (!imgdata) { TRACE(("unable to allocate XImage for graphics refresh\n")); XDestroyImage(image); diff --git a/app/xterm/graphics_regis.c b/app/xterm/graphics_regis.c index 479bb7960..c532e4e29 100644 --- a/app/xterm/graphics_regis.c +++ b/app/xterm/graphics_regis.c @@ -1,4 +1,4 @@ -/* $XTermId: graphics_regis.c,v 1.129 2022/02/21 13:33:08 tom Exp $ */ +/* $XTermId: graphics_regis.c,v 1.130 2022/05/16 23:31:18 tom Exp $ */ /* * Copyright 2014-2021,2022 by Ross Combs @@ -538,8 +538,8 @@ draw_or_save_patterned_pixel(RegisGraphicsContext *context, int x, int y) static int sort_points(void const *l, void const *r) { - RegisPoint const *const lp = l; - RegisPoint const *const rp = r; + RegisPoint const *const lp = (RegisPoint const *)l; + RegisPoint const *const rp = (RegisPoint const *)r; if (lp->y < rp->y) return -1; @@ -1696,7 +1696,7 @@ get_xft_glyph_dimensions(XtermWidget xw, XftFont *font, unsigned *w, workh = (unsigned) font->height + 2U; } - if (!(pixels = malloc((size_t) (workw * workh)))) { + if (!(pixels = TypeMallocN(Char, (size_t) (workw * workh)))) { *w = 0U; *h = 0U; #ifdef DEBUG_COMPUTED_FONT_METRICS @@ -6838,12 +6838,12 @@ parse_regis_option(RegisParseState *state, RegisGraphicsContext *context) static int expand_macrographs(RegisDataFragment *input, RegisGraphicsContext const *context) { - char operator; + char op; char name; (void) context; /* to be used later */ - operator = get_fragment(input, 0U); - if (operator != '@') + op = get_fragment(input, 0U); + if (op != '@') return 0; name = get_fragment(input, 1U); if (islower(CharOf(name))) @@ -7304,7 +7304,7 @@ parse_regis_items(RegisParseState *state, RegisGraphicsContext *context) * context->alphabets[state->load_index].pixh; if (context->alphabets[state->load_index].bytes == NULL) { if (!(context->alphabets[state->load_index].bytes = - calloc((size_t) (MAX_GLYPHS * glyph_size), sizeof(Char)))) { + TypeCallocN(Char, (size_t) (MAX_GLYPHS * glyph_size)))) { TRACE(("ERROR: unable to allocate %u bytes for glyph storage\n", MAX_GLYPHS * glyph_size)); return 0; @@ -7605,7 +7605,7 @@ parse_regis(XtermWidget xw, ANSI *params, char const *string) init_fragment(&state->input, string); state->templen = (unsigned) strlen(string) + 1U; - if (!(state->temp = malloc((size_t) state->templen))) { + if (!(state->temp = TypeMallocN(char, (size_t) state->templen))) { TRACE(("Unable to allocate temporary buffer of size %u\n", state->templen)); return; diff --git a/app/xterm/graphics_sixel.c b/app/xterm/graphics_sixel.c index 410199eec..876642289 100644 --- a/app/xterm/graphics_sixel.c +++ b/app/xterm/graphics_sixel.c @@ -1,4 +1,4 @@ -/* $XTermId: graphics_sixel.c,v 1.36 2022/02/21 23:13:48 tom Exp $ */ +/* $XTermId: graphics_sixel.c,v 1.38 2022/10/10 15:09:41 tom Exp $ */ /* * Copyright 2014-2021,2022 by Ross Combs @@ -109,15 +109,24 @@ typedef struct { int col; /* context used during parsing */ } SixelContext; -/* sixel scrolling: - * VK100/GIGI ? (did it even support Sixel?) - * VT125 unsupported - * VT240 unsupported - * VT241 unsupported - * VT330 mode setting - * VT382 ? - * VT340 mode setting - * dxterm ? +/* SIXEL SCROLLING, which is on by default in VT3xx terminals, can be + * turned off to better emulate VT2xx terminals by setting Sixel + * Display Mode (DECSDM) + * + * SIXEL DISPLAY MODE SIXEL SCROLLING + * VT125 Always on Unsupported + * VT240 Always on Unsupported + * VT241 Always on Unsupported + * VT330 Available via DECSDM Default mode + * VT382 Available via DECSDM Default mode + * VT340 Available via DECSDM Default mode + * VK100/GIGI No sixel support No sixel support + * + * dxterm (DECterm) emulated a VT100 series terminal, and supported sixels + * according to 1995 posting to comp.os.vms: + * https://groups.google.com/g/comp.os.vms/c/XAUMmLtC8Yk + * though not DRCS according to + * http://odl.sysworks.biz/disk$axpdocdec023/office/dwmot126/vmsdw126/relnotes/6470pro_004.html */ static void @@ -250,17 +259,26 @@ finished_parsing(XtermWidget xw, Graphic *graphic) + FontWidth(screen) - 1) / FontWidth(screen))); } else { - /* FIXME: At least of the VT382 the vertical position appears to be - * truncated (rounded toward zero after converting to character row. - * This code rounds up, which seems more useful, but it would be - * better to be compatible. Verify this is true on a VT3[34]0 as - * well. + /* NOTE: XTerm follows the VT382 behavior in text cursor + * placement. The VT382's vertical position appears to be + * truncated (rounded toward zero) after converting to character + * row. While rounding up is more often what is desired, so as to + * not overwrite the image, doing so automatically would cause text + * or graphics to scroll off the top of the screen. Therefore, + * applications must add their own newline character, if desired, + * after a sixel image. + * + * FIXME: The VT340 also rounds down, but it seems to have a + * strange behavior where, on rare occasions, two newlines are + * required to advance beyond the end of the image. This appears + * to be a firmware bug, but it should be added as an option for + * compatibility. */ - new_row = (graphic->charrow + new_row = (graphic->charrow - 1 + (((graphic->actual_height * graphic->pixh) + FontHeight(screen) - 1) / FontHeight(screen))); - new_col = 0; + new_col = graphic->charcol; } TRACE(("setting text position after %dx%d\t%.1f start (%d %d): cursor (%d,%d)\n", diff --git a/app/xterm/linedata.c b/app/xterm/linedata.c index 7d9ce29b6..9b439560f 100644 --- a/app/xterm/linedata.c +++ b/app/xterm/linedata.c @@ -1,7 +1,7 @@ -/* $XTermId: linedata.c,v 1.101 2021/12/27 23:43:28 tom Exp $ */ +/* $XTermId: linedata.c,v 1.102 2022/09/18 21:17:43 tom Exp $ */ /* - * Copyright 2009-2019,2021 by Thomas E. Dickey + * Copyright 2009-2021,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -70,7 +70,7 @@ getLineData(TScreen *screen, int row) void copyLineData(LineData *dst, CLineData *src) { - if (dst == NULL || src == NULL) + if (dst == NULL || src == NULL || dst == src) return; dst->bufHead = src->bufHead; diff --git a/app/xterm/main.c b/app/xterm/main.c index 643522cee..275c1818d 100644 --- a/app/xterm/main.c +++ b/app/xterm/main.c @@ -1,4 +1,4 @@ -/* $XTermId: main.c,v 1.886 2022/02/22 23:35:41 tom Exp $ */ +/* $XTermId: main.c,v 1.889 2022/07/13 07:57:08 Brendan.O.Dea Exp $ */ /* * Copyright 2002-2021,2022 by Thomas E. Dickey @@ -1189,8 +1189,8 @@ DATA("-sm", "*sessionMgt", XrmoptionNoArg, "on"), DATA("+sm", "*sessionMgt", XrmoptionNoArg, "off"), #endif #if OPT_TOOLBAR -DATA("-tb", "*"XtNtoolBar, XrmoptionNoArg, "on"), -DATA("+tb", "*"XtNtoolBar, XrmoptionNoArg, "off"), +DATA("-tb", "*" XtNtoolBar, XrmoptionNoArg, "on"), +DATA("+tb", "*" XtNtoolBar, XrmoptionNoArg, "off"), #endif #if OPT_MAXIMIZE DATA("-maximized", "*maximized", XrmoptionNoArg, "on"), @@ -1537,7 +1537,7 @@ parseArg(int *num, char **argv, char **valuep) { /* table adapted from XtInitialize, used here to improve abbreviations */ /* *INDENT-OFF* */ -#define DATA(option,kind) { (char *) option, NULL, kind, (XtPointer) NULL } +#define DATA(option,kind) { (char *) option, NULL, kind, (XPointer) 0 } static XrmOptionDescRec opTable[] = { DATA("+synchronous", XrmoptionNoArg), DATA("-background", XrmoptionSepArg), @@ -2911,7 +2911,7 @@ main(int argc, char *argv[]ENVP_ARG) #endif { -#if OPT_EXEC_XTERM +#if OPT_EXEC_SELECTION String data = NULL; getKeymapResources(SHELL_OF(term), "vt100", "VT100", XtRString, &data, sizeof(data)); if (data && @@ -2922,7 +2922,7 @@ main(int argc, char *argv[]ENVP_ARG) exit(1); } } else -#endif /* OPT_EXEC_XTERM */ +#endif /* OPT_EXEC_SELECTION */ { char *env; @@ -3619,7 +3619,7 @@ findValidShell(const char *haystack, const char *needle) have = (size_t) (t - s); if ((have >= want) && (*s != '#')) { - char *p = malloc(have + 1); + char *p = (char *) malloc(have + 1); if (p != 0) { char *q; @@ -3757,24 +3757,38 @@ static void xtermTrimEnv(void) { #define DATA(wild,name) { wild, #name } + /* *INDENT-OFF* */ static struct { int wild; const char *name; } table[] = { + DATA(0, COLUMNS), DATA(0, DEFAULT_COLORS), - DATA(0, DESKTOP_STARTUP_ID), - DATA(0, WCWIDTH_CJK_LEGACY), - DATA(0, XCURSOR_PATH), - DATA(1, COLORFGBG), - DATA(1, COLORTERM), - DATA(1, ITERM2_), - DATA(1, MC_), - DATA(1, PUTTY), - DATA(1, RXVT_), - DATA(1, URXVT_), - DATA(1, VTE_), + DATA(0, DESKTOP_STARTUP_ID), + DATA(0, LINES), + DATA(0, SHLVL), /* ksh, bash */ + DATA(0, STY), /* screen */ + DATA(0, TERMCAP), + DATA(0, TMUX), + DATA(0, TMUX_PANE), + DATA(0, WCWIDTH_CJK_LEGACY), + DATA(0, WINDOW), /* screen */ + DATA(0, XCURSOR_PATH), + DATA(1, COLORFGBG), + DATA(1, COLORTERM), + DATA(1, GIO_LAUNCHED_), + DATA(1, ITERM2_), + DATA(1, MC_), + DATA(1, MINTTY_), + DATA(1, PUTTY), + DATA(1, RXVT_), + DATA(1, TERM_), + DATA(1, URXVT_), + DATA(1, VTE_), + DATA(1, XTERM_), }; #undef DATA + /* *INDENT-ON* */ Cardinal n; for (n = 0; n < XtNumber(table); ++n) { @@ -3788,7 +3802,7 @@ xtermTrimEnv(void) char *my_var; if (dstend != NULL && (dstlen = (size_t) (dstend - environ[s])) >= srclen && - !strncmp(table[n].name, environ[s], dstlen) && + !strncmp(table[n].name, environ[s], srclen) && (my_var = x_strdup(environ[s])) != NULL) { my_var[dstlen] = '\0'; xtermUnsetenv(my_var); @@ -5224,7 +5238,7 @@ spawnXTerm(XtermWidget xw, unsigned line_speed) signal(SIGHUP, SIG_DFL); #endif - if ((shname_minus = malloc(strlen(shname) + 2)) != 0) { + if ((shname_minus = (char *) malloc(strlen(shname) + 2)) != 0) { (void) strcpy(shname_minus, "-"); (void) strcat(shname_minus, shname); } else { diff --git a/app/xterm/main.h b/app/xterm/main.h index 1769dd407..1feb57c73 100644 --- a/app/xterm/main.h +++ b/app/xterm/main.h @@ -1,4 +1,4 @@ -/* $XTermId: main.h,v 1.80 2022/01/31 00:42:27 tom Exp $ */ +/* $XTermId: main.h,v 1.81 2022/07/07 09:44:28 tom Exp $ */ /* * Copyright 2000-2021,2022 by Thomas E. Dickey @@ -239,6 +239,10 @@ #define DEF_TI_XTRA_SCROLL "False" #endif +#ifndef DEF_TRACK_USAGE +#define DEF_TRACK_USAGE True +#endif + #ifndef DEF_XFT_CACHE #define DEF_XFT_CACHE 50 #endif diff --git a/app/xterm/menu.c b/app/xterm/menu.c index baf38ee72..2af00bfac 100644 --- a/app/xterm/menu.c +++ b/app/xterm/menu.c @@ -1,7 +1,7 @@ -/* $XTermId: menu.c,v 1.367 2021/06/03 21:23:40 tom Exp $ */ +/* $XTermId: menu.c,v 1.370 2022/10/07 08:00:53 Ben.Wong Exp $ */ /* - * Copyright 1999-2020,2021 by Thomas E. Dickey + * Copyright 1999-2021,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -2344,7 +2344,7 @@ update_decsdm(void) UpdateCheckbox("update_decsdm", vtMenuEntries, vtMenu_sixelscrolling, - (term->keyboard.flags & MODE_DECSDM) != 0); + (term->keyboard.flags & MODE_DECSDM) == 0); } void diff --git a/app/xterm/minstall.in b/app/xterm/minstall.in index cd1577508..fe2c610a3 100644 --- a/app/xterm/minstall.in +++ b/app/xterm/minstall.in @@ -1,9 +1,9 @@ #!/bin/sh -# $XTermId: minstall.in,v 1.26 2021/01/27 01:36:06 tom Exp $ +# $XTermId: minstall.in,v 1.27 2022/10/02 20:13:11 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2001-2019,2021 by Thomas E. Dickey +# Copyright 2001-2021,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -126,8 +126,8 @@ X_MANSECT=`man $X_MANPAGE 2>&1 | grep $X_MANPAGE'([^)]*)' | head -n 1 | tr '\012 test -z "$X_MANSECT" && X_MANSECT=$suffix VERSION_H=`echo "$OLD_FILE" | sed -e 's,/[^/]*$,/version.h,' -e s',^[^/]*$,version.h,'` -PATCH_NUM=`${FGREP-fgrep} XTERM_PATCH "$VERSION_H" | sed -e 's/[^0-9]*//g'` -PATCH_YMD=`${FGREP-fgrep} XTERM_DATE "$VERSION_H" | sed -e 's,[^0-9/.-]*,,g'` +PATCH_NUM=`@FGREP@ XTERM_PATCH "$VERSION_H" | sed -e 's/[^0-9]*//g'` +PATCH_YMD=`@FGREP@ XTERM_DATE "$VERSION_H" | sed -e 's,[^0-9/.-]*,,g'` # Make capitalization variants APP_chr0=`echo "$APP_name" | sed -e 's/^\(.\).*/\1/' | tr "$lower" "$upper"` diff --git a/app/xterm/misc.c b/app/xterm/misc.c index 35f12489b..58b9f8dab 100644 --- a/app/xterm/misc.c +++ b/app/xterm/misc.c @@ -1,4 +1,4 @@ -/* $XTermId: misc.c,v 1.1015 2022/02/18 09:08:10 tom Exp $ */ +/* $XTermId: misc.c,v 1.1028 2022/10/06 22:24:07 tom Exp $ */ /* * Copyright 1999-2021,2022 by Thomas E. Dickey @@ -99,6 +99,12 @@ #include <assert.h> +#ifdef HAVE_MKSTEMP +#define MakeTemp(f) mkstemp(f) +#else +#define MakeTemp(f) mktemp(f) +#endif + #ifdef VMS #define XTERM_VMS_LOGFILE "SYS$SCRATCH:XTERM_LOG.TXT" #ifdef ALLOWLOGFILEEXEC @@ -777,7 +783,7 @@ init_colored_cursor(Display *dpy) #ifdef HAVE_MKDTEMP xterm_cursor_theme = mkdtemp(filename); #else - if (mktemp(filename) != 0 + if (MakeTemp(filename) != 0 && mkdir(filename, 0700) == 0) { xterm_cursor_theme = filename; } @@ -1213,13 +1219,13 @@ HandleInterpret(Widget w GCC_UNUSED, { if (*param_count == 1) { const char *value = params[0]; - int need = (int) strlen(value); - int used = (int) (VTbuffer->next - VTbuffer->buffer); - int have = (int) (VTbuffer->last - VTbuffer->buffer); + size_t need = strlen(value); + size_t used = (size_t) (VTbuffer->next - VTbuffer->buffer); + size_t have = (size_t) (VTbuffer->last - VTbuffer->buffer); - if (have - used + need < BUF_SIZE) { + if ((have - used) + need < (size_t) BUF_SIZE) { - fillPtyData(term, VTbuffer, value, (int) strlen(value)); + fillPtyData(term, VTbuffer, value, strlen(value)); TRACE(("Interpret %s\n", value)); VTbuffer->update++; @@ -1733,7 +1739,7 @@ dabbrev_expand(XtermWidget xw) memmove(copybuffer + del_cnt, expansion + hint_len, strlen(expansion) - hint_len); - v_write(pty, copybuffer, (unsigned) buf_cnt); + v_write(pty, copybuffer, buf_cnt); /* v_write() just reset our flag */ screen->dabbrev_working = True; free(copybuffer); @@ -2480,7 +2486,7 @@ GenerateLogPath(void) #else static const char log_def_name[] = "XtermLog.XXXXXX"; if ((log_default = x_strdup(log_def_name)) != NULL) { - mktemp(log_default); + MakeTemp(log_default); } #endif @@ -2553,7 +2559,7 @@ FlushLog(XtermWidget xw) if (screen->logging && !(screen->inhibit & I_LOG)) { Char *cp; - int i; + size_t i; #ifdef VMS /* avoid logging output loops which otherwise occur sometimes when there is no output and cp/screen->logstart are 1 apart */ @@ -2563,8 +2569,8 @@ FlushLog(XtermWidget xw) #endif /* VMS */ cp = VTbuffer->next; if (screen->logstart != 0 - && (i = (int) (cp - screen->logstart)) > 0) { - IGNORE_RC(write(screen->logfd, screen->logstart, (size_t) i)); + && (i = (size_t) (cp - screen->logstart)) > 0) { + IGNORE_RC(write(screen->logfd, screen->logstart, i)); } screen->logstart = VTbuffer->next; } @@ -2599,7 +2605,7 @@ maskToWidth(unsigned long mask) return result; } -int +XVisualInfo * getVisualInfo(XtermWidget xw) { #define MYFMT "getVisualInfo \ @@ -2640,7 +2646,12 @@ rgb masks (%04lx/%04lx/%04lx)\n" (vi->blue_mask != 0) && ((vi->red_mask & vi->green_mask) == 0) && ((vi->green_mask & vi->blue_mask) == 0) && - ((vi->blue_mask & vi->red_mask) == 0)); + ((vi->blue_mask & vi->red_mask) == 0) && + xw->rgb_widths[0] <= (unsigned) vi->bits_per_rgb && + xw->rgb_widths[1] <= (unsigned) vi->bits_per_rgb && + xw->rgb_widths[2] <= (unsigned) vi->bits_per_rgb && + (vi->class == TrueColor + || vi->class == DirectColor)); if (resource.reportColors) { printf(MYFMT, MYARG); @@ -2650,9 +2661,13 @@ rgb masks (%04lx/%04lx/%04lx)\n" xw->rgb_shifts[0], xw->rgb_shifts[1], xw->rgb_shifts[2])); + TRACE(("...widths %u/%u/%u\n", + xw->rgb_widths[0], + xw->rgb_widths[1], + xw->rgb_widths[2])); } } - return (xw->visInfo != 0) && (xw->numVisuals > 0); + return (xw->visInfo != 0) && (xw->numVisuals > 0) ? xw->visInfo : NULL; #undef MYFMT #undef MYARG } @@ -2665,12 +2680,11 @@ ReportAnsiColorRequest(XtermWidget xw, int opcode, int colornum, int final) if (AllowColorOps(xw, ecGetAnsiColor)) { XColor color; - Colormap cmap = xw->core.colormap; char buffer[80]; TRACE(("ReportAnsiColorRequest %d\n", colornum)); color.pixel = GET_COLOR_RES(xw, TScreenOf(xw)->Acolors[colornum]); - XQueryColor(TScreenOf(xw)->display, cmap, &color); + (void) QueryOneColor(xw, &color); sprintf(buffer, "%d;%d;rgb:%04x/%04x/%04x", opcode, (opcode == 5) ? (colornum - NUM_ANSI_COLORS) : colornum, @@ -2737,6 +2751,79 @@ loadColorTable(XtermWidget xw, unsigned length) return result; } +/***====================================================================***/ + +/* + * Call this function with def->{red,green,blue} initialized, to obtain a pixel + * value. + */ +Boolean +AllocOneColor(XtermWidget xw, XColor *def) +{ + TScreen *screen = TScreenOf(xw); + Boolean result = True; + +#define MaskIt(name,nn) \ + ((unsigned long) ((def->name >> (16 - xw->rgb_widths[nn])) \ + << xw->rgb_shifts[nn]) \ + & xw->visInfo->name ##_mask) + +#define VisualIsRGB(xw) (getVisualInfo(xw) != NULL && xw->has_rgb && xw->visInfo->bits_per_rgb <= 8) + + if (VisualIsRGB(xw)) { + def->pixel = MaskIt(red, 0) | MaskIt(green, 1) | MaskIt(blue, 2); + } else { + Display *dpy = screen->display; + if (!XAllocColor(dpy, xw->core.colormap, def)) { + /* + * Decide between foreground and background by a grayscale + * approximation. + */ + int bright = def->red * 3 + def->green * 10 + def->blue; + int levels = 14 * 0x8000; + def->pixel = ((bright >= levels) + ? xw->dft_background + : xw->dft_foreground); + TRACE(("XAllocColor failed, for %04x/%04x/%04x: choose %08lx (%d vs %d)\n", + def->red, def->green, def->blue, + def->pixel, bright, levels)); + result = False; + } + } + return result; +} + +/***====================================================================***/ + +/* + * Call this function with def->pixel set to the color that we want to convert + * to separate red/green/blue. + */ +Boolean +QueryOneColor(XtermWidget xw, XColor *def) +{ + Boolean result = True; + +#define UnMaskIt(name,nn) \ + ((unsigned short)((def->pixel & xw->visInfo->name ##_mask) >> xw->rgb_shifts[nn])) +#define UnMaskIt2(name,nn) \ + (unsigned short)((((UnMaskIt(name,nn) << 8) \ + |UnMaskIt(name,nn))) << (8 - xw->rgb_widths[nn])) + + if (VisualIsRGB(xw)) { + /* *INDENT-EQLS* */ + def->red = UnMaskIt2(red, 0); + def->green = UnMaskIt2(green, 1); + def->blue = UnMaskIt2(blue, 2); + } else { + Display *dpy = TScreenOf(xw)->display; + if (!XQueryColor(dpy, xw->core.colormap, def)) { + TRACE(("XQueryColor failed, given %08lx\n", def->pixel)); + result = False; + } + } + return result; +} /***====================================================================***/ @@ -2751,7 +2838,7 @@ loadColorTable(XtermWidget xw, unsigned length) * Return False if not able to find or allocate a color. */ static Boolean -allocateClosestRGB(XtermWidget xw, Colormap cmap, XColor *def) +allocateClosestRGB(XtermWidget xw, XColor *def) { TScreen *screen = TScreenOf(xw); Boolean result = False; @@ -2805,8 +2892,7 @@ allocateClosestRGB(XtermWidget xw, Colormap cmap, XColor *def) } } } - if (XAllocColor(screen->display, cmap, - &screen->cmap_data[bestInx]) != 0) { + if (AllocOneColor(xw, &screen->cmap_data[bestInx])) { *def = screen->cmap_data[bestInx]; TRACE(("...closest %x/%x/%x\n", def->red, def->green, def->blue)); @@ -2831,193 +2917,6 @@ allocateClosestRGB(XtermWidget xw, Colormap cmap, XColor *def) #define ULONG_MAX (unsigned long)(~(0L)) #endif -#define CheckColor(result, value) \ - result = 0; \ - if (value.red) \ - result |= 1; \ - if (value.green) \ - result |= 2; \ - if (value.blue) \ - result |= 4 - -#define SelectColor(state, value, result) \ - switch (state) { \ - default: \ - case 1: \ - result = value.red; \ - break; \ - case 2: \ - result = value.green; \ - break; \ - case 4: \ - result = value.blue; \ - break; \ - } - -/* - * Check if the color map consists of values in exactly one of the red, green - * or blue columns. If it is not, we do not know how to use it for the exact - * match. - */ -static int -simpleColors(XColor *colortable, unsigned length) -{ - unsigned n; - int state = 0; - int check; - - for (n = 0; n < length; ++n) { - if (state > 0) { - CheckColor(check, colortable[n]); - if (check > 0 && check != state) { - state = 0; - break; - } - } else { - CheckColor(state, colortable[n]); - } - } - switch (state) { - case 1: - case 2: - case 4: - break; - default: - state = 0; - break; - } - return state; -} - -/* - * Shift the mask left or right to put its most significant bit at the 16-bit - * mark. - */ -static unsigned -normalizeMask(unsigned mask) -{ - while (mask < 0x8000) { - mask <<= 1; - } - while (mask >= 0x10000) { - mask >>= 1; - } - return mask; -} - -static unsigned -searchColors(XColor *colortable, unsigned mask, unsigned length, unsigned - color, int state) -{ - unsigned result = 0; - unsigned n; - unsigned long best = ULONG_MAX; - unsigned value; - - mask = normalizeMask(mask); - for (n = 0; n < length; ++n) { - unsigned long diff; - - SelectColor(state, colortable[n], value); - diff = ((color & mask) - (value & mask)); - diff *= diff; - if (diff < best) { -#if 0 - TRACE(("...%d:looking for %x, found %x/%x/%x (%lx)\n", - n, color, - colortable[n].red, - colortable[n].green, - colortable[n].blue, - diff)); -#endif - result = n; - best = diff; - } - } - SelectColor(state, colortable[result], value); - return value; -} - -/* - * This is a workaround for a longstanding defect in the X libraries. - * - * According to - * http://www.unix.com/man-page/all/3x/XAllocColoA/ - * - * XAllocColor() acts differently on static and dynamic visuals. On Pseu- - * doColor, DirectColor, and GrayScale visuals, XAllocColor() fails if - * there are no unallocated colorcells and no allocated read-only cell - * exactly matches the requested RGB values. On StaticColor, TrueColor, - * and StaticGray visuals, XAllocColor() returns the closest RGB values - * available in the colormap. The colorcell_in_out structure returns the - * actual RGB values allocated. - * - * That is, XAllocColor() should suffice unless the color map is full. In that - * case, allocateClosestRGB() is useful for the dynamic display classes such as - * PseudoColor. It is not useful for TrueColor, since XQueryColors() does not - * return regular RGB triples (unless a different scheme was used for - * specifying the pixel values); only the blue value is filled in. However, it - * is filled in with the colors that the server supports. - * - * Also (the reason for this function), XAllocColor() does not really work as - * described. For some TrueColor configurations it merely returns a close - * approximation, but not the closest. - */ -static Boolean -allocateExactRGB(XtermWidget xw, Colormap cmap, XColor *def) -{ - XColor save = *def; - TScreen *screen = TScreenOf(xw); - Boolean result = (Boolean) (XAllocColor(screen->display, cmap, def) != 0); - - /* - * If this is a statically allocated display with too many items to store - * in our array, i.e., TrueColor, see if we can improve on the result by - * using the color values actually supported by the server. - */ - if (result) { - unsigned cmap_type; - unsigned cmap_size; - - getColormapInfo(xw, &cmap_type, &cmap_size); - - if (cmap_type == TrueColor) { - XColor temp = *def; - int state; - - if (loadColorTable(xw, cmap_size) - && (state = simpleColors(screen->cmap_data, cmap_size)) > 0) { -#define SearchColors(which) \ - temp.which = (unsigned short) searchColors(screen->cmap_data, \ - (unsigned) xw->visInfo->which##_mask,\ - cmap_size, \ - save.which, \ - state) - SearchColors(red); - SearchColors(green); - SearchColors(blue); - if (XAllocColor(screen->display, cmap, &temp) != 0) { -#if OPT_TRACE - if (temp.red != save.red - || temp.green != save.green - || temp.blue != save.blue) { - TRACE(("...improved %x/%x/%x ->%x/%x/%x\n", - save.red, save.green, save.blue, - temp.red, temp.green, temp.blue)); - } else { - TRACE(("...no improvement for %x/%x/%x\n", - save.red, save.green, save.blue)); - } -#endif - *def = temp; - } - } - } - } - - return result; -} - /* * Allocate a color for the "ANSI" colors. That actually includes colors up * to 256. @@ -3036,11 +2935,8 @@ AllocateAnsiColor(XtermWidget xw, XColor def; if (xtermAllocColor(xw, &def, spec)) { - if ( -#if OPT_COLOR_RES - res->mode == True && -#endif - EQL_COLOR_RES(res, def.pixel)) { + if (res->mode == True && + EQL_COLOR_RES(res, def.pixel)) { result = 0; } else { result = 1; @@ -3054,11 +2950,9 @@ AllocateAnsiColor(XtermWidget xw, def.green, def.blue, def.pixel)); -#if OPT_COLOR_RES if (!res->mode) result = 0; res->mode = True; -#endif } } else { TRACE(("AllocateAnsiColor %s (failed)\n", spec)); @@ -3067,7 +2961,6 @@ AllocateAnsiColor(XtermWidget xw, return (result); } -#if OPT_COLOR_RES Pixel xtermGetColorRes(XtermWidget xw, ColorRes * res) { @@ -3095,7 +2988,6 @@ xtermGetColorRes(XtermWidget xw, ColorRes * res) } return result; } -#endif static int ChangeOneAnsiColor(XtermWidget xw, int color, const char *name) @@ -3234,16 +3126,15 @@ ResetAnsiColorRequest(XtermWidget xw, char *buf, int start) return repaint; } #else -#define allocateClosestRGB(xw, cmap, def) 0 -#define allocateExactRGB(xw, cmap, def) XAllocColor(TScreenOf(xw)->display, cmap, def) +#define allocateClosestRGB(xw, def) 0 #endif /* OPT_ISO_COLORS */ Boolean allocateBestRGB(XtermWidget xw, XColor *def) { - Colormap cmap = xw->core.colormap; - - return allocateExactRGB(xw, cmap, def) || allocateClosestRGB(xw, cmap, def); + (void) xw; + (void) def; + return AllocOneColor(xw, def) || allocateClosestRGB(xw, def); } static Boolean @@ -3256,7 +3147,7 @@ xtermAllocColor(XtermWidget xw, XColor *def, const char *spec) if (have == 0 || have > MAX_U_STRING) { if (resource.reportColors) { - printf("color (ignored, length %lu)\n", have); + printf("color (ignored, length %lu)\n", (unsigned long) have); } } else if (XParseColor(screen->display, cmap, spec, def)) { XColor save_def = *def; @@ -3293,7 +3184,7 @@ int xtermClosestColor(XtermWidget xw, int find_red, int find_green, int find_blue) { int result = -1; -#if OPT_COLOR_RES && OPT_ISO_COLORS +#if OPT_ISO_COLORS int n; int best_index = -1; unsigned long best_value = 0; @@ -3328,6 +3219,7 @@ xtermClosestColor(XtermWidget xw, int find_red, int find_green, int find_blue) } TRACE(("...best match at %d with diff %lx\n", best_index, best_value)); result = best_index; + #else (void) xw; (void) find_red; @@ -3341,19 +3233,48 @@ xtermClosestColor(XtermWidget xw, int find_red, int find_green, int find_blue) int getDirectColor(XtermWidget xw, int red, int green, int blue) { -#define nRGB(name,shift) \ - ((unsigned long)(name << xw->rgb_shifts[shift]) \ - & xw->visInfo->name ##_mask) - MyPixel result = (MyPixel) (nRGB(red, 0) | nRGB(green, 1) | nRGB(blue, 2)); + Pixel result = 0; + +#define getRGB(name,shift) \ + do { \ + Pixel value = (Pixel) name & 0xff; \ + if (xw->rgb_widths[shift] < 8) { \ + value >>= (int) (8 - xw->rgb_widths[shift]); \ + } \ + value <<= xw->rgb_shifts[shift]; \ + value &= xw->visInfo->name ##_mask; \ + result |= value; \ + } while (0) + + getRGB(red, 0); + getRGB(green, 1); + getRGB(blue, 2); + +#undef getRGB + return (int) result; } static void formatDirectColor(char *target, XtermWidget xw, unsigned value) { -#define fRGB(name, shift) \ - (value & xw->visInfo->name ## _mask) >> xw->rgb_shifts[shift] - sprintf(target, "%lu:%lu:%lu", fRGB(red, 0), fRGB(green, 1), fRGB(blue, 2)); + Pixel result[3]; + +#define getRGB(name, shift) \ + do { \ + result[shift] = value & xw->visInfo->name ## _mask; \ + result[shift] >>= xw->rgb_shifts[shift]; \ + if (xw->rgb_widths[shift] < 8) \ + result[shift] <<= (int) (8 - xw->rgb_widths[shift]); \ + } while(0) + + getRGB(red, 0); + getRGB(green, 1); + getRGB(blue, 2); + +#undef getRGB + + sprintf(target, "%lu:%lu:%lu", result[0], result[1], result[2]); } #endif /* OPT_DIRECT_COLOR */ @@ -3455,93 +3376,85 @@ ManipulateSelectionData(XtermWidget xw, TScreen *screen, char *buf, int final) PDATA('6', CUT_BUFFER6), PDATA('7', CUT_BUFFER7), }; + char target_used[XtNumber(table)]; + char select_code[XtNumber(table) + 1]; + String select_args[XtNumber(table) + 1]; const char *base = buf; - Cardinal j, n = 0; + Cardinal j; + Cardinal num_targets = 0; TRACE(("Manipulate selection data\n")); + memset(target_used, 0, sizeof(target_used)); while (*buf != ';' && *buf != '\0') { ++buf; } if (*buf == ';') { - char *used; *buf++ = '\0'; - if (*base == '\0') base = "s0"; - if ((used = x_strdup(base)) != 0) { - String *select_args; - - if ((select_args = TypeCallocN(String, 2 + strlen(base))) != 0) { - while (*base != '\0') { - for (j = 0; j < XtNumber(table); ++j) { - if (*base == table[j].given) { - used[n] = *base; - select_args[n++] = table[j].result; - TRACE(("atom[%d] %s\n", n, table[j].result)); - break; - } + while (*base != '\0') { + for (j = 0; j < XtNumber(table); ++j) { + if (*base == table[j].given) { + if (!target_used[j]) { + target_used[j] = 1; + select_code[num_targets] = *base; + select_args[num_targets++] = table[j].result; + TRACE(("atom[%d] %s\n", num_targets, table[j].result)); } - ++base; + break; } - used[n] = 0; - - if (!strcmp(buf, "?")) { - if (AllowWindowOps(xw, ewGetSelection)) { - TRACE(("Getting selection\n")); - unparseputc1(xw, ANSI_OSC); - unparseputs(xw, "52"); - unparseputc(xw, ';'); - - unparseputs(xw, used); - unparseputc(xw, ';'); - - /* Tell xtermGetSelection data is base64 encoded */ - screen->base64_paste = n; - screen->base64_final = final; - - screen->selection_time = - XtLastTimestampProcessed(TScreenOf(xw)->display); - - /* terminator will be written in this call */ - xtermGetSelection((Widget) xw, - screen->selection_time, - select_args, n, - NULL); - /* - * select_args is used via SelectionReceived, cannot - * free it here. - */ - } else { - free(select_args); - } - } else { - if (AllowWindowOps(xw, ewSetSelection)) { - char *old = buf; - - TRACE(("Setting selection(%s) with %s\n", used, buf)); - screen->selection_time = - XtLastTimestampProcessed(TScreenOf(xw)->display); - - for (j = 0; j < n; ++j) { - buf = old; - ClearSelectionBuffer(screen, select_args[j]); - while (*buf != '\0') { - AppendToSelectionBuffer(screen, - CharOf(*buf++), - select_args[j]); - } - } - CompleteSelection(xw, select_args, n); + } + ++base; + } + select_code[num_targets] = '\0'; + + if (!strcmp(buf, "?")) { + if (AllowWindowOps(xw, ewGetSelection)) { + TRACE(("Getting selection\n")); + unparseputc1(xw, ANSI_OSC); + unparseputs(xw, "52"); + unparseputc(xw, ';'); + + unparseputs(xw, select_code); + unparseputc(xw, ';'); + + /* Tell xtermGetSelection data is base64 encoded */ + screen->base64_paste = num_targets; + screen->base64_final = final; + + screen->selection_time = + XtLastTimestampProcessed(TScreenOf(xw)->display); + + /* terminator will be written in this call */ + xtermGetSelection((Widget) xw, + screen->selection_time, + select_args, num_targets, + NULL); + } + } else { + if (AllowWindowOps(xw, ewSetSelection)) { + char *old = buf; + + TRACE(("Setting selection(%s) with %s\n", select_code, buf)); + screen->selection_time = + XtLastTimestampProcessed(TScreenOf(xw)->display); + + for (j = 0; j < num_targets; ++j) { + buf = old; + ClearSelectionBuffer(screen, select_args[j]); + while (*buf != '\0') { + AppendToSelectionBuffer(screen, + CharOf(*buf++), + select_args[j]); } - free(select_args); } + CompleteSelection(xw, select_args, num_targets); } - free(used); } } } @@ -3697,7 +3610,6 @@ ReportColorRequest(XtermWidget xw, int ndx, int final) if (AllowColorOps(xw, ecGetColor)) { XColor color; - Colormap cmap = xw->core.colormap; char buffer[80]; /* @@ -3709,7 +3621,7 @@ ReportColorRequest(XtermWidget xw, int ndx, int final) GetOldColors(xw); color.pixel = xw->work.oldColors->colors[ndx]; - XQueryColor(TScreenOf(xw)->display, cmap, &color); + (void) QueryOneColor(xw, &color); sprintf(buffer, "%d;rgb:%04x/%04x/%04x", i + 10, color.red, color.green, @@ -3850,8 +3762,6 @@ ResetColorsRequest(XtermWidget xw, (void) code; TRACE(("ResetColorsRequest code=%d\n", code)); - -#if OPT_COLOR_RES if (GetOldColors(xw)) { ScrnColors newColors; const char *thisName; @@ -3877,7 +3787,6 @@ ResetColorsRequest(XtermWidget xw, } result = True; } -#endif return result; } @@ -4116,8 +4025,8 @@ do_osc(XtermWidget xw, Char *oscbuf, size_t len, int final) /* FALLTHRU */ case 1: if (*cp != ';') { - TRACE(("do_osc did not find semicolon offset %d\n", - (int) (cp - oscbuf))); + TRACE(("do_osc did not find semicolon offset %lu\n", + (unsigned long) (cp - oscbuf))); return; } state = 2; @@ -4134,9 +4043,9 @@ do_osc(XtermWidget xw, Char *oscbuf, size_t len, int final) case 2: break; default: - TRACE(("do_osc found nonprinting char %02X offset %d\n", + TRACE(("do_osc found nonprinting char %02X offset %lu\n", CharOf(*cp), - (int) (cp - oscbuf))); + (unsigned long) (cp - oscbuf))); return; } } @@ -7075,7 +6984,9 @@ die_callback(Widget w GCC_UNUSED, XtPointer client_data GCC_UNUSED, XtPointer call_data GCC_UNUSED) { - TRACE(("die_callback %p\n", die_callback)); + TRACE(("die_callback client=%p, call=%p\n", + (void *) client_data, + (void *) call_data)); TRACE_SM_PROPS(); NormalExit(); } @@ -7285,7 +7196,7 @@ findFontParams(int argc, char **argv) } static int -insertFontParams(XtermWidget xw, int *targetp, Boolean first) +insertFontParams(XtermWidget xw, int *targetp, Bool first) { int changed = 0; int n; @@ -7580,14 +7491,6 @@ update_winsize(TScreen *screen, int rows, int cols, int height, int width) last_cols = cols; last_high = height; last_wide = width; -#if OPT_STATUS_LINE - if (IsStatusShown(screen)) { - ++rows; - height += FontHeight(screen); - TRACE(("... account for status-line -> %dx%d (%dx%d)\n", - rows, cols, height, width)); - } -#endif setup_winsize(ts, rows, cols, height, width); TRACE_RC(code, SET_TTYSIZE(screen->respond, ts)); trace_winsize(ts, "from SET_TTYSIZE"); diff --git a/app/xterm/package/debian/changelog b/app/xterm/package/debian/changelog index 05addf845..29966537f 100644 --- a/app/xterm/package/debian/changelog +++ b/app/xterm/package/debian/changelog @@ -1,3 +1,15 @@ +xterm-dev (374) unstable; urgency=low + + * maintenance updates + + -- Thomas E. Dickey <dickey@invisible-island.net> Tue, 27 Sep 2022 04:18:41 -0400 + +xterm-dev (373) unstable; urgency=low + + * maintenance updates + + -- Thomas E. Dickey <dickey@invisible-island.net> Fri, 11 Mar 2022 14:51:56 -0500 + xterm-dev (372) unstable; urgency=low * maintenance updates diff --git a/app/xterm/package/freebsd/Makefile b/app/xterm/package/freebsd/Makefile index a301cf751..b8ab1790e 100644 --- a/app/xterm/package/freebsd/Makefile +++ b/app/xterm/package/freebsd/Makefile @@ -1,4 +1,4 @@ -# $XTermId: Makefile,v 1.93 2022/03/04 21:39:26 tom Exp $ +# $XTermId: Makefile,v 1.95 2022/09/27 08:18:41 tom Exp $ # $FreeBSD: head/x11/xterm/Makefile 492827 2019-02-13 06:43:36Z ehaupt $ # This is adapted from the FreeBSD port, installing as "xterm-dev" with @@ -7,7 +7,7 @@ # and "make makesum". PORTNAME= xterm -PORTVERSION= 372 +PORTVERSION= 374 CATEGORIES= x11 MASTER_SITES= ftp://ftp.invisible-island.net/xterm/:src1 \ https://invisible-mirror.net/archives/xterm/:src1 diff --git a/app/xterm/package/pkgsrc/Makefile b/app/xterm/package/pkgsrc/Makefile index f9b7ece60..bed75dcb8 100644 --- a/app/xterm/package/pkgsrc/Makefile +++ b/app/xterm/package/pkgsrc/Makefile @@ -1,6 +1,6 @@ # $NetBSD: Makefile,v 1.117 2018/03/12 11:18:00 wiz Exp $ -DISTNAME= xterm-372 +DISTNAME= xterm-374 PKGREVISION= 1 CATEGORIES= x11 MASTER_SITES= ftp://ftp.invisible-island.net/xterm/ diff --git a/app/xterm/package/xterm.spec b/app/xterm/package/xterm.spec index 883482d53..2de0a002e 100644 --- a/app/xterm/package/xterm.spec +++ b/app/xterm/package/xterm.spec @@ -1,11 +1,11 @@ -# $XTermId: xterm.spec,v 1.149 2022/03/04 21:39:26 tom Exp $ +# $XTermId: xterm.spec,v 1.151 2022/09/27 08:18:41 tom Exp $ Summary: X terminal emulator (development version) %global my_middle xterm %global my_suffix -dev %global fullname %{my_middle}%{my_suffix} %global my_class XTermDev Name: %{fullname} -Version: 372 +Version: 374 Release: 1 License: X11 Group: User Interface/X diff --git a/app/xterm/plink.sh b/app/xterm/plink.sh index 045f3a23a..ff625a919 100644 --- a/app/xterm/plink.sh +++ b/app/xterm/plink.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: plink.sh,v 1.16 2022/02/13 14:30:17 tom Exp $ +# $XTermId: plink.sh,v 1.17 2022/03/13 18:27:29 Ryan.Schmidt Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -44,13 +44,15 @@ case "$*" in ;; esac +: "${TMPDIR=/tmp}" + while [ $# != 0 ] do if [ $ASNEED = no ] && [ -n "$LINKIT" ] then ASNEED=yes OPT=-Wl,-as-needed - warned=`mktemp` + warned=`mktemp "$TMPDIR/xterm.XXXXXXXX"` trap "rm -f $warned; exit 1" 1 2 3 15 trap "rm -f $warned" 0 if ( eval $LINKIT $OPT $NO_LTO "$@" >"$warned" 2>&1 ) diff --git a/app/xterm/print.c b/app/xterm/print.c index bdb42e0bb..d97e70051 100644 --- a/app/xterm/print.c +++ b/app/xterm/print.c @@ -1,7 +1,7 @@ -/* $XTermId: print.c,v 1.172 2021/03/02 00:19:13 tom Exp $ */ +/* $XTermId: print.c,v 1.173 2022/09/18 21:00:08 tom Exp $ */ /* - * Copyright 1997-2020,2021 by Thomas E. Dickey + * Copyright 1997-2021,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -325,16 +325,16 @@ xtermPrintEverything(XtermWidget xw, PrinterFlags *p) printLines(xw, -screen->savedlines, -(screen->topline + 1), p); } if (p->print_everything & 4) { - SwitchBufPtrs(screen, 1); + SwitchBufPtrs(xw, 1); done_which |= 2; printLines(xw, 0, screen->max_row, p); - SwitchBufPtrs(screen, save_which); + SwitchBufPtrs(xw, save_which); } if (p->print_everything & 2) { - SwitchBufPtrs(screen, 0); + SwitchBufPtrs(xw, 0); done_which |= 1; printLines(xw, 0, screen->max_row, p); - SwitchBufPtrs(screen, save_which); + SwitchBufPtrs(xw, save_which); } if (p->print_everything & 1) { if (!(done_which & (1 << screen->whichBuf))) { diff --git a/app/xterm/ptydata.c b/app/xterm/ptydata.c index f3dfa3df8..8b664ecd6 100644 --- a/app/xterm/ptydata.c +++ b/app/xterm/ptydata.c @@ -1,7 +1,7 @@ -/* $XTermId: ptydata.c,v 1.150 2020/10/12 18:46:28 tom Exp $ */ +/* $XTermId: ptydata.c,v 1.158 2022/10/10 19:27:56 tom Exp $ */ /* - * Copyright 1999-2019,2020 by Thomas E. Dickey + * Copyright 1999-2020,2022 by Thomas E. Dickey * * All Rights Reserved * @@ -68,8 +68,8 @@ Bool decodeUtf8(TScreen *screen, PtyData *data) { - int i; - int length = (int) (data->last - data->next); + size_t i; + size_t length = (size_t) (data->last - data->next); int utf_count = 0; unsigned utf_char = 0; @@ -226,8 +226,8 @@ decodeUtf8(TScreen *screen, PtyData *data) #if OPT_TRACE > 1 TRACE(("UTF-8 char %04X [%d..%d]\n", data->utf_data, - (int) (data->next - data->buffer), - (int) (data->next - data->buffer + data->utf_size - 1))); + (size_t) (data->next - data->buffer), + (size_t) (data->next - data->buffer + data->utf_size - 1))); #endif return (data->utf_size != 0); @@ -410,10 +410,10 @@ trimPtyData(XtermWidget xw, PtyData *data) FlushLog(xw); if (data->next != data->buffer) { - int i; - int n = (int) (data->last - data->next); + size_t i; + size_t n = (size_t) (data->last - data->next); - TRACE(("shifting buffer down by %d\n", n)); + TRACE(("shifting buffer down by %lu\n", (unsigned long) n)); for (i = 0; i < n; ++i) { data->buffer[i] = data->next[i]; } @@ -428,16 +428,16 @@ trimPtyData(XtermWidget xw, PtyData *data) * and nextPtyData() will return that. */ void -fillPtyData(XtermWidget xw, PtyData *data, const char *value, int length) +fillPtyData(XtermWidget xw, PtyData *data, const char *value, size_t length) { - int size; - int n; + size_t size; + size_t n; /* remove the used portion of the buffer */ trimPtyData(xw, data); VTbuffer->last += length; - size = (int) (VTbuffer->last - VTbuffer->next); + size = (size_t) (VTbuffer->last - VTbuffer->next); /* shift the unused portion up to make room */ for (n = size; n >= length; --n) @@ -605,20 +605,19 @@ isValidUTF8(Char *lp) * Write data back to the PTY */ void -writePtyData(int f, IChar *d, unsigned len) +writePtyData(int f, IChar *d, size_t len) { - unsigned n = (len << 1); + size_t n = (len << 1); if (VTbuffer->write_len <= len) { VTbuffer->write_len = n; - VTbuffer->write_buf = (Char *) XtRealloc((char *) - VTbuffer->write_buf, VTbuffer->write_len); + VTbuffer->write_buf = realloc(VTbuffer->write_buf, VTbuffer->write_len); } for (n = 0; n < len; n++) VTbuffer->write_buf[n] = (Char) d[n]; - TRACE(("writePtyData %u:%s\n", n, + TRACE(("writePtyData %lu:%s\n", (unsigned long) n, visibleChars(VTbuffer->write_buf, n))); v_write(f, VTbuffer->write_buf, n); } @@ -668,7 +667,7 @@ FlushLog(XtermWidget xw) #endif void -v_write(int f, const Char *data, unsigned len) +v_write(int f, const Char *data, size_t len) { (void) f; (void) data; @@ -923,8 +922,8 @@ do_range(const char *source) c_in, c_out); } else if (message_level > 1) { *next = '\0'; - printf("TEST %04X (%d:%s) ->%04X\n", c_in, - (int) (next - buffer), + printf("TEST %04X (%lu:%s) ->%04X\n", c_in, + (unsigned long) (next - buffer), buffer, c_out); fflush(stdout); @@ -937,8 +936,8 @@ do_range(const char *source) data->last = next; decodeUtf8(&screen, data); if (message_level > 1) { - printf("TEST %04X (%d:%s) ->%04X\n", c_in, - (int) (next - data->buffer), + printf("TEST %04X (%lu:%s) ->%04X\n", c_in, + (unsigned long) (next - data->buffer), data->buffer, data->utf_data); fflush(stdout); diff --git a/app/xterm/ptyx.h b/app/xterm/ptyx.h index e392dc9fa..ab50f5c77 100644 --- a/app/xterm/ptyx.h +++ b/app/xterm/ptyx.h @@ -1,4 +1,4 @@ -/* $XTermId: ptyx.h,v 1.1060 2022/03/08 23:31:40 tom Exp $ */ +/* $XTermId: ptyx.h,v 1.1076 2022/10/07 08:00:53 Ben.Wong Exp $ */ /* * Copyright 1999-2021,2022 by Thomas E. Dickey @@ -81,6 +81,7 @@ #endif #include <stdio.h> +#include <limits.h> #if defined(HAVE_STDINT_H) || !defined(HAVE_CONFIG_H) #include <stdint.h> @@ -92,8 +93,8 @@ /* adapted from IntrinsicI.h */ #define MyStackAlloc(size, stack_cache_array) \ ((size) <= sizeof(stack_cache_array) \ - ? (XtPointer)(stack_cache_array) \ - : (XtPointer)malloc((size_t)(size))) + ? (stack_cache_array) \ + : (char*)malloc((size_t)(size))) #define MyStackFree(pointer, stack_cache_array) \ if ((pointer) != ((char *)(stack_cache_array))) free(pointer) @@ -313,6 +314,7 @@ typedef enum { #define MaxCols(screen) ((screen)->max_col + 1) #define MaxRows(screen) ((screen)->max_row + 1) +#define MaxUChar 255 typedef unsigned char Char; /* to support 8 bit chars */ typedef Char *ScrnPtr; typedef ScrnPtr *ScrnBuf; @@ -422,7 +424,7 @@ typedef struct { #define TERMCAP_SIZE 1500 /* 1023 is standard; 'screen' exceeds */ #define MAX_XLFD_FONTS 1 -#define MAX_XFT_FONTS 1 +#define MAX_XFT_FONTS 2 #define NMENUFONTS 10 /* font entries in fontMenu */ #define NBOX 5 /* Number of Points in box */ @@ -552,10 +554,6 @@ typedef enum { #define OPT_COLOR_CLASS 1 /* true if xterm uses separate color-resource classes */ #endif -#ifndef OPT_COLOR_RES -#define OPT_COLOR_RES 1 /* true if xterm delays color-resource evaluation */ -#endif - #ifndef OPT_DABBREV #define OPT_DABBREV 0 /* dynamic abbreviations */ #endif @@ -572,6 +570,10 @@ typedef enum { #define OPT_DEC_RECTOPS 1 /* true if xterm is configured for VT420 rectangles */ #endif +#ifndef OPT_SGR2_HASH +#define OPT_SGR2_HASH 1 /* true if xterm hashes color-lookups for faint color */ +#endif + #ifndef OPT_SIXEL_GRAPHICS #define OPT_SIXEL_GRAPHICS 0 /* true if xterm supports VT240-style sixel graphics */ #endif @@ -608,6 +610,10 @@ typedef enum { #endif #endif +#ifndef OPT_EXEC_SELECTION +#define OPT_EXEC_SELECTION 1 /* true if xterm can exec to process selection */ +#endif + #ifndef OPT_EXEC_XTERM #define OPT_EXEC_XTERM 0 /* true if xterm can fork/exec copies of itself */ #endif @@ -1711,9 +1717,9 @@ typedef struct { int update; /* HandleInterpret */ #if OPT_WIDE_CHARS IChar utf_data; /* resulting character */ - int utf_size; /* ...number of bytes decoded */ + size_t utf_size; /* ...number of bytes decoded */ Char *write_buf; - unsigned write_len; + size_t write_len; #endif Char buffer[1]; } PtyData; @@ -1897,9 +1903,22 @@ typedef struct { Bool mixed; Dimension min_width; /* nominal cell width for 0..255 */ Dimension max_width; /* maximum cell width */ -} FontMap; +} XTermFontInfo; -#define KNOWN_MISSING 256 + /* + * Map of characters to simplify/speed-up the checks for missing glyphs + * at runtime. + * + * FIXME: initially implement for Xft, but replace known_missing[] in + * X11 fonts as well. + */ +typedef struct { + int depth; /* number of fonts merged for map */ + size_t limit; /* allocated size of per_font, etc */ + size_t first_char; /* merged first-character index */ + size_t last_char; /* merged last-character index */ + Char * per_font; /* index 1-n of first font with char */ +} XTermFontMap; typedef enum { fwNever = 0, @@ -1913,8 +1932,8 @@ typedef struct { fontWarningTypes warn; XFontStruct * fs; char * fn; - FontMap map; - Char known_missing[KNOWN_MISSING]; + XTermFontInfo font_info; + Char known_missing[MaxUChar + 1]; } XTermFonts; #if OPT_RENDERFONT @@ -1935,23 +1954,29 @@ typedef enum { , xcBogus /* ignore this pattern */ , xcOpened /* slot has open font descriptor */ , xcUnused /* opened, but unused so far */ -} XftCache; +} XTermXftState; typedef struct { XftFont * font; - XftCache usage; + XTermXftState usage; } XTermXftCache; typedef struct { - XftFont * font; /* main font */ XftPattern * pattern; /* pattern for main font */ XftFontSet * fontset; /* ordered list of fallback patterns */ - XTermXftCache * cache; - unsigned limit; /* allocated size of cache[] */ - unsigned opened; /* number of slots with xcOpened */ - FontMap map; + XTermXftCache cache[MaxUChar + 1]; /* list of open font pointers */ + unsigned fs_size; /* allocated size of cache[] */ + Char opened; /* number in cache[] with xcOpened */ + XTermFontInfo font_info; /* summary of font metrics */ + XTermFontMap font_map; /* map of glyphs provided in fontset */ } XTermXftFonts; +#define XftFpN(p,n) (p)->cache[(n)].font +#define XftIsN(p,n) (p)->cache[(n)].usage + +#define XftFp(p) XftFpN(p,0) +#define XftIs(p) XftIsN(p,0) + typedef struct _ListXftFonts { struct _ListXftFonts *next; XftFont * font; @@ -2334,6 +2359,9 @@ typedef struct { #if OPT_DIRECT_COLOR Boolean direct_color; /* direct-color enabled? */ #endif +#if OPT_WIDE_ATTRS && OPT_SGR2_HASH + Boolean faint_relative; /* faint is relative? */ +#endif #endif /* OPT_ISO_COLORS */ #if OPT_DEC_CHRSET Boolean font_doublesize;/* enable font-scaling */ @@ -2342,7 +2370,7 @@ typedef struct { int fonts_used; /* count items in double_fonts */ XTermFonts double_fonts[NUM_CHRSET]; #if OPT_RENDERFONT - XftFont * double_xft_fonts[NUM_CHRSET]; + XTermXftFonts double_xft_fonts[NUM_CHRSET]; #endif #endif /* OPT_DEC_CHRSET */ #if OPT_DEC_RECTOPS @@ -2762,6 +2790,7 @@ typedef struct { #define AddStatusLineRows(nrow) /* nothing */ #define LastRowNumber(screen) (screen)->max_row #define FirstRowNumber(screen) 0 +#define IsStatusShown(screen) False #define PlusStatusLine(screen,expr) (expr) #define if_STATUS_LINE(screen,stmt) /* nothing */ @@ -2896,12 +2925,17 @@ typedef struct { void * icon_cgs_cache; #endif #if OPT_RENDERFONT + int xft_max_glyph_memory; + int xft_max_unref_fonts; + Boolean xft_track_mem_usage; Boolean force_xft_height; ListXftFonts *list_xft_fonts; XTermXftFonts renderFontNorm[NMENUFONTS]; XTermXftFonts renderFontBold[NMENUFONTS]; +#if OPT_WIDE_ATTRS || OPT_RENDERWIDE XTermXftFonts renderFontItal[NMENUFONTS]; XTermXftFonts renderFontBtal[NMENUFONTS]; +#endif #if OPT_RENDERWIDE XTermXftFonts renderWideNorm[NMENUFONTS]; XTermXftFonts renderWideBold[NMENUFONTS]; @@ -3238,6 +3272,7 @@ typedef struct _Work { Boolean force_wideFont; /* true to single-step wideFont */ #if OPT_RENDERFONT Boolean render_font; + FcPattern *xft_defaults; unsigned max_fontsets; #endif #if OPT_DABBREV @@ -3278,7 +3313,7 @@ extern WidgetClass tekWidgetClass; #define MODE_DECCKM xBIT(2) /* private mode 1: cursor keys */ #define MODE_SRM xBIT(3) /* mode 12: send-receive mode */ #define MODE_DECBKM xBIT(4) /* private mode 67: backarrow */ -#define MODE_DECSDM xBIT(5) /* private mode 80: sixel scrolling mode */ +#define MODE_DECSDM xBIT(5) /* private mode 80: sixel DISPLAY mode -- note, when SDM is off, the terminal is in sixel SCROLLING mode */ #define N_MARGINBELL 10 @@ -3456,7 +3491,8 @@ typedef struct _TekWidgetRec { #endif /* - * Sixel-scrolling is backwards, perhaps from an error in the hardware design. + * Sixel scrolling is on when Sixel Display Mode is off, and vice versa. + * (Note: DEC erroneously conflates the two in the VT330/340 manual). */ #define SixelScrolling(xw) (!((xw)->keyboard.flags & MODE_DECSDM)) diff --git a/app/xterm/screen.c b/app/xterm/screen.c index 93e36b3b8..b95a882aa 100644 --- a/app/xterm/screen.c +++ b/app/xterm/screen.c @@ -1,4 +1,4 @@ -/* $XTermId: screen.c,v 1.623 2022/03/09 01:20:09 tom Exp $ */ +/* $XTermId: screen.c,v 1.626 2022/09/19 23:08:41 tom Exp $ */ /* * Copyright 1999-2021,2022 by Thomas E. Dickey @@ -632,7 +632,7 @@ ChangeToWide(XtermWidget xw) * data in the alternate buffer. */ if (screen->whichBuf) - SwitchBufPtrs(screen, 0); + SwitchBufPtrs(xw, 0); ReallocateFifoIndex(xw); @@ -659,7 +659,7 @@ ChangeToWide(XtermWidget xw) * Switch the pointers back before we start painting on the screen. */ if (whichBuf) - SwitchBufPtrs(screen, whichBuf); + SwitchBufPtrs(xw, whichBuf); update_font_utf8_mode(); SetVTFont(xw, screen->menu_font_number, True, NULL); @@ -1985,27 +1985,35 @@ ScreenResize(XtermWidget xw, cols = 1; #if OPT_STATUS_LINE + /* + * The dimensions passed to this function include the status-line. + * Discount that here (to obtain the actual rows/columns), and save + * the contents of the status-line, to repaint it after resizing. + */ TRACE(("...StatusShown %d/%d\n", IsStatusShown(screen), screen->status_shown)); if (IsStatusShown(screen)) { int oldRow = MaxRows(screen); + int newRow = rows - StatusLineRows; + LineData *oldLD; TRACE(("...status line is currently on row %d(%d-%d) vs %d\n", oldRow, MaxRows(screen), (screen->status_shown ? 0 : StatusLineRows), rows)); - if (1 || rows != oldRow) { - LineData *oldLD = getLineData(screen, oldRow); - TRACE(("...will move status-line from row %d to %d\n", - oldRow, - rows)); - savedStatus = allocLineData(screen, oldLD); - copyLineData(savedStatus, oldLD); - TRACE(("...copied::%s\n", - visibleIChars(savedStatus->charData, - savedStatus->lineSize))); - } + oldLD = getLineData(screen, oldRow); + TRACE(("...copying:%s\n", + visibleIChars(oldLD->charData, + oldLD->lineSize))); + TRACE(("...will move status-line from row %d to %d\n", + oldRow, + newRow)); + savedStatus = allocLineData(screen, oldLD); + copyLineData(savedStatus, oldLD); + TRACE(("...copied::%s\n", + visibleIChars(savedStatus->charData, + savedStatus->lineSize))); TRACE(("...discount a row for status-line\n")); - rows -= StatusLineRows; + rows = newRow; height -= FontHeight(screen) * StatusLineRows; } #endif @@ -2240,6 +2248,9 @@ ScreenResize(XtermWidget xw, TRACE(("...status line is currently on row %d\n", LastRowNumber(screen))); copyLineData(newLD, savedStatus); + TRACE(("...copied::%s\n", + visibleIChars(newLD->charData, + newLD->lineSize))); freeLineData(screen, savedStatus); } #endif diff --git a/app/xterm/terminfo b/app/xterm/terminfo index 3b874ce76..2cfff3ffc 100644 --- a/app/xterm/terminfo +++ b/app/xterm/terminfo @@ -1,4 +1,4 @@ -# $XTermId: terminfo,v 1.203 2022/02/01 00:35:15 tom Exp $ +# $XTermId: terminfo,v 1.204 2022/06/20 23:37:59 tom Exp $ # # Updates/notes/new entries (e.g., xterm-8bit, xterm-16color, xterm-256color) # - Thomas E. Dickey @@ -2772,7 +2772,7 @@ xterm-r5|xterm R5 version, dec+sl|DEC VTxx status line, eslok, hs, - dsl=\E[1$~, + dsl=\E[0$~, fsl=\E[0$}, tsl=\E[2$~\E[1$}\E[%i%p1%d`, # diff --git a/app/xterm/trace.c b/app/xterm/trace.c index bdbde61a2..aaabed314 100644 --- a/app/xterm/trace.c +++ b/app/xterm/trace.c @@ -1,4 +1,4 @@ -/* $XTermId: trace.c,v 1.236 2022/02/18 08:48:47 tom Exp $ */ +/* $XTermId: trace.c,v 1.239 2022/10/06 20:43:02 tom Exp $ */ /* * Copyright 1997-2021,2022 by Thomas E. Dickey @@ -309,17 +309,17 @@ visibleScsCode(DECNRCM_codes chrset) } const char * -visibleChars(const Char *buf, unsigned len) +visibleChars(const Char *buf, size_t len) { static char *result; - static unsigned used; + static size_t used; if (buf != 0) { - unsigned limit = ((len + 1) * 8) + 1; + size_t limit = ((len + 1) * 8) + 1; if (limit > used) { used = limit; - result = XtRealloc(result, used); + result = realloc(result, used); } if (result != 0) { char *dst = result; @@ -359,17 +359,17 @@ visibleEventMode(EventMode value) } const char * -visibleIChars(const IChar *buf, unsigned len) +visibleIChars(const IChar *buf, size_t len) { static char *result; - static unsigned used; + static size_t used; if (buf != 0) { - unsigned limit = ((len + 1) * 12) + 1; + size_t limit = ((len + 1) * 12) + 1; if (limit > used) { used = limit; - result = XtRealloc(result, used); + result = realloc(result, used); } if (result != 0) { char *dst = result; @@ -484,6 +484,7 @@ visibleNotifyDetail(int code) return result; } +#if OPT_TEK4014 const char * visibleSelectionTarget(Display *d, Atom a) { @@ -545,6 +546,7 @@ visibleVTparse(int code) } return result; } +#endif const char * visibleXError(int code) @@ -904,9 +906,9 @@ TraceEvent(const char *tag, XEvent *ev, String *params, Cardinal *num_params) for (j = 0; j < XtNumber(ev->xkeymap.key_vector); ++j) { if (ev->xkeymap.key_vector[j] != 0) { Cardinal k; - for (k = 0; k < 8; ++k) { + for (k = 0; k < CHAR_BIT; ++k) { if (ev->xkeymap.key_vector[j] & (1 << k)) { - TRACE((" key%u", (j * 8) + k)); + TRACE((" key%u", (j * CHAR_BIT) + k)); } } } diff --git a/app/xterm/trace.h b/app/xterm/trace.h index 224bd6c16..fa9d90abe 100644 --- a/app/xterm/trace.h +++ b/app/xterm/trace.h @@ -1,4 +1,4 @@ -/* $XTermId: trace.h,v 1.93 2022/02/21 22:54:05 tom Exp $ */ +/* $XTermId: trace.h,v 1.94 2022/10/06 20:40:49 tom Exp $ */ /* * Copyright 1997-2021,2022 by Thomas E. Dickey @@ -69,9 +69,9 @@ extern void TraceClose (void); #define TRACE_L "{{" #define TRACE_R "}}" -extern const char * visibleChars(const Char * /* buf */, unsigned /* len */); +extern const char * visibleChars(const Char * /* buf */, size_t /* len */); extern const char * visibleEventMode(EventMode); -extern const char * visibleIChars(const IChar * /* buf */, unsigned /* len */); +extern const char * visibleIChars(const IChar * /* buf */, size_t /* len */); extern const char * visibleUChar(unsigned); extern const char * visibleDblChrset(unsigned /* chrset */); extern const char * visibleEventType (int); diff --git a/app/xterm/util.c b/app/xterm/util.c index eca80336f..9d96fee34 100644 --- a/app/xterm/util.c +++ b/app/xterm/util.c @@ -1,4 +1,4 @@ -/* $XTermId: util.c,v 1.898 2022/03/08 00:48:22 tom Exp $ */ +/* $XTermId: util.c,v 1.913 2022/09/25 17:46:22 tom Exp $ */ /* * Copyright 1999-2021,2022 by Thomas E. Dickey @@ -2953,7 +2953,7 @@ getXftColor(XtermWidget xw, Pixel pixel) if (!found) { i = oldest; color.pixel = pixel; - XQueryColor(TScreenOf(xw)->display, xw->core.colormap, &color); + (void) QueryOneColor(xw, &color); cache[i].color.color.red = color.red; cache[i].color.color.green = color.green; cache[i].color.color.blue = color.blue; @@ -2991,7 +2991,7 @@ getXftColor(XtermWidget xw, Pixel pixel) #endif /* OPT_RENDERWIDE */ -#define XFT_FONT(which) getXftFont(params->xw, which, fontnum) +#define XFT_DATA(which) getMyXftFont(params->xw, which, fontnum) #if OPT_ISO_COLORS #define UseBoldFont(screen) (!(screen)->colorBDMode || ((screen)->veryBoldColors & BOLD)) @@ -3003,13 +3003,13 @@ getXftColor(XtermWidget xw, Pixel pixel) /* * Find Xft (truetype) double-width font for the given normal/bold attributes. */ -static XftFont * +static XTermXftFonts * getWideXftFont(XTermDraw * params, unsigned attr_flags) { TScreen *screen = TScreenOf(params->xw); int fontnum = screen->menu_font_number; - XftFont *wfont = 0; + XTermXftFonts *result = 0; #if OPT_WIDE_ATTRS if ((attr_flags & ATR_ITALIC) @@ -3019,13 +3019,13 @@ getWideXftFont(XTermDraw * params, ) { if ((attr_flags & BOLDATTR(screen)) && UseBoldFont(screen) - && XFT_FONT(fWBtal)) { - wfont = XFT_FONT(fWBtal); - } else if (XFT_FONT(fWItal)) { - wfont = XFT_FONT(fWItal); + && XFT_DATA(fWBtal)) { + result = XFT_DATA(fWBtal); + } else if (XFT_DATA(fWItal)) { + result = XFT_DATA(fWItal); } } - if (wfont != 0) { + if (result != 0) { ; /* skip the other tests */ } else #endif @@ -3033,39 +3033,39 @@ getWideXftFont(XTermDraw * params, if ((attr_flags & UNDERLINE) && !screen->colorULMode && screen->italicULMode - && XFT_FONT(fWItal)) { - wfont = XFT_FONT(fWItal); + && XFT_DATA(fWItal)) { + result = XFT_DATA(fWItal); } else #endif if ((attr_flags & BOLDATTR(screen)) && UseBoldFont(screen) - && XFT_FONT(fWBold)) { - wfont = XFT_FONT(fWBold); + && XFT_DATA(fWBold)) { + result = XFT_DATA(fWBold); } else { - wfont = XFT_FONT(fWide); + result = XFT_DATA(fWide); } - return wfont; + return result; } #endif /* OPT_RENDERWIDE */ /* * Find Xft (truetype) single-width font for the given normal/bold attributes. */ -static XftFont * +static XTermXftFonts * getNormXftFont(XTermDraw * params, unsigned attr_flags, Bool *did_ul) { TScreen *screen = TScreenOf(params->xw); int fontnum = screen->menu_font_number; - XftFont *font = 0; + XTermXftFonts *result = NULL; (void) did_ul; #if OPT_DEC_CHRSET if (CSET_DOUBLE(params->real_chrset)) { - font = xterm_DoubleFT(params, params->real_chrset, attr_flags); + result = xterm_DoubleFT(params, params->real_chrset, attr_flags); } - if (font != 0) { + if (result != 0) { ; /* found a usable double-sized font */ } else #endif @@ -3077,13 +3077,13 @@ getNormXftFont(XTermDraw * params, ) { if ((attr_flags & BOLDATTR(screen)) && UseBoldFont(screen) - && XFT_FONT(fBtal)) { - font = XFT_FONT(fBtal); - } else if (XFT_FONT(fItal)) { - font = XFT_FONT(fItal); + && XFT_DATA(fBtal)) { + result = XFT_DATA(fBtal); + } else if (XFT_DATA(fItal)) { + result = XFT_DATA(fItal); } } - if (font != 0) { + if (result != NULL) { ; /* skip the other tests */ } else #endif @@ -3091,24 +3091,26 @@ getNormXftFont(XTermDraw * params, if ((attr_flags & UNDERLINE) && !screen->colorULMode && screen->italicULMode - && XFT_FONT(fItal)) { - font = XFT_FONT(fItal); + && XFT_DATA(fItal)) { + result = XFT_DATA(fItal); *did_ul = True; } else #endif if ((attr_flags & BOLDATTR(screen)) && UseBoldFont(screen) - && XFT_FONT(fBold)) { - font = XFT_FONT(fBold); + && XFT_DATA(fBold)) { + result = XFT_DATA(fBold); } else { - font = XFT_FONT(fNorm); + result = XFT_DATA(fNorm); } - return font; + return result; } #if OPT_RENDERWIDE -#define pickXftFont(width, nf, wf) ((width == 2 && wf != 0) ? wf : nf) +#define pickXftData(width, nf, wf) (((width == 2) && ((wf) != NULL) && XftFp(wf) != NULL) ? (wf) : (nf)) +#define pickXftFont(width, nf, wf) (((width == 2) && ((wf) != NULL)) ? (wf) : (nf)) #else +#define pickXftData(width, nf, wf) (nf) #define pickXftFont(width, nf, wf) (nf) #endif @@ -3140,7 +3142,8 @@ xtermXftDrawString(XTermDraw * params, if (len != 0) { #if OPT_RENDERWIDE XftCharSpec *sbuf; - XftFont *wfont = getWideXftFont(params, attr_flags); + XTermXftFonts *wdata = getWideXftFont(params, attr_flags); + XftFont *wfont = XftFp(wdata); Cardinal src, dst; XftFont *lastFont = 0; XftFont *currFont = 0; @@ -3906,12 +3909,14 @@ drawXtermText(XTermDraw * params, if (UsingRenderFont(recur.xw)) { VTwin *currentWin = WhichVWin(screen); Display *dpy = screen->display; - XftFont *font; - XftFont *font0; + XTermXftFonts *ndata; XGCValues values; +#if OPT_WIDE_CHARS + XTermXftFonts *ndata0; +#endif #if OPT_RENDERWIDE - XftFont *wfont; - XftFont *wfont0; + XTermXftFonts *wdata; + XTermXftFonts *wdata0; #endif #if OPT_DEC_CHRSET @@ -3940,19 +3945,18 @@ drawXtermText(XTermDraw * params, } /* - * font0/wfont0 provide fallback to non-bolded Xft font if a glyph is + * ndata0/wdata0 provide fallback to non-bolded Xft font if a glyph is * not found in the bold version. */ #define IS_BOLD (recur.attr_flags & BOLDATTR(screen)) #define NOT_BOLD (recur.attr_flags & ~BOLDATTR(screen)) - font = getNormXftFont(&recur, recur.attr_flags, &did_ul); - font0 = IS_BOLD ? getNormXftFont(&recur, NOT_BOLD, &did_ul) : font; - (void) font0; + ndata = getNormXftFont(&recur, recur.attr_flags, &did_ul); +#if OPT_WIDE_CHARS + ndata0 = IS_BOLD ? getNormXftFont(&recur, NOT_BOLD, &did_ul) : ndata; +#endif #if OPT_RENDERWIDE - wfont = getWideXftFont(&recur, recur.attr_flags); - wfont0 = IS_BOLD ? getWideXftFont(&recur, NOT_BOLD) : wfont; - - (void) wfont0; + wdata = getWideXftFont(&recur, recur.attr_flags); + wdata0 = IS_BOLD ? getWideXftFont(&recur, NOT_BOLD) : wdata; #endif #define GET_XFT_FG() getXftColor(recur.xw, values.foreground) @@ -3965,7 +3969,7 @@ drawXtermText(XTermDraw * params, XftColor *bg_color = GET_XFT_BG(); int ncells = xtermXftWidth(&recur, recur.attr_flags, bg_color, - font, x, y, + XftFp(ndata), x, y, text, len); XftDrawRect(screen->renderDraw, @@ -3975,7 +3979,7 @@ drawXtermText(XTermDraw * params, (unsigned) FontHeight(screen)); } - y += font->ascent; + y += XftFp(ndata)->ascent; #if OPT_BOX_CHARS { /* adding code to substitute simulated line-drawing characters */ @@ -3989,9 +3993,9 @@ drawXtermText(XTermDraw * params, int filler = 0; #if OPT_WIDE_CHARS int needed = forceDbl ? 2 : CharWidth(screen, ch); - XftFont *currFont = pickXftFont(needed, font, wfont); + XTermXftFonts *currData = pickXftData(needed, ndata, wdata); XftFont *tempFont = 0; -#define CURR_TEMP (tempFont ? tempFont : currFont) +#define CURR_TEMP (tempFont ? tempFont : XftFp(currData)) if (xtermIsDecGraphic(ch) || ch == 0) { /* @@ -4004,7 +4008,8 @@ drawXtermText(XTermDraw * params, if (screen->force_box_chars || screen->broken_box_chars || xtermXftMissing(recur.xw, - currFont, + currData, 0, + XftFp(currData), dec2ucs(screen, ch))) { SetMissing("case 1"); } else { @@ -4026,11 +4031,21 @@ drawXtermText(XTermDraw * params, ch = part; } } - if (!missing && xtermXftMissing(recur.xw, currFont, ch)) { - XftFont *test = findXftGlyph(recur.xw, currFont, ch); - if (test == 0) - test = pickXftFont(needed, font0, wfont0); - if (!xtermXftMissing(recur.xw, test, ch)) { + if (!missing && xtermXftMissing(recur.xw, + currData, 0, + XftFp(currData), ch)) { + int found = findXftGlyph(recur.xw, currData, ch); + XftFont *test; + if (found >= 0) { + test = XftFpN(currData, found); + } else { + test = pickXftFont(needed, + XftFp(ndata0), + XftFp(wdata0)); + } + if (!xtermXftMissing(recur.xw, + currData, found, + test, ch)) { tempFont = test; replace = True; filler = 0; @@ -4045,8 +4060,8 @@ drawXtermText(XTermDraw * params, }); } #else - XftFont *currFont = font; -#define CURR_TEMP (currFont) + XTermXftFonts *currData = ndata; +#define CURR_TEMP XftFp(currData) if (xtermIsDecGraphic(ch)) { /* * Xft generally does not have the line-drawing characters @@ -4055,7 +4070,9 @@ drawXtermText(XTermDraw * params, * Unicode position. Failing that, use our own * box-characters. */ - if (xtermXftMissing(recur.xw, currFont, ch)) { + if (xtermXftMissing(recur.xw, + currData, 0, + XftFp(currData), ch)) { SetMissing("case 4"); } } @@ -4069,7 +4086,7 @@ drawXtermText(XTermDraw * params, if (last > first) { int nc = drawClippedXftString(&recur, recur.attr_flags, - currFont, + XftFp(currData), GET_XFT_FG(), curX, y, @@ -4127,7 +4144,7 @@ drawXtermText(XTermDraw * params, underline_len += (Cardinal) drawClippedXftString(&recur, recur.attr_flags, - font, + XftFp(ndata), GET_XFT_FG(), curX, y, @@ -4140,7 +4157,7 @@ drawXtermText(XTermDraw * params, underline_len += (Cardinal) drawClippedXftString(&recur, recur.attr_flags, - font, + XftFp(ndata), GET_XFT_FG(), x, y, @@ -5006,15 +5023,18 @@ ClearCurBackground(XtermWidget xw, unsigned fw) { TScreen *screen = TScreenOf(xw); - - TRACE(("ClearCurBackground %d,%d %dx%d with %d\n", - top, left, height, width, xw->cur_background)); - - assert((int) width > 0); - assert((left + (int) width) <= screen->max_col + 1); - assert((int) (height + top) <= screen->max_row + 1); - - if (VWindow(screen)) { + int actual_rows = PlusStatusLine(screen, screen->max_row + 1); + Boolean visible = (((int) width > 0) + && ((left + (int) width) <= screen->max_col + 1) + && (((int) height + top) <= actual_rows)); + + TRACE(("ClearCurBackground %d,%d %dx%d%s with %d %s\n", + top, left, height, width, + IsStatusShown(screen) ? "*" : "", + xw->cur_background, + visible ? "(ok)" : "(err)")); + + if (VWindow(screen) && visible) { set_background(xw, xw->cur_background); xtermClear2(xw, @@ -5048,6 +5068,44 @@ getXtermBackground(XtermWidget xw, unsigned attr_flags, int color) return result; } +#if OPT_ISO_COLORS && OPT_WIDE_ATTRS +#if OPT_SGR2_HASH +typedef struct _DimColorHT { + Pixel org; + Pixel dim; +} DimColorHT; + +static unsigned +jhash1(unsigned char *key, size_t len) +{ + unsigned hash; + size_t i; + + for (hash = 0, i = 0; i < len; ++i) { + hash += key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return hash; +} + +static unsigned +computeFaint(XtermWidget xw, unsigned value, unsigned compare) +{ + TScreen *screen = TScreenOf(xw); + if (screen->faint_relative) { + value = (unsigned) ((value + compare) / 2); + } else { + value = (unsigned) ((2 * value) / 3); + } + return value; +} +#endif /* OPT_SGR2_HASH */ +#endif /* OPT_ISO_COLORS && OPT_WIDE_ATTRS */ + Pixel getXtermForeground(XtermWidget xw, unsigned attr_flags, int color) { @@ -5066,19 +5124,67 @@ getXtermForeground(XtermWidget xw, unsigned attr_flags, int color) (void) color; #endif -#if OPT_WIDE_ATTRS -#define DIM_IT(n) work.n = (unsigned short) ((2 * (unsigned)work.n) / 3) +#if OPT_ISO_COLORS && OPT_WIDE_ATTRS if ((attr_flags & ATR_FAINT)) { +#if OPT_SGR2_HASH +#define DIM_IT(n) work.n = (unsigned short) computeFaint(xw, work.n, bkg.n) +#define SizeOfHT ((unsigned) sizeof(unsigned long) * CHAR_BIT) + static DimColorHT ht[SizeOfHT]; + Pixel bg = T_COLOR(TScreenOf(xw), TEXT_BG); + XColor work; + Pixel p; + + if ((color >= 0) + || (result != (Pixel) color)) { + static unsigned long have = 0; + static Boolean have_bg = False; + static XColor bkg; + + /* cache bkg color in r/g/b */ + if (!have_bg || bg != bkg.pixel) { + bkg.pixel = bg; + have_bg = QueryOneColor(xw, &bkg); + have = 0; /* invalidate color cache */ + } + if (have_bg) { + unsigned hv; + hv = jhash1((unsigned char *) &result, sizeof(result)); + hv %= SizeOfHT; + + if ((have & (1UL << hv)) + && ht[hv].org == result) { + result = ht[hv].dim; /* return cached color */ + } else { + work.pixel = result; + if (QueryOneColor(xw, &work)) { + DIM_IT(red); + DIM_IT(green); + DIM_IT(blue); + p = result; + if (allocateBestRGB(xw, &work)) { + result = work.pixel; + } + + /* cache the result */ + have |= (1UL << hv); + ht[hv].org = p; + ht[hv].dim = result; + } + } + } + } +#else /* !OPT_SGR2_HASH */ +#define DIM_IT(n) work.n = (unsigned short) ((2 * (unsigned)work.n) / 3) static Pixel last_in; static Pixel last_out; if ((result != last_in) && ((color >= 0) || (result != (Pixel) color))) { XColor work; + last_in = result; work.pixel = result; - last_in = result; - if (XQueryColor(TScreenOf(xw)->display, xw->core.colormap, &work)) { - DIM_IT(red); + if (QueryOneColor(xw, &work)) { + DIM_IT(red); DIM_IT(green); DIM_IT(blue); if (allocateBestRGB(xw, &work)) { @@ -5089,6 +5195,7 @@ getXtermForeground(XtermWidget xw, unsigned attr_flags, int color) } else { result = last_out; } +#endif /* OPT_SGR2_HASH */ } #endif return result; @@ -5606,11 +5713,7 @@ VDrawable(TScreen *screen) void discardRenderDraw(TScreen *screen) { - if ( -#if USE_DOUBLE_BUFFER - resource.buffered && -#endif - screen->renderDraw) { + if (screen->renderDraw) { XftDrawDestroy(screen->renderDraw); screen->renderDraw = NULL; } diff --git a/app/xterm/uxterm.desktop b/app/xterm/uxterm.desktop index 7923e9b3f..c0f81ffa5 100644 --- a/app/xterm/uxterm.desktop +++ b/app/xterm/uxterm.desktop @@ -1,8 +1,8 @@ -# $XTermId: uxterm.desktop,v 1.15 2019/02/06 01:36:47 tom Exp $ +# $XTermId: uxterm.desktop,v 1.16 2022/09/06 21:09:42 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2006-2016,2019 by Thomas E. Dickey +# Copyright 2006-2019,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -41,3 +41,4 @@ Encoding=UTF-8 Icon=xterm-color_48x48 Categories=System;TerminalEmulator; Keywords=shell;prompt;command;commandline;cmd; +StartupWMClass=UXTerm diff --git a/app/xterm/version.h b/app/xterm/version.h index 8a8726efc..8d2a332c3 100644 --- a/app/xterm/version.h +++ b/app/xterm/version.h @@ -1,4 +1,4 @@ -/* $XTermId: version.h,v 1.522 2022/03/10 00:58:00 tom Exp $ */ +/* $XTermId: version.h,v 1.527 2022/10/10 16:31:27 tom Exp $ */ /* * Copyright 1998-2021,2022 by Thomas E. Dickey @@ -38,8 +38,8 @@ * version of X to which this version of xterm has been built. The resulting * number in parentheses is my patch number (Thomas E. Dickey). */ -#define XTERM_PATCH 372 -#define XTERM_DATE 2022-03-09 +#define XTERM_PATCH 374 +#define XTERM_DATE 2022-10-10 #ifndef __vendorversion__ #define __vendorversion__ "XTerm/OpenBSD" diff --git a/app/xterm/vms.c b/app/xterm/vms.c index e318c5c91..138b7f218 100644 --- a/app/xterm/vms.c +++ b/app/xterm/vms.c @@ -1,4 +1,4 @@ -/* $XTermId: vms.c,v 1.14 2020/01/18 18:32:45 tom Exp $ */ +/* $XTermId: vms.c,v 1.15 2022/10/06 19:35:35 tom Exp $ */ /* vms.c * @@ -390,7 +390,7 @@ static void tt_echo_ast(TT_BUF_STRUCT *buff_addr) */ -int tt_write(const char *tt_write_buf, int size) +int tt_write(const char *tt_write_buf, size_t size) { int status; TT_BUF_STRUCT *echoBuff; diff --git a/app/xterm/vms.h b/app/xterm/vms.h index 8eb206433..c62889120 100644 --- a/app/xterm/vms.h +++ b/app/xterm/vms.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/xterm/vms.h,v 1.1 2000/02/08 17:19:45 dawes Exp $ */ +/* $XTermId: vms.h,v 1.6 2022/10/06 19:37:30 tom Exp $ */ /* vms.h */ @@ -38,4 +38,4 @@ static struct items { int return_addr; } itemlist[MAXITEMLIST]; -int tt_write(const char *tt_write_buf,int size); +int tt_write(const char *tt_write_buf, size_t size); diff --git a/app/xterm/vttests/16colors.sh b/app/xterm/vttests/16colors.sh index 6654f9c86..6e2fd7be4 100644 --- a/app/xterm/vttests/16colors.sh +++ b/app/xterm/vttests/16colors.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: 16colors.sh,v 1.20 2022/02/13 14:33:35 tom Exp $ +# $XTermId: 16colors.sh,v 1.22 2022/04/24 23:36:20 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -41,14 +41,15 @@ CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -56,7 +57,7 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" trap '$CMD "${CSI}0m"; exit 1' 1 2 3 15 trap '$CMD "${CSI}0m"' 0 diff --git a/app/xterm/vttests/256colors2.pl b/app/xterm/vttests/256colors2.pl index 2d63277a9..08f352845 100644 --- a/app/xterm/vttests/256colors2.pl +++ b/app/xterm/vttests/256colors2.pl @@ -1,9 +1,9 @@ #!/usr/bin/env perl -# $XTermId: 256colors2.pl,v 1.25 2020/06/07 22:52:05 tom Exp $ +# $XTermId: 256colors2.pl,v 1.26 2022/10/10 17:22:07 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 1999-2018,2020 by Thomas E. Dickey +# Copyright 1999-2020,2022 by Thomas E. Dickey # Copyright 2002 by Steve Wall # Copyright 1999 by Todd Larason # @@ -140,9 +140,16 @@ if ($opt_C) { } if ( $opt_8 and $opt_u ) { - my $lc_ctype = `locale 2>/dev/null | fgrep LC_CTYPE | sed -e 's/^.*=//'`; - if ( $lc_ctype =~ /utf.?8/i ) { - binmode( STDOUT, ":utf8" ); + if ( open( FP, "locale 2>/dev/null |" ) ) { + my (@locale) = <FP>; + chomp @locale; + close(FP); + for my $n ( 0 .. $#locale ) { + if ( $locale[$n] =~ /^LC_CTYPE=/ ) { + binmode( STDOUT, ":utf8" ) if ( $locale[$n] =~ /utf.?8/i ); + last; + } + } } } diff --git a/app/xterm/vttests/88colors2.pl b/app/xterm/vttests/88colors2.pl index b0ca162e9..cb8476405 100644 --- a/app/xterm/vttests/88colors2.pl +++ b/app/xterm/vttests/88colors2.pl @@ -1,9 +1,9 @@ #!/usr/bin/env perl -# $XTermId: 88colors2.pl,v 1.19 2020/06/07 22:48:11 tom Exp $ +# $XTermId: 88colors2.pl,v 1.22 2022/10/11 00:05:34 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 1999-2018,2020 by Thomas E. Dickey +# Copyright 1999-2021,2022 by Thomas E. Dickey # Copyright 1999 by Steve Wall # # All Rights Reserved @@ -141,9 +141,16 @@ if ($opt_C) { } if ( $opt_8 and $opt_u ) { - my $lc_ctype = `locale 2>/dev/null | fgrep LC_CTYPE | sed -e 's/^.*=//'`; - if ( $lc_ctype =~ /utf.?8/i ) { - binmode( STDOUT, ":utf8" ); + if ( open( FP, "locale 2>/dev/null |" ) ) { + my (@locale) = <FP>; + chomp @locale; + close(FP); + for my $n ( 0 .. $#locale ) { + if ( $locale[$n] =~ /^LC_CTYPE=/ ) { + binmode( STDOUT, ":utf8" ) if ( $locale[$n] =~ /utf.?8/i ); + last; + } + } } } diff --git a/app/xterm/vttests/8colors.sh b/app/xterm/vttests/8colors.sh index af8b7d0e2..362a7d9f3 100644 --- a/app/xterm/vttests/8colors.sh +++ b/app/xterm/vttests/8colors.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: 8colors.sh,v 1.21 2022/02/13 14:42:02 tom Exp $ +# $XTermId: 8colors.sh,v 1.23 2022/04/24 23:36:20 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -38,14 +38,15 @@ CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -53,7 +54,7 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" trap '$CMD $OPT "${CSI}0m"; exit 1' 1 2 3 15 trap '$CMD $OPT "${CSI}0m"' 0 diff --git a/app/xterm/vttests/acolors.sh b/app/xterm/vttests/acolors.sh index bcda9a3ac..ae4c685e1 100644 --- a/app/xterm/vttests/acolors.sh +++ b/app/xterm/vttests/acolors.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: acolors.sh,v 1.13 2022/02/13 14:34:17 tom Exp $ +# $XTermId: acolors.sh,v 1.16 2022/04/25 08:19:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -38,14 +38,15 @@ CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -53,7 +54,7 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" LIST="00 30 80 d0 ff" @@ -62,7 +63,7 @@ old=`stty -g` stty raw -echo min 0 time 5 $CMD $OPT "${ESC}]4;4;?${SUF}" > /dev/tty -read original +read -r original stty $old original=${original}${SUF} diff --git a/app/xterm/vttests/ctlpix.sh b/app/xterm/vttests/ctlpix.sh index 1bfa37f55..00ae62895 100644 --- a/app/xterm/vttests/ctlpix.sh +++ b/app/xterm/vttests/ctlpix.sh @@ -1,9 +1,9 @@ #!/bin/sh -# $XTermId: ctlpix.sh,v 1.2 2019/05/02 22:02:06 tom Exp $ +# $XTermId: ctlpix.sh,v 1.6 2022/04/25 08:03:21 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2019 by Thomas E. Dickey +# Copyright 2019,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -31,11 +31,13 @@ # sale, use or other dealings in this Software without prior written # authorization. # ----------------------------------------------------------------------------- +PATH="$(dirname "$(readlink -f "$0")"):$PATH" +export PATH clear lo=9216 hi=9232 for n in `seq $lo $hi` do - vxt-utf8 $n + utf8.pl "$n" done -vxt-altchars +altchars.sh diff --git a/app/xterm/vttests/dl.sh b/app/xterm/vttests/dl.sh index 5181b673f..51684befd 100644 --- a/app/xterm/vttests/dl.sh +++ b/app/xterm/vttests/dl.sh @@ -1,9 +1,9 @@ #!/bin/bash -# $XTermId: dl.sh,v 1.2 2019/11/18 10:13:03 tom Exp $ +# $XTermId: dl.sh,v 1.4 2022/04/25 08:25:37 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2019 by Thomas E. Dickey +# Copyright 2019,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -53,7 +53,7 @@ reset_margins() { finish_test() { printf '\033[10;1H' - read -p "$*" + read -r -p "$*" } start_test diff --git a/app/xterm/vttests/doublechars.sh b/app/xterm/vttests/doublechars.sh index 74aa9efe9..c69cdaa27 100644 --- a/app/xterm/vttests/doublechars.sh +++ b/app/xterm/vttests/doublechars.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: doublechars.sh,v 1.22 2022/02/13 14:34:47 tom Exp $ +# $XTermId: doublechars.sh,v 1.26 2022/04/25 23:25:41 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -42,14 +42,15 @@ CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -57,16 +58,21 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" +ITAL=no SAVE=yes WRAP=no if test $# != 0 ; then while test $# != 0 do case $1 in + -i) ITAL=yes ;; -n) SAVE=no ;; -w) WRAP=yes ;; + *) + echo "usage: $0 [-i] [-n] [-w]" + exit 1 esac shift done @@ -78,7 +84,7 @@ if test $SAVE = yes ; then stty raw -echo min 0 time 5 $CMD $OPT "${CSI}18t${SUF}" > /dev/tty - IFS=';' read junk high wide + IFS=';' read -r junk high wide stty $old @@ -103,6 +109,7 @@ fi for SGR in 0 1 4 5 7 do $CMD $OPT "${CSI}0;${SGR}m" >/dev/tty + test "$ITAL" = yes && $CMD $OPT "${CSI}3m" >/dev/tty for DBL in 5 3 4 6 5 do $CMD $OPT "${ESC}#${DBL}" >/dev/tty diff --git a/app/xterm/vttests/dynamic.sh b/app/xterm/vttests/dynamic.sh index a352852fd..6fc24c059 100644 --- a/app/xterm/vttests/dynamic.sh +++ b/app/xterm/vttests/dynamic.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: dynamic.sh,v 1.22 2022/02/13 14:35:09 tom Exp $ +# $XTermId: dynamic.sh,v 1.25 2022/04/25 08:19:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -39,14 +39,15 @@ OSC="${ESC}]" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -54,7 +55,7 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" LIST="00 30 80 d0 ff" @@ -63,7 +64,7 @@ old=`stty -g` stty raw -echo min 0 time 5 $CMD $OPT "${OSC}11;?${SUF}" > /dev/tty -read original +read -r original stty $old original=${original}${SUF} diff --git a/app/xterm/vttests/dynamic2.sh b/app/xterm/vttests/dynamic2.sh index 708373f35..69271d58b 100644 --- a/app/xterm/vttests/dynamic2.sh +++ b/app/xterm/vttests/dynamic2.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: dynamic2.sh,v 1.8 2022/02/13 14:35:30 tom Exp $ +# $XTermId: dynamic2.sh,v 1.11 2022/04/25 08:19:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -39,14 +39,15 @@ OSC="${ESC}]" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -54,7 +55,7 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" LIST="00 30 80 d0 ff" FULL="10 11 12 13 14 15 16 17 18" @@ -69,7 +70,7 @@ original= for N in $FULL do $CMD $OPT "${OSC}$N;?${SUF}" > /dev/tty - read reply + read -r reply eval original"$N"='${reply}${SUF}' original=${original}${reply}${SUF} done diff --git a/app/xterm/vttests/fonts.sh b/app/xterm/vttests/fonts.sh index cdbd2c78c..9bd6692e8 100644 --- a/app/xterm/vttests/fonts.sh +++ b/app/xterm/vttests/fonts.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: fonts.sh,v 1.17 2022/02/13 14:35:50 tom Exp $ +# $XTermId: fonts.sh,v 1.20 2022/04/25 08:19:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -38,14 +38,15 @@ CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -53,14 +54,14 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" exec </dev/tty old=`stty -g` stty raw -echo min 0 time 5 $CMD $OPT "${ESC}]50;?${SUF}" > /dev/tty -read original +read -r original stty $old original="${original}${SUF}" diff --git a/app/xterm/vttests/halves.pl b/app/xterm/vttests/halves.pl index f8fd99352..debc7ed46 100644 --- a/app/xterm/vttests/halves.pl +++ b/app/xterm/vttests/halves.pl @@ -1,9 +1,9 @@ #!/usr/bin/env perl -# $XTermId: halves.pl,v 1.6 2007/07/18 01:24:37 tom Exp $ +# $XTermId: halves.pl,v 1.10 2022/10/10 23:59:05 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2007 by Thomas E. Dickey +# Copyright 2007,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -35,133 +35,153 @@ # overstrike, insert- and delete-characters to see if the double-width # characters are completely cleared when "partly" modified. use strict; +use warnings; use Getopt::Std; -our ($opt_c, $opt_n, $opt_r, $opt_w); -our ($lineno, $test_string, $term_width); +our ( $opt_c, $opt_n, $opt_r, $opt_w ); +our ( $lineno, $test_string, $term_width ); # returns the number of columns in the screen sub screen_width() { - my $data = `resize -u |fgrep COLUMNS=`; - $data =~ s/COLUMNS=//; - $data =~ s/;//; - return $data + open( FP, "resize -u |" ) or exit $!; + my (@input) = <FP>; + chomp @input; + close(FP); + my $result = 80; + for my $n ( 0 .. $#input ) { + if ( $input[$n] =~ /^COLUMNS=/ ) { + $result = $input[$n]; + $result =~ s/^[^=]*=//; + last; + } + } + return $result; } sub set_color($) { - my $code = $_[0]; - if (defined($opt_c)) { - if ($code == 3) { - printf "\x1b[1;33;42m"; # yellow-on-green - } elsif ($code == 2) { - printf "\x1b[0;31;45m"; # red-on-magenta - } elsif ($code == 1) { - printf "\x1b[0;36;44m"; # cyan-on-blue - } else { - printf "\x1b[0;39;49m"; - } - } + my $code = $_[0]; + if ( defined($opt_c) ) { + if ( $code == 3 ) { + printf "\x1b[1;33;42m"; # yellow-on-green + } + elsif ( $code == 2 ) { + printf "\x1b[0;31;45m"; # red-on-magenta + } + elsif ( $code == 1 ) { + printf "\x1b[0;36;44m"; # cyan-on-blue + } + else { + printf "\x1b[0;39;49m"; + } + } } # returns a string of two-column characters given an ASCII alpha/numeric string sub double_cells($) { - my $value = $_[0]; - $value =~ s/ / /g; - pack("U*", - map { ($_ <= 32 || $_ > 127) # if non-ASCII character... - ? 32 # ...just show a blank - : (0xff00 + ($_ - 32)) # map to "Fullwidth Form" - } unpack("C*", $value)); # unpack unsigned-char characters + my $value = $_[0]; + $value =~ s/ / /g; + pack( + "U*", + map { + ( $_ <= 32 || $_ > 127 ) # if non-ASCII character... + ? 32 # ...just show a blank + : ( 0xff00 + ( $_ - 32 ) ) # map to "Fullwidth Form" + } unpack( "C*", $value ) + ); # unpack unsigned-char characters } sub move_to($) { - printf "\x1b[%dG", $_[0] + 1; + printf "\x1b[%dG", $_[0] + 1; } sub delete_char() { - set_color(2); - printf "\x1b[%dP", 1; - set_color(1); + set_color(2); + printf "\x1b[%dP", 1; + set_color(1); } sub insert_once($) { - set_color(2); - printf "\x1b[%d@%s", length($_[0]); - write_chars($_[0]); + set_color(2); + printf "\x1b[%d@", length( $_[0] ); + write_chars( $_[0] ); } sub insert_mode($) { - set_color(2); - printf "\x1b[%dP", length($_[0]); - printf "\x1b[4h"; - write_chars($_[0]); - printf "\x1b[4l"; + set_color(2); + printf "\x1b[%dP", length( $_[0] ); + printf "\x1b[4h"; + write_chars( $_[0] ); + printf "\x1b[4l"; } sub write_chars($) { - set_color(3); - printf "%s", $_[0]; - set_color(1); + set_color(3); + printf "%s", $_[0]; + set_color(1); } # vary the starting point of each line, to make a more interesting pattern sub starts_of($) { - my $value = $_[0]; - if (defined($opt_w)) { - # 0,1,1,2,2,3,3,... - $value = (($value + 1) / 2) % length($test_string); - } else { - $value %= length($test_string); - } - return $value; + my $value = $_[0]; + if ( defined($opt_w) ) { + + # 0,1,1,2,2,3,3,... + $value = ( ( $value + 1 ) / 2 ) % length($test_string); + } + else { + $value %= length($test_string); + } + return $value; } # write the text for the given line-number sub testit($) { - my $number = $_[0]; - my $length = $term_width; - if ( defined($opt_n) ) { - printf "%5d ", $number % 99999; - $length -= 6; - } - # if we're printing double-column characters, we have half as much - # space effectively - but don't forget the remainder, so we can push - # the characters by single-columns. - if (defined($opt_c)) { - set_color(1); - printf "\x1b[K"; - } - my $starts = starts_of($number); - if ( defined($opt_w) ) { - printf " ", if ( ($number % 2 ) != 0); - $length = ($length - (($number) % 2)) / 2; - } - my $string = substr($test_string, $starts); - while ( length($string) < $length ) { - $string = $string . $test_string; - } - $string = substr($string, 0, $length); - if ( defined($opt_w) ) { - $string = double_cells($string); - } - printf "%s", $string; - # now - within the line - modify it - move_to((4 * $term_width) / 5); - insert_mode("XX"); - move_to((3 * $term_width) / 5); - delete_char(); - move_to((2 * $term_width) / 5); - insert_once('~'); - move_to((1 * $term_width) / 5); - write_chars('~'); - move_to(0); - set_color(0); - printf "\n", $string; + my $number = $_[0]; + my $length = $term_width; + if ( defined($opt_n) ) { + printf "%5d ", $number % 99999; + $length -= 6; + } + + # if we're printing double-column characters, we have half as much + # space effectively - but don't forget the remainder, so we can push + # the characters by single-columns. + if ( defined($opt_c) ) { + set_color(1); + printf "\x1b[K"; + } + my $starts = starts_of($number); + if ( defined($opt_w) ) { + printf " ", if ( ( $number % 2 ) != 0 ); + $length = ( $length - ( ($number) % 2 ) ) / 2; + } + my $string = substr( $test_string, $starts ); + while ( length($string) < $length ) { + $string = $string . $test_string; + } + $string = substr( $string, 0, $length ); + if ( defined($opt_w) ) { + $string = double_cells($string); + } + printf "%s", $string; + + # now - within the line - modify it + move_to( ( 4 * $term_width ) / 5 ); + insert_mode("XX"); + move_to( ( 3 * $term_width ) / 5 ); + delete_char(); + move_to( ( 2 * $term_width ) / 5 ); + insert_once('~'); + move_to( ( 1 * $term_width ) / 5 ); + write_chars('~'); + move_to(0); + set_color(0); + printf "\n"; } sub main::HELP_MESSAGE() { - printf STDERR <<EOF + printf STDERR <<EOF Usage: $0 [options] Options: @@ -171,25 +191,27 @@ Options: -r repeat indefinitely -w write wide-characters EOF -; - exit; + ; + exit; } &getopts('cnrw') || die(); $term_width = screen_width(); -$test_string="0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +$test_string = + "0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -binmode(STDOUT, ":utf8"); +binmode( STDOUT, ":utf8" ); if ( defined($opt_r) ) { - for ($lineno = 0; ; ++$lineno) { - testit($lineno); - } -} else { - for ($lineno = 0; $lineno < 24; ++$lineno) { - testit($lineno); - } + for ( $lineno = 0 ; ; ++$lineno ) { + testit($lineno); + } +} +else { + for ( $lineno = 0 ; $lineno < 24 ; ++$lineno ) { + testit($lineno); + } } exit; diff --git a/app/xterm/vttests/il.sh b/app/xterm/vttests/il.sh index 06f2befeb..3e851c3bf 100644 --- a/app/xterm/vttests/il.sh +++ b/app/xterm/vttests/il.sh @@ -1,9 +1,9 @@ #!/bin/bash -# $XTermId: il.sh,v 1.2 2019/11/18 10:17:38 tom Exp $ +# $XTermId: il.sh,v 1.3 2022/04/25 08:26:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2019 by Thomas E. Dickey +# Copyright 2019,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -53,7 +53,7 @@ reset_margins() { finish_test() { printf '\033[10;1H' - read -p "$*" + read -r -p "$*" } start_test diff --git a/app/xterm/vttests/insdelln.pl b/app/xterm/vttests/insdelln.pl index 97b8c9735..9ce7e5175 100644 --- a/app/xterm/vttests/insdelln.pl +++ b/app/xterm/vttests/insdelln.pl @@ -1,9 +1,9 @@ #!/usr/bin/env perl -# $XTermId: insdelln.pl,v 1.6 2009/07/02 22:05:30 tom Exp $ +# $XTermId: vxt-insdelln,v 1.10 2022/10/10 17:05:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2009 by Thomas E. Dickey +# Copyright 2009,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -38,190 +38,223 @@ # add option to wrap the test-pattern # use scrolling-margins to help fill-in a chunk use strict; +use warnings; use Getopt::Std; -# do this so outout from successive calls to this script won't get in the +# do this so output from successive calls to this script won't get in the # wrong order: use IO::Handle; STDERR->autoflush(1); STDOUT->autoflush(1); -our ($opt_c, $opt_n, $opt_r, $opt_w); -our ($lineno, $test_string, $term_height, $term_width); +our ( $opt_c, $opt_n, $opt_r, $opt_w ); +our ( $lineno, $test_string, $term_height, $term_width ); + +our @resize; + +sub read_resize($) { + my $field = shift; + my $result = shift; + if ( $#resize < 0 ) { + open( FP, "resize -u |" ) or exit $!; + @resize = <FP>; + chomp @resize; + close(FP); + } + for my $n ( 0 .. $#resize ) { + if ( $resize[$n] =~ /^$field=/ ) { + $result = $resize[$n]; + $result =~ s/^[^=]*=//; + $result =~ s/;.*//; + last; + } + } + return $result; +} # returns the number of rows in the screen sub screen_height() { - my $data = `resize -u |fgrep LINES=`; - $data =~ s/LINES=//; - $data =~ s/;//; - return $data + return &read_resize( "LINES", 24 ); } # returns the number of columns in the screen sub screen_width() { - my $data = `resize -u |fgrep COLUMNS=`; - $data =~ s/COLUMNS=//; - $data =~ s/;//; - return $data + return &read_resize( "COLUMNS", 80 ); } sub set_color($) { - my $code = $_[0]; - if (defined($opt_c)) { - if ($code == 3) { - printf "\x1b[1;33;42m"; # yellow-on-green - } elsif ($code == 2) { - printf "\x1b[0;31;45m"; # red-on-magenta - } elsif ($code == 1) { - printf "\x1b[0;36;44m"; # cyan-on-blue - } else { - printf "\x1b[0;39;49m"; - } - } + my $code = $_[0]; + if ( defined($opt_c) ) { + if ( $code == 3 ) { + printf "\x1b[1;33;42m"; # yellow-on-green + } + elsif ( $code == 2 ) { + printf "\x1b[0;31;45m"; # red-on-magenta + } + elsif ( $code == 1 ) { + printf "\x1b[0;36;44m"; # cyan-on-blue + } + else { + printf "\x1b[0;39;49m"; + } + } } # returns a string of two-column characters given an ASCII alpha/numeric string sub double_cells($) { - my $value = $_[0]; - $value =~ s/ / /g; - pack("U*", - map { ($_ <= 32 || $_ > 127) # if non-ASCII character... - ? 32 # ...just show a blank - : (0xff00 + ($_ - 32)) # map to "Fullwidth Form" - } unpack("C*", $value)); # unpack unsigned-char characters + my $value = $_[0]; + $value =~ s/ / /g; + pack( + "U*", + map { + ( $_ <= 32 || $_ > 127 ) # if non-ASCII character... + ? 32 # ...just show a blank + : ( 0xff00 + ( $_ - 32 ) ) # map to "Fullwidth Form" + } unpack( "C*", $value ) + ); # unpack unsigned-char characters } sub clear_screen() { - upper_left(); - printf "\x1b[J"; + upper_left(); + printf "\x1b[J"; } sub clr_to_eol() { - printf "\x1b[K"; + printf "\x1b[K"; } sub lower_left() { - printf "\x1b[%dH", $term_height; + printf "\x1b[%dH", $term_height; } sub upper_left() { - printf "\x1b[H"; + printf "\x1b[H"; } sub move_to($) { - printf "\x1b[%dG", $_[0] + 1; + printf "\x1b[%dG", $_[0] + 1; } sub insert_lines($) { - #lower_left; - if ($_[0]) { - printf "\x1b[%dL", $_[0]; - } else { - printf "\x1b[L"; - } + + #lower_left; + if ( $_[0] ) { + printf "\x1b[%dL", $_[0]; + } + else { + printf "\x1b[L"; + } } sub delete_lines($) { - if ($_[0]) { - printf "\x1b[%dM", $_[0]; - } else { - printf "\x1b[M"; - } + if ( $_[0] ) { + printf "\x1b[%dM", $_[0]; + } + else { + printf "\x1b[M"; + } } sub delete_char() { - set_color(2); - printf "\x1b[%dP", 1; - set_color(1); + set_color(2); + printf "\x1b[%dP", 1; + set_color(1); } sub insert_once($) { - set_color(2); - printf "\x1b[%d@%s", length($_[0]); - write_chars($_[0]); + my $text = shift; + set_color(2); + printf "\x1b[%d@", length($text); + write_chars($text); } sub insert_mode($) { - set_color(2); - printf "\x1b[%dP", length($_[0]); - printf "\x1b[4h"; - write_chars($_[0]); - printf "\x1b[4l"; + set_color(2); + printf "\x1b[%dP", length( $_[0] ); + printf "\x1b[4h"; + write_chars( $_[0] ); + printf "\x1b[4l"; } sub write_chars($) { - set_color(3); - printf "%s", $_[0]; - set_color(1); + set_color(3); + printf "%s", $_[0]; + set_color(1); } # vary the starting point of each line, to make a more interesting pattern sub starts_of($) { - my $value = $_[0]; - if (defined($opt_w)) { - # 0,1,1,2,2,3,3,... - $value = (($value + 1) / 2) % length($test_string); - } else { - $value %= length($test_string); - } - return $value; + my $value = $_[0]; + if ( defined($opt_w) ) { + + # 0,1,1,2,2,3,3,... + $value = ( ( $value + 1 ) / 2 ) % length($test_string); + } + else { + $value %= length($test_string); + } + return $value; } # write the text for the given line-number sub testit($) { - my $number = $_[0]; - my $length = $term_width; - # use delete-lines to "pull" the screen up, like scrolling. - select(undef, undef, undef, 0.1); - if ((($number / $term_height) % 2) != 0) { - upper_left; - insert_lines(1); - } else { - upper_left; - delete_lines(1); - lower_left; - } - if ( defined($opt_n) ) { - printf "%5d ", $number % 99999; - $length -= 6; - } - # if we're printing double-column characters, we have half as much - # space effectively - but don't forget the remainder, so we can push - # the characters by single-columns. - if (defined($opt_c)) { - set_color(1); - clr_to_eol(); - } - my $starts = starts_of($number); - if ( defined($opt_w) ) { - printf " ", if ( ($number % 2 ) != 0); - $length = ($length - (($number) % 2)) / 2; - } - my $string = substr($test_string, $starts); - while ( length($string) < $length ) { - $string = $string . $test_string; - } - $string = substr($string, 0, $length); - if ( defined($opt_w) ) { - $string = double_cells($string); - } - printf "%s", $string; - # now - within the line - modify it - move_to((4 * $term_width) / 5); - insert_mode("XX"); - move_to((3 * $term_width) / 5); - delete_char(); - move_to((2 * $term_width) / 5); - insert_once('~'); - move_to((1 * $term_width) / 5); - write_chars('~'); - move_to(0); - set_color(0); + my $number = $_[0]; + my $length = $term_width; + + # use delete-lines to "pull" the screen up, like scrolling. + select( undef, undef, undef, 0.1 ); + if ( ( ( $number / $term_height ) % 2 ) != 0 ) { + upper_left; + insert_lines(1); + } + else { + upper_left; + delete_lines(1); + lower_left; + } + if ( defined($opt_n) ) { + printf "%5d ", $number % 99999; + $length -= 6; + } + + # if we're printing double-column characters, we have half as much + # space effectively - but don't forget the remainder, so we can push + # the characters by single-columns. + if ( defined($opt_c) ) { + set_color(1); + clr_to_eol(); + } + my $starts = starts_of($number); + if ( defined($opt_w) ) { + printf " ", if ( ( $number % 2 ) != 0 ); + $length = ( $length - ( ($number) % 2 ) ) / 2; + } + my $string = substr( $test_string, $starts ); + while ( length($string) < $length ) { + $string = $string . $test_string; + } + $string = substr( $string, 0, $length ); + if ( defined($opt_w) ) { + $string = double_cells($string); + } + printf "%s", $string; + + # now - within the line - modify it + move_to( ( 4 * $term_width ) / 5 ); + insert_mode("XX"); + move_to( ( 3 * $term_width ) / 5 ); + delete_char(); + move_to( ( 2 * $term_width ) / 5 ); + insert_once('~'); + move_to( ( 1 * $term_width ) / 5 ); + write_chars('~'); + move_to(0); + set_color(0); } sub main::HELP_MESSAGE() { - printf STDERR <<EOF + printf STDERR <<EOF Usage: $0 [options] Options: @@ -231,27 +264,29 @@ Options: -r repeat indefinitely -w write wide-characters EOF -; - exit; + ; + exit; } &getopts('cnrw') || die(); $term_height = screen_height(); -$term_width = screen_width(); +$term_width = screen_width(); -$test_string="0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +$test_string = + "0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -binmode(STDOUT, ":utf8"); +binmode( STDOUT, ":utf8" ); clear_screen(); if ( defined($opt_r) ) { - for ($lineno = 0; ; ++$lineno) { - testit($lineno); - } -} else { - for ($lineno = 0; $lineno < $term_height * 2; ++$lineno) { - testit($lineno); - } + for ( $lineno = 0 ; ; ++$lineno ) { + testit($lineno); + } +} +else { + for ( $lineno = 0 ; $lineno < $term_height * 2 ; ++$lineno ) { + testit($lineno); + } } lower_left(); clr_to_eol(); diff --git a/app/xterm/vttests/lrmm-scroll.pl b/app/xterm/vttests/lrmm-scroll.pl index 33c84751a..028e9d0b6 100644 --- a/app/xterm/vttests/lrmm-scroll.pl +++ b/app/xterm/vttests/lrmm-scroll.pl @@ -1,7 +1,7 @@ #!/usr/bin/env perl -# $XTermId: lrmm-scroll.pl,v 1.12 2019/07/10 08:22:48 tom Exp $ +# $XTermId: lrmm-scroll.pl,v 1.14 2022/10/10 17:07:48 tom Exp $ # ----------------------------------------------------------------------------- -# Copyright 2019 by Thomas E. Dickey +# Copyright 2019,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -40,7 +40,7 @@ use diagnostics; use Term::ReadKey; use Getopt::Std; -# do this so outout from successive calls to this script won't get in the +# do this so output from successive calls to this script won't get in the # wrong order: use IO::Handle; STDERR->autoflush(1); @@ -52,20 +52,36 @@ our ( $term_height, $term_width ); our $CSI = "\033["; +our @resize; + +sub read_resize($) { + my $field = shift; + my $result = shift; + if ( $#resize < 0 ) { + open( FP, "resize -u |" ) or exit $!; + @resize = <FP>; + chomp @resize; + close(FP); + } + for my $n ( 0 .. $#resize ) { + if ( $resize[$n] =~ /^$field=/ ) { + $result = $resize[$n]; + $result =~ s/^[^=]*=//; + $result =~ s/;.*//; + last; + } + } + return $result; +} + # returns the number of rows in the screen sub screen_height() { - my $data = `resize -u |fgrep LINES=`; - $data =~ s/LINES=//; - $data =~ s/;//; - return $data; + return &read_resize( "LINES", 24 ); } # returns the number of columns in the screen sub screen_width() { - my $data = `resize -u |fgrep COLUMNS=`; - $data =~ s/COLUMNS=//; - $data =~ s/;//; - return $data; + return &read_resize( "COLUMNS", 80 ); } sub set_color($) { diff --git a/app/xterm/vttests/other-sgr.sh b/app/xterm/vttests/other-sgr.sh index de253cee0..16aa6b44c 100644 --- a/app/xterm/vttests/other-sgr.sh +++ b/app/xterm/vttests/other-sgr.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: other-sgr.sh,v 1.7 2022/02/13 14:36:10 tom Exp $ +# $XTermId: other-sgr.sh,v 1.9 2022/04/24 23:36:20 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -38,14 +38,15 @@ CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -53,7 +54,7 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" trap '$CMD $OPT "${CSI}0m"; exit 1' 1 2 3 15 trap '$CMD $OPT "${CSI}0m"' 0 diff --git a/app/xterm/vttests/resize.sh b/app/xterm/vttests/resize.sh index b62645206..1bdfb646c 100644 --- a/app/xterm/vttests/resize.sh +++ b/app/xterm/vttests/resize.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: resize.sh,v 1.22 2022/02/13 14:36:28 tom Exp $ +# $XTermId: resize.sh,v 1.25 2022/04/25 08:19:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -39,14 +39,15 @@ CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -54,17 +55,17 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" exec </dev/tty old=`stty -g` stty raw -echo min 0 time 5 $CMD $OPT "${CSI}18t${SUF}" > /dev/tty -IFS=';' read junk high wide +IFS=';' read -r junk high wide $CMD $OPT "${CSI}19t${SUF}" > /dev/tty -IFS=';' read junk maxhigh maxwide +IFS=';' read -r junk maxhigh maxwide stty $old diff --git a/app/xterm/vttests/scroll.pl b/app/xterm/vttests/scroll.pl index f95e1deb1..274bfca73 100644 --- a/app/xterm/vttests/scroll.pl +++ b/app/xterm/vttests/scroll.pl @@ -1,9 +1,9 @@ #!/usr/bin/env perl -# $XTermId: scroll.pl,v 1.2 2009/07/02 23:54:51 tom Exp $ +# $XTermId: scroll.pl,v 1.4 2022/10/10 17:02:54 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2009 by Thomas E. Dickey +# Copyright 2009,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -38,189 +38,222 @@ # add option to wrap the test-pattern # use scrolling-margins to help fill-in a chunk use strict; +use warnings; use Getopt::Std; -# do this so outout from successive calls to this script won't get in the +# do this so output from successive calls to this script won't get in the # wrong order: use IO::Handle; STDERR->autoflush(1); STDOUT->autoflush(1); -our ($opt_c, $opt_n, $opt_r, $opt_w); -our ($lineno, $test_string, $term_height, $term_width, $max_scroll); +our ( $opt_c, $opt_n, $opt_r, $opt_w ); +our ( $lineno, $test_string, $term_height, $term_width, $max_scroll ); + +our @resize; + +sub read_resize($) { + my $field = shift; + my $result = shift; + if ( $#resize < 0 ) { + open( FP, "resize -u |" ) or exit $!; + @resize = <FP>; + chomp @resize; + close(FP); + } + for my $n ( 0 .. $#resize ) { + if ( $resize[$n] =~ /^$field=/ ) { + $result = $resize[$n]; + $result =~ s/^[^=]*=//; + $result =~ s/;.*//; + last; + } + } + return $result; +} # returns the number of rows in the screen sub screen_height() { - my $data = `resize -u |fgrep LINES=`; - $data =~ s/LINES=//; - $data =~ s/;//; - return $data + return &read_resize( "LINES", 24 ); } # returns the number of columns in the screen sub screen_width() { - my $data = `resize -u |fgrep COLUMNS=`; - $data =~ s/COLUMNS=//; - $data =~ s/;//; - return $data + return &read_resize( "COLUMNS", 80 ); } sub set_color($) { - my $code = $_[0]; - if (defined($opt_c)) { - if ($code == 3) { - printf "\x1b[1;33;42m"; # yellow-on-green - } elsif ($code == 2) { - printf "\x1b[0;31;45m"; # red-on-magenta - } elsif ($code == 1) { - printf "\x1b[0;36;44m"; # cyan-on-blue - } else { - printf "\x1b[0;39;49m"; - } - } + my $code = $_[0]; + if ( defined($opt_c) ) { + if ( $code == 3 ) { + printf "\x1b[1;33;42m"; # yellow-on-green + } + elsif ( $code == 2 ) { + printf "\x1b[0;31;45m"; # red-on-magenta + } + elsif ( $code == 1 ) { + printf "\x1b[0;36;44m"; # cyan-on-blue + } + else { + printf "\x1b[0;39;49m"; + } + } } # returns a string of two-column characters given an ASCII alpha/numeric string sub double_cells($) { - my $value = $_[0]; - $value =~ s/ / /g; - pack("U*", - map { ($_ <= 32 || $_ > 127) # if non-ASCII character... - ? 32 # ...just show a blank - : (0xff00 + ($_ - 32)) # map to "Fullwidth Form" - } unpack("C*", $value)); # unpack unsigned-char characters + my $value = $_[0]; + $value =~ s/ / /g; + pack( + "U*", + map { + ( $_ <= 32 || $_ > 127 ) # if non-ASCII character... + ? 32 # ...just show a blank + : ( 0xff00 + ( $_ - 32 ) ) # map to "Fullwidth Form" + } unpack( "C*", $value ) + ); # unpack unsigned-char characters } sub clear_screen() { - upper_left(); - printf "\x1b[J"; + upper_left(); + printf "\x1b[J"; } sub clr_to_eol() { - printf "\x1b[K"; + printf "\x1b[K"; } sub lower_left() { - printf "\x1b[%dH", $term_height; + printf "\x1b[%dH", $term_height; } sub upper_left() { - printf "\x1b[H"; + printf "\x1b[H"; } sub move_to($) { - printf "\x1b[%dG", $_[0] + 1; + printf "\x1b[%dG", $_[0] + 1; } sub bak_scroll($) { - #lower_left; - if ($_[0]) { - printf "\x1b[%dS", $_[0]; - } else { - printf "\x1b[S"; - } + + #lower_left; + if ( $_[0] ) { + printf "\x1b[%dS", $_[0]; + } + else { + printf "\x1b[S"; + } } sub fwd_scroll($) { - if ($_[0]) { - printf "\x1b[%dT", $_[0]; - } else { - printf "\x1b[T"; - } + if ( $_[0] ) { + printf "\x1b[%dT", $_[0]; + } + else { + printf "\x1b[T"; + } } sub delete_char() { - set_color(2); - printf "\x1b[%dP", 1; - set_color(1); + set_color(2); + printf "\x1b[%dP", 1; + set_color(1); } sub insert_once($) { - set_color(2); - printf "\x1b[%d@%s", length($_[0]); - write_chars($_[0]); + my $data = shift; + set_color(2); + printf "\x1b[%d@%s", length($data), $data; + write_chars($data); } sub insert_mode($) { - set_color(2); - printf "\x1b[%dP", length($_[0]); - printf "\x1b[4h"; - write_chars($_[0]); - printf "\x1b[4l"; + set_color(2); + printf "\x1b[%dP", length( $_[0] ); + printf "\x1b[4h"; + write_chars( $_[0] ); + printf "\x1b[4l"; } sub write_chars($) { - set_color(3); - printf "%s", $_[0]; - set_color(1); + set_color(3); + printf "%s", $_[0]; + set_color(1); } # vary the starting point of each line, to make a more interesting pattern sub starts_of($) { - my $value = $_[0]; - if (defined($opt_w)) { - # 0,1,1,2,2,3,3,... - $value = (($value + 1) / 2) % length($test_string); - } else { - $value %= length($test_string); - } - return $value; + my $value = $_[0]; + if ( defined($opt_w) ) { + + # 0,1,1,2,2,3,3,... + $value = ( ( $value + 1 ) / 2 ) % length($test_string); + } + else { + $value %= length($test_string); + } + return $value; } # write the text for the given line-number sub testit($) { - my $number = $_[0]; - my $length = $term_width; - # use delete-lines to "pull" the screen up, like scrolling. - select(undef, undef, undef, 0.1); - if ((($number / $max_scroll) % 2) != 0) { - lower_left; - fwd_scroll(1); - } else { - lower_left; - bak_scroll(1); - } - if ( defined($opt_n) ) { - printf "%5d ", $number % 99999; - $length -= 6; - } - # if we're printing double-column characters, we have half as much - # space effectively - but don't forget the remainder, so we can push - # the characters by single-columns. - if (defined($opt_c)) { - set_color(1); - clr_to_eol(); - } - my $starts = starts_of($number); - if ( defined($opt_w) ) { - printf " ", if ( ($number % 2 ) != 0); - $length = ($length - (($number) % 2)) / 2; - } - my $string = substr($test_string, $starts); - while ( length($string) < $length ) { - $string = $string . $test_string; - } - $string = substr($string, 0, $length); - if ( defined($opt_w) ) { - $string = double_cells($string); - } - printf "%s", $string; - # now - within the line - modify it - move_to((4 * $term_width) / 5); - insert_mode("XX"); - move_to((3 * $term_width) / 5); - delete_char(); - move_to((2 * $term_width) / 5); - insert_once('~'); - move_to((1 * $term_width) / 5); - write_chars('~'); - move_to(0); - set_color(0); + my $number = $_[0]; + my $length = $term_width; + + # use delete-lines to "pull" the screen up, like scrolling. + select( undef, undef, undef, 0.1 ); + if ( ( ( $number / $max_scroll ) % 2 ) != 0 ) { + lower_left; + fwd_scroll(1); + } + else { + lower_left; + bak_scroll(1); + } + if ( defined($opt_n) ) { + printf "%5d ", $number % 99999; + $length -= 6; + } + + # if we're printing double-column characters, we have half as much + # space effectively - but don't forget the remainder, so we can push + # the characters by single-columns. + if ( defined($opt_c) ) { + set_color(1); + clr_to_eol(); + } + my $starts = starts_of($number); + if ( defined($opt_w) ) { + printf " ", if ( ( $number % 2 ) != 0 ); + $length = ( $length - ( ($number) % 2 ) ) / 2; + } + my $string = substr( $test_string, $starts ); + while ( length($string) < $length ) { + $string = $string . $test_string; + } + $string = substr( $string, 0, $length ); + if ( defined($opt_w) ) { + $string = double_cells($string); + } + printf "%s", $string; + + # now - within the line - modify it + move_to( ( 4 * $term_width ) / 5 ); + insert_mode("XX"); + move_to( ( 3 * $term_width ) / 5 ); + delete_char(); + move_to( ( 2 * $term_width ) / 5 ); + insert_once('~'); + move_to( ( 1 * $term_width ) / 5 ); + write_chars('~'); + move_to(0); + set_color(0); } sub main::HELP_MESSAGE() { - printf STDERR <<EOF + printf STDERR <<EOF Usage: $0 [options] Options: @@ -230,28 +263,30 @@ Options: -r repeat indefinitely -w write wide-characters EOF -; - exit; + ; + exit; } &getopts('cnrw') || die(); $term_height = screen_height(); -$term_width = screen_width(); -$max_scroll = $term_height * 2; +$term_width = screen_width(); +$max_scroll = $term_height * 2; -$test_string="0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +$test_string = + "0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -binmode(STDOUT, ":utf8"); +binmode( STDOUT, ":utf8" ); clear_screen(); if ( defined($opt_r) ) { - for ($lineno = 0; ; ++$lineno) { - testit($lineno); - } -} else { - for ($lineno = 0; $lineno < $max_scroll * 2; ++$lineno) { - testit($lineno); - } + for ( $lineno = 0 ; ; ++$lineno ) { + testit($lineno); + } +} +else { + for ( $lineno = 0 ; $lineno < $max_scroll * 2 ; ++$lineno ) { + testit($lineno); + } } lower_left(); clr_to_eol(); diff --git a/app/xterm/vttests/tab0.sh b/app/xterm/vttests/tab0.sh index 4e025dd39..2ee5ee83a 100644 --- a/app/xterm/vttests/tab0.sh +++ b/app/xterm/vttests/tab0.sh @@ -1,7 +1,7 @@ #!/bin/sh -# $XTermId: tab0.sh,v 1.2 2019/06/01 16:03:03 tom Exp $ +# $XTermId: tab0.sh,v 1.6 2022/04/25 22:49:46 tom Exp $ # ----------------------------------------------------------------------------- -# Copyright 2019 by Thomas E. Dickey +# Copyright 2019,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -31,44 +31,44 @@ # ----------------------------------------------------------------------------- # Demonstrate hard-tabs. -: ${TABS:=tabs} -: ${TPUT:=tput} +: "${TABS:=tabs}" +: "${TPUT:=tput}" show() { - printf "Tabs $1:" - read ignore + printf "Tabs %s:" "$1" + read -r ignore p=0 - while [ $p -lt $wide ] + while [ "$p" -lt "$wide" ] do - printf "%s+----%d" "----" `expr 1 + \( $p / 10 \)` + printf "%s+----%d" "----" "`expr 1 + \( "$p" / 10 \)`" p=`expr $p + 10` done - printf "\n" + printf '\n' p=1 printf " " - while [ $p -lt $wide ] + while [ "$p" -lt "$wide" ] do - printf "%*s" $1 "*" - p=`expr $p + $1` + printf "%*s" "$1" "*" + p=`expr "$p" + "$1"` done - printf "\n" + printf '\n' p=0 - while [ $p -lt $wide ] + while [ "$p" -lt "$wide" ] do - printf "\t+" - p=`expr $p + $1` + printf '\t+' + p=`expr "$p" + "$1"` done - printf "\n" + printf '\n' printf "...done" - read ignore + read -r ignore } # enable hard tabs, disable autowrap. initialize() { - $TPUT $1 + "$TPUT" "$1" clear stty tabs - printf "\033[?7l" + printf '\033[?7l' } setup() { @@ -78,7 +78,7 @@ setup() { # Turn hard tabs off, reenable autowrap. restore() { stty -tabs - printf "\033[?7h" + printf '\033[?7h' } wide=`$TPUT cols` @@ -98,7 +98,7 @@ do if [ -n "$value" ] then initialize $name - printf "Testing after tput $name\r\n" + printf 'Testing after tput %s\r\n' "$name" show 8 break fi diff --git a/app/xterm/vttests/title.sh b/app/xterm/vttests/title.sh index 7b7f4d6d7..62f2753b6 100644 --- a/app/xterm/vttests/title.sh +++ b/app/xterm/vttests/title.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $XTermId: title.sh,v 1.23 2022/02/13 14:36:47 tom Exp $ +# $XTermId: title.sh,v 1.26 2022/04/25 08:19:38 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # @@ -39,14 +39,15 @@ CSI="${ESC}[" CMD='/bin/echo' OPT='-n' SUF='' -TMP=`(mktemp) 2>/dev/null` || TMP=/tmp/xterm$$ +: "${TMPDIR=/tmp}" +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -{ test ! -f $TMP || test -s $TMP; } && +{ test ! -f "$TMP" || test -s "$TMP"; } && for verb in "printf" "print" ; do - rm -f $TMP + rm -f "$TMP" eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -54,14 +55,14 @@ for verb in "printf" "print" ; do fi fi done -rm -f $TMP +rm -f "$TMP" exec </dev/tty old=`stty -g` stty raw -echo min 0 time 5 $CMD $OPT "${CSI}21t${SUF}" > /dev/tty -read original +read -r original stty $old diff --git a/app/xterm/vttests/unascii.sh b/app/xterm/vttests/unascii.sh index dcd4d0b96..02c3c6f4a 100644 --- a/app/xterm/vttests/unascii.sh +++ b/app/xterm/vttests/unascii.sh @@ -1,9 +1,9 @@ #!/bin/bash -# $XTermId: unascii.sh,v 1.2 2013/09/02 21:54:06 tom Exp $ +# $XTermId: unascii.sh,v 1.4 2022/04/25 07:58:15 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2013 by Thomas E. Dickey +# Copyright 2013,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -32,17 +32,18 @@ # authorization. # ----------------------------------------------------------------------------- # display the characters recognized by xterm in AsciiEquivs -export PATH=$(dirname $(readlink -f $0)):$PATH -vxt-utf8 0x2010 -vxt-utf8 0x2011 -vxt-utf8 0x2012 -vxt-utf8 0x2013 -vxt-utf8 0x2014 -vxt-utf8 0x2015 -vxt-utf8 0x2212 -vxt-utf8 0x2018 -vxt-utf8 0x2019 -vxt-utf8 0x201C -vxt-utf8 0x201D -vxt-utf8 0x2329 -vxt-utf8 0x232a +PATH="$(dirname "$(readlink -f "$0")"):$PATH" +export PATH +utf8.pl 0x2010 +utf8.pl 0x2011 +utf8.pl 0x2012 +utf8.pl 0x2013 +utf8.pl 0x2014 +utf8.pl 0x2015 +utf8.pl 0x2212 +utf8.pl 0x2018 +utf8.pl 0x2019 +utf8.pl 0x201C +utf8.pl 0x201D +utf8.pl 0x2329 +utf8.pl 0x232a diff --git a/app/xterm/vttests/utf8.pl b/app/xterm/vttests/utf8.pl index 3b162361e..0061e9393 100644 --- a/app/xterm/vttests/utf8.pl +++ b/app/xterm/vttests/utf8.pl @@ -1,12 +1,12 @@ #!/usr/bin/env perl -# $XTermId: utf8.pl,v 1.5 2018/12/14 09:25:47 tom Exp $ +# $XTermId: utf8.pl,v 1.12 2022/07/08 18:32:43 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2012,2018 by Thomas E. Dickey -# +# Copyright 2012-2018,2022 by Thomas E. Dickey +# # All Rights Reserved -# +# # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including @@ -14,10 +14,10 @@ # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: -# +# # The above copyright notice and this permission notice shall be included # in all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. @@ -25,7 +25,7 @@ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# +# # Except as contained in this notice, the name(s) of the above copyright # holders shall not be used in advertising or otherwise to promote the # sale, use or other dealings in this Software without prior written @@ -33,41 +33,92 @@ # ----------------------------------------------------------------------------- # display the given Unicode characters, given their hex or decimal values. +use warnings FATAL => "overflow"; +no warnings "portable"; use strict; use Encode 'encode_utf8'; +use Text::CharWidth qw(mbswidth); + +$| = 1; + +sub num_bytes($) { + my $char = shift; + my $value = length( Encode::encode_utf8($char) ); + my $result = + ( $value <= 0 + ? "no bytes" + : ( $value > 1 ? sprintf( "%d bytes", $value ) : "1 bytes" ) ); + return $result; +} + +sub num_cells($) { + my $char = shift; + my $value = mbswidth($char); + my $result = + ( $value <= 0 + ? "no cells" + : ( $value > 1 ? sprintf( "%d cells", $value ) : "1 cell" ) ); + return $result; +} + +sub pad_column($) { + my $char = shift; + my $value = mbswidth($char); + $value = 0 if ( $value < 0); + my $result = sprintf( "%.*s", 3 - $value, " "); + return $result; +} sub vxt_utf8($) { - my $arg = $_[0]; - my $hex = $arg; - my $dec = $arg; - if ( $arg =~ /^u\+[[:xdigit:]]+/i ) { - $hex =~ s/^../0x/; - $dec = hex($hex); - } elsif ( $arg !~ /^0x[[:xdigit:]]+$/i ) { - $hex = sprintf "%04X", $arg; - } elsif ( $arg !~ /^u\+[[:xdigit:]]+$/i ) { - $hex =~ s/^u\+//i; - $hex = sprintf "%04X", $arg; - } else { - $dec = hex($hex); - } - my $chr = chr($dec); - my $type = ( $chr =~ /\p{isPrint}/ - ? ( $chr =~ /\p{isAlpha}/ - ? "alpha" - : ( $chr =~ /\p{isPunct}/ - ? "punct" - : ( $chr =~ /\p{isDigit}/ - ? "digit" - : "printing" ) ) ) - : ( $chr =~ /\p{isCntrl}/ - ? "cntrl" - : "nonprinting" ) ); - printf "%d ->%#x ->{%s} (%d bytes, %s)\n", $dec, $dec, $chr, length(Encode::encode_utf8($dec)), $type; + my $arg = $_[0]; + my $hex = $arg; + my $dec = $arg; + if ( $arg =~ /^u\+[[:xdigit:]]+$/i ) { + $hex =~ s/^../0x/; + $dec = hex($hex); + } + elsif ( $arg =~ /^0x[[:xdigit:]]+$/i ) { + $dec = hex($hex); + } + elsif ( $arg =~ /^[[:xdigit:]]+$/i ) { + $dec = hex($hex); + } + else { + printf STDERR "? not a codepoint: $dec\n"; + return; + } + my $chr = chr($dec); + my $type = ( + $chr =~ /\p{isPrint}/ + ? ( + $chr =~ /\p{isAlpha}/ + ? "alpha" + : ( + $chr =~ /\p{isPunct}/ + ? "punct" + : ( + $chr =~ /\p{isDigit}/ + ? "digit" + : "printing" + ) + ) + ) + : ( + $chr =~ /\p{isCntrl}/ + ? "cntrl" + : "nonprinting" + ) + ); + printf "%d ->%#x ->{%s}%s(%s %s %s)\n", $dec, $dec, $chr, + &pad_column($chr), + &num_bytes($chr), + &num_cells($chr), + $type; } -binmode(STDOUT, ":utf8"); +binmode( STDOUT, ":utf8" ); while ( $#ARGV >= 0 ) { - vxt_utf8 ( shift @ARGV ); + vxt_utf8( shift @ARGV ); } -exit; + +1; diff --git a/app/xterm/vttests/version.sh b/app/xterm/vttests/version.sh index 7e680fe38..1c6eeab81 100644 --- a/app/xterm/vttests/version.sh +++ b/app/xterm/vttests/version.sh @@ -1,9 +1,9 @@ #!/bin/sh -# $XTermId: version.sh,v 1.1 2020/04/25 20:47:48 tom Exp $ +# $XTermId: version.sh,v 1.6 2022/04/25 22:47:07 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2020 by Thomas E. Dickey +# Copyright 2020,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -37,14 +37,14 @@ ESC="" CMD='/bin/echo' OPT='-n' SUF='' -TMP=/tmp/xterm$$ +TMP=`(mktemp "$TMPDIR/xterm.XXXXXXXX") 2>/dev/null` || TMP="$TMPDIR/xterm$$" eval '$CMD $OPT >$TMP || echo fail >$TMP' 2>/dev/null -( test ! -f $TMP || test -s $TMP ) && +( test ! -f "$TMP" || test -s "$TMP" ) && for verb in printf print ; do - rm -f $TMP - eval '$verb "\c" >$TMP || echo fail >$TMP' 2>/dev/null - if test -f $TMP ; then - if test ! -s $TMP ; then + rm -f "$TMP" + eval '$verb "\c" >"$TMP" || echo fail >"$TMP"' 2>/dev/null + if test -f "$TMP" ; then + if test ! -s "$TMP" ; then CMD="$verb" OPT= SUF='\c' @@ -52,14 +52,14 @@ for verb in printf print ; do fi fi done -rm -f $TMP +rm -f "$TMP" exec </dev/tty old=`stty -g` stty raw -echo min 0 time 5 $CMD $OPT "${ESC}[>0q${SUF}" > /dev/tty -read version +read -r version stty $old echo "$version" |cat -v diff --git a/app/xterm/vttests/xorblink.pl b/app/xterm/vttests/xorblink.pl index ae4b978b3..5381f19ad 100644 --- a/app/xterm/vttests/xorblink.pl +++ b/app/xterm/vttests/xorblink.pl @@ -1,5 +1,34 @@ #!/usr/bin/env perl -# $XTermId: xorblink.pl,v 1.15 2017/12/24 21:03:54 tom Exp $ +# $XTermId: xorblink.pl,v 1.16 2017/12/24 21:03:54 tom Exp $ +# ----------------------------------------------------------------------------- +# Copyright 2017 by Thomas E. Dickey +# +# All Rights Reserved +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name(s) of the above copyright +# holders shall not be used in advertising or otherwise to promote the +# sale, use or other dealings in this Software without prior written +# authorization. +# ----------------------------------------------------------------------------- # walk through the different states of cursor-blinking, with annotation # # Manual: diff --git a/app/xterm/wcwidth.c b/app/xterm/wcwidth.c index 023aa9004..b19d3b95f 100644 --- a/app/xterm/wcwidth.c +++ b/app/xterm/wcwidth.c @@ -1,4 +1,4 @@ -/* $XTermId: wcwidth.c,v 1.59 2022/02/13 16:11:03 tom Exp $ */ +/* $XTermId: wcwidth.c,v 1.61 2022/09/24 00:24:57 tom Exp $ */ /* $XFree86: xc/programs/xterm/wcwidth.c,v 1.9 2006/06/19 00:36:52 dickey Exp $ */ @@ -213,12 +213,28 @@ int mk_wcwidth(wchar_t ucs) { unsigned long cmp = (unsigned long) ucs; + /* sorted list of non-overlapping intervals of formatting characters */ + /* generated by + * uniset +cat=Cf -00AD -0600-0605 -061C -06DD -070F c + */ + /* *INDENT-OFF* */ + /* generated by run-uniset_ctl 1.1 */ + static const struct interval formatting[] = { + { 0x0890, 0x0891 }, { 0x08E2, 0x08E2 }, { 0x180E, 0x180E }, + { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2064 }, + { 0x2066, 0x206F }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, + { 0x110BD, 0x110BD }, { 0x110CD, 0x110CD }, { 0x13430, 0x13438 }, + { 0x1BCA0, 0x1BCA3 }, { 0x1D173, 0x1D17A }, { 0xE0001, 0xE0001 }, + { 0xE0020, 0xE007F } + }; + /* *INDENT-OFF* */ + /* sorted list of non-overlapping intervals of non-spacing characters */ /* generated by - * uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c + * uniset +cat=Me +cat=Mn +0600-0605 +061C +06DD +070F +1160-11FF +D7B0-D7C6 +D7CB-D7FB c */ /* *INDENT-OFF* */ - /* generated by run-uniset 1.6 */ + /* generated by run-uniset 1.9 */ static const struct interval combining[] = { { 0x0300, 0x036F }, { 0x0483, 0x0489 }, { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, { 0x05C4, 0x05C5 }, @@ -229,7 +245,7 @@ int mk_wcwidth(wchar_t ucs) { 0x0730, 0x074A }, { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x07FD, 0x07FD }, { 0x0816, 0x0819 }, { 0x081B, 0x0823 }, { 0x0825, 0x0827 }, { 0x0829, 0x082D }, { 0x0859, 0x085B }, - { 0x0890, 0x0891 }, { 0x0898, 0x089F }, { 0x08CA, 0x0902 }, + { 0x0898, 0x089F }, { 0x08CA, 0x08E1 }, { 0x08E3, 0x0902 }, { 0x093A, 0x093A }, { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0957 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, @@ -262,22 +278,21 @@ int mk_wcwidth(wchar_t ucs) { 0x1160, 0x11FF }, { 0x135D, 0x135F }, { 0x1712, 0x1714 }, { 0x1732, 0x1733 }, { 0x1752, 0x1753 }, { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD }, { 0x17C6, 0x17C6 }, - { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, { 0x180B, 0x180F }, - { 0x1885, 0x1886 }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 }, - { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B }, - { 0x1A17, 0x1A18 }, { 0x1A1B, 0x1A1B }, { 0x1A56, 0x1A56 }, - { 0x1A58, 0x1A5E }, { 0x1A60, 0x1A60 }, { 0x1A62, 0x1A62 }, - { 0x1A65, 0x1A6C }, { 0x1A73, 0x1A7C }, { 0x1A7F, 0x1A7F }, - { 0x1AB0, 0x1ACE }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 }, - { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 }, - { 0x1B6B, 0x1B73 }, { 0x1B80, 0x1B81 }, { 0x1BA2, 0x1BA5 }, - { 0x1BA8, 0x1BA9 }, { 0x1BAB, 0x1BAD }, { 0x1BE6, 0x1BE6 }, - { 0x1BE8, 0x1BE9 }, { 0x1BED, 0x1BED }, { 0x1BEF, 0x1BF1 }, - { 0x1C2C, 0x1C33 }, { 0x1C36, 0x1C37 }, { 0x1CD0, 0x1CD2 }, - { 0x1CD4, 0x1CE0 }, { 0x1CE2, 0x1CE8 }, { 0x1CED, 0x1CED }, - { 0x1CF4, 0x1CF4 }, { 0x1CF8, 0x1CF9 }, { 0x1DC0, 0x1DFF }, - { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2064 }, - { 0x2066, 0x206F }, { 0x20D0, 0x20F0 }, { 0x2CEF, 0x2CF1 }, + { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD }, { 0x180B, 0x180D }, + { 0x180F, 0x180F }, { 0x1885, 0x1886 }, { 0x18A9, 0x18A9 }, + { 0x1920, 0x1922 }, { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, + { 0x1939, 0x193B }, { 0x1A17, 0x1A18 }, { 0x1A1B, 0x1A1B }, + { 0x1A56, 0x1A56 }, { 0x1A58, 0x1A5E }, { 0x1A60, 0x1A60 }, + { 0x1A62, 0x1A62 }, { 0x1A65, 0x1A6C }, { 0x1A73, 0x1A7C }, + { 0x1A7F, 0x1A7F }, { 0x1AB0, 0x1ACE }, { 0x1B00, 0x1B03 }, + { 0x1B34, 0x1B34 }, { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, + { 0x1B42, 0x1B42 }, { 0x1B6B, 0x1B73 }, { 0x1B80, 0x1B81 }, + { 0x1BA2, 0x1BA5 }, { 0x1BA8, 0x1BA9 }, { 0x1BAB, 0x1BAD }, + { 0x1BE6, 0x1BE6 }, { 0x1BE8, 0x1BE9 }, { 0x1BED, 0x1BED }, + { 0x1BEF, 0x1BF1 }, { 0x1C2C, 0x1C33 }, { 0x1C36, 0x1C37 }, + { 0x1CD0, 0x1CD2 }, { 0x1CD4, 0x1CE0 }, { 0x1CE2, 0x1CE8 }, + { 0x1CED, 0x1CED }, { 0x1CF4, 0x1CF4 }, { 0x1CF8, 0x1CF9 }, + { 0x1DC0, 0x1DFF }, { 0x20D0, 0x20F0 }, { 0x2CEF, 0x2CF1 }, { 0x2D7F, 0x2D7F }, { 0x2DE0, 0x2DFF }, { 0x302A, 0x302D }, { 0x3099, 0x309A }, { 0xA66F, 0xA672 }, { 0xA674, 0xA67D }, { 0xA69E, 0xA69F }, { 0xA6F0, 0xA6F1 }, { 0xA802, 0xA802 }, @@ -291,16 +306,15 @@ int mk_wcwidth(wchar_t ucs) { 0xAAB2, 0xAAB4 }, { 0xAAB7, 0xAAB8 }, { 0xAABE, 0xAABF }, { 0xAAC1, 0xAAC1 }, { 0xAAEC, 0xAAED }, { 0xAAF6, 0xAAF6 }, { 0xABE5, 0xABE5 }, { 0xABE8, 0xABE8 }, { 0xABED, 0xABED }, - { 0xD7B0, 0xD7FF }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F }, - { 0xFE20, 0xFE2F }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB }, - { 0x101FD, 0x101FD }, { 0x102E0, 0x102E0 }, { 0x10376, 0x1037A }, - { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, - { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x10AE5, 0x10AE6 }, - { 0x10D24, 0x10D27 }, { 0x10EAB, 0x10EAC }, { 0x10F46, 0x10F50 }, - { 0x10F82, 0x10F85 }, { 0x11001, 0x11001 }, { 0x11038, 0x11046 }, - { 0x11070, 0x11070 }, { 0x11073, 0x11074 }, { 0x1107F, 0x11081 }, - { 0x110B3, 0x110B6 }, { 0x110B9, 0x110BA }, { 0x110BD, 0x110BD }, - { 0x110C2, 0x110C2 }, { 0x110CD, 0x110CD }, { 0x11100, 0x11102 }, + { 0xD7B0, 0xD7C6 }, { 0xD7CB, 0xD7FB }, { 0xFB1E, 0xFB1E }, + { 0xFE00, 0xFE0F }, { 0xFE20, 0xFE2F }, { 0x101FD, 0x101FD }, + { 0x102E0, 0x102E0 }, { 0x10376, 0x1037A }, { 0x10A01, 0x10A03 }, + { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F }, { 0x10A38, 0x10A3A }, + { 0x10A3F, 0x10A3F }, { 0x10AE5, 0x10AE6 }, { 0x10D24, 0x10D27 }, + { 0x10EAB, 0x10EAC }, { 0x10F46, 0x10F50 }, { 0x10F82, 0x10F85 }, + { 0x11001, 0x11001 }, { 0x11038, 0x11046 }, { 0x11070, 0x11070 }, + { 0x11073, 0x11074 }, { 0x1107F, 0x11081 }, { 0x110B3, 0x110B6 }, + { 0x110B9, 0x110BA }, { 0x110C2, 0x110C2 }, { 0x11100, 0x11102 }, { 0x11127, 0x1112B }, { 0x1112D, 0x11134 }, { 0x11173, 0x11173 }, { 0x11180, 0x11181 }, { 0x111B6, 0x111BE }, { 0x111C9, 0x111CC }, { 0x111CF, 0x111CF }, { 0x1122F, 0x11231 }, { 0x11234, 0x11234 }, @@ -325,18 +339,16 @@ int mk_wcwidth(wchar_t ucs) { 0x11D31, 0x11D36 }, { 0x11D3A, 0x11D3A }, { 0x11D3C, 0x11D3D }, { 0x11D3F, 0x11D45 }, { 0x11D47, 0x11D47 }, { 0x11D90, 0x11D91 }, { 0x11D95, 0x11D95 }, { 0x11D97, 0x11D97 }, { 0x11EF3, 0x11EF4 }, - { 0x13430, 0x13438 }, { 0x16AF0, 0x16AF4 }, { 0x16B30, 0x16B36 }, - { 0x16F4F, 0x16F4F }, { 0x16F8F, 0x16F92 }, { 0x16FE4, 0x16FE4 }, - { 0x1BC9D, 0x1BC9E }, { 0x1BCA0, 0x1BCA3 }, { 0x1CF00, 0x1CF2D }, - { 0x1CF30, 0x1CF46 }, { 0x1D167, 0x1D169 }, { 0x1D173, 0x1D182 }, - { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, { 0x1D242, 0x1D244 }, - { 0x1DA00, 0x1DA36 }, { 0x1DA3B, 0x1DA6C }, { 0x1DA75, 0x1DA75 }, - { 0x1DA84, 0x1DA84 }, { 0x1DA9B, 0x1DA9F }, { 0x1DAA1, 0x1DAAF }, - { 0x1E000, 0x1E006 }, { 0x1E008, 0x1E018 }, { 0x1E01B, 0x1E021 }, - { 0x1E023, 0x1E024 }, { 0x1E026, 0x1E02A }, { 0x1E130, 0x1E136 }, - { 0x1E2AE, 0x1E2AE }, { 0x1E2EC, 0x1E2EF }, { 0x1E8D0, 0x1E8D6 }, - { 0x1E944, 0x1E94A }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F }, - { 0xE0100, 0xE01EF } + { 0x16AF0, 0x16AF4 }, { 0x16B30, 0x16B36 }, { 0x16F4F, 0x16F4F }, + { 0x16F8F, 0x16F92 }, { 0x16FE4, 0x16FE4 }, { 0x1BC9D, 0x1BC9E }, + { 0x1CF00, 0x1CF2D }, { 0x1CF30, 0x1CF46 }, { 0x1D167, 0x1D169 }, + { 0x1D17B, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD }, + { 0x1D242, 0x1D244 }, { 0x1DA00, 0x1DA36 }, { 0x1DA3B, 0x1DA6C }, + { 0x1DA75, 0x1DA75 }, { 0x1DA84, 0x1DA84 }, { 0x1DA9B, 0x1DA9F }, + { 0x1DAA1, 0x1DAAF }, { 0x1E000, 0x1E006 }, { 0x1E008, 0x1E018 }, + { 0x1E01B, 0x1E021 }, { 0x1E023, 0x1E024 }, { 0x1E026, 0x1E02A }, + { 0x1E130, 0x1E136 }, { 0x1E2AE, 0x1E2AE }, { 0x1E2EC, 0x1E2EF }, + { 0x1E8D0, 0x1E8D6 }, { 0x1E944, 0x1E94A }, { 0xE0100, 0xE01EF } }; /* *INDENT-ON* */ @@ -645,6 +657,9 @@ int mk_wcwidth(wchar_t ucs) result = -1; } else if (cmp == 0xad) { result = use_latin1; + } else if (Lookup(cmp, formatting)) { + /* treat formatting characters like control characters */ + result = -1; } else if (Lookup(cmp, combining)) { /* binary search in table of non-spacing characters */ result = 0; diff --git a/app/xterm/xterm.appdata.xml b/app/xterm/xterm.appdata.xml index 92fa95b1c..fa7b633dd 100644 --- a/app/xterm/xterm.appdata.xml +++ b/app/xterm/xterm.appdata.xml @@ -35,7 +35,7 @@ <keyword>terminal</keyword> </keywords> <releases> - <release version="372" date="2022-03-09"/> + <release version="374" date="2022-10-10"/> </releases> <url type="homepage">https://invisible-island.net/xterm/</url> <update_contact>dickey@invisible-island.net</update_contact> diff --git a/app/xterm/xterm.desktop b/app/xterm/xterm.desktop index 61dcd2c29..b6b27d084 100644 --- a/app/xterm/xterm.desktop +++ b/app/xterm/xterm.desktop @@ -1,8 +1,8 @@ -# $XTermId: xterm.desktop,v 1.15 2016/03/08 01:38:50 tom Exp $ +# $XTermId: xterm.desktop,v 1.16 2022/09/06 21:10:14 tom Exp $ # ----------------------------------------------------------------------------- # this file is part of xterm # -# Copyright 2006-2012,2016 by Thomas E. Dickey +# Copyright 2006-2016,2022 by Thomas E. Dickey # # All Rights Reserved # @@ -41,3 +41,4 @@ Encoding=UTF-8 Icon=xterm-color_48x48 Categories=System;TerminalEmulator; Keywords=shell;prompt;command;commandline;cmd; +StartupWMClass=XTerm diff --git a/app/xterm/xterm.h b/app/xterm/xterm.h index a91b26a47..b3f1d45c9 100644 --- a/app/xterm/xterm.h +++ b/app/xterm/xterm.h @@ -1,4 +1,4 @@ -/* $XTermId: xterm.h,v 1.910 2022/03/09 00:39:01 tom Exp $ */ +/* $XTermId: xterm.h,v 1.918 2022/10/06 19:48:28 tom Exp $ */ /* * Copyright 1999-2021,2022 by Thomas E. Dickey @@ -516,6 +516,7 @@ extern char **environ; #define XtNfaceName "faceName" #define XtNfaceNameDoublesize "faceNameDoublesize" #define XtNfaceSize "faceSize" +#define XtNfaintIsRelative "faintIsRelative" #define XtNfastScroll "fastScroll" #define XtNfont1 "font1" #define XtNfont2 "font2" @@ -645,6 +646,9 @@ extern char **environ; #define XtNwideBoldFont "wideBoldFont" #define XtNwideChars "wideChars" #define XtNwideFont "wideFont" +#define XtNxftMaxGlyphMemory "xftMaxGlyphMemory" +#define XtNxftMaxUnrefFonts "xftMaxUnrefFonts" +#define XtNxftTrackMemUsage "xftTrackMemUsage" #define XtNximFont "ximFont" #define XtNxmcAttributes "xmcAttributes" /* ncurses-testing */ #define XtNxmcGlitch "xmcGlitch" /* ncurses-testing */ @@ -726,6 +730,7 @@ extern char **environ; #define XtCFaceName "FaceName" #define XtCFaceNameDoublesize "FaceNameDoublesize" #define XtCFaceSize "FaceSize" +#define XtCFaintIsRelative "FaintIsRelative" #define XtCFastScroll "FastScroll" #define XtCFont1 "Font1" #define XtCFont2 "Font2" @@ -845,6 +850,9 @@ extern char **environ; #define XtCWideBoldFont "WideBoldFont" #define XtCWideChars "WideChars" #define XtCWideFont "WideFont" +#define XtCXftMaxGlyphMemory "XftMaxGlyphMemory" +#define XtCXftMaxUnrefFonts "XftMaxUnrefFonts" +#define XtCXftTrackMemUsage "XftTrackMemUsage" #define XtCXimFont "XimFont" #define XtCXmcAttributes "XmcAttributes" /* ncurses-testing */ #define XtCXmcGlitch "XmcGlitch" /* ncurses-testing */ @@ -1005,7 +1013,7 @@ extern void FindFontSelection (XtermWidget /* xw */, const char * /* atom_name * extern void HideCursor (XtermWidget /* xw */); extern void RestartBlinking(XtermWidget /* xw */); extern void ShowCursor (XtermWidget /* xw */); -extern void SwitchBufPtrs (TScreen * /* screen */, int /* toBuf */); +extern void SwitchBufPtrs (XtermWidget /* xw */, int /* toBuf */); extern void ToggleAlternate (XtermWidget /* xw */); extern void VTInitTranslations (void); extern GCC_NORETURN void VTReset (XtermWidget /* xw */, int /* full */, int /* saved */); @@ -1028,7 +1036,7 @@ extern void unparseputc1 (XtermWidget /* xw */, int /* c */); extern void unparseputn (XtermWidget /* xw */, unsigned /* n */); extern void unparseputs (XtermWidget /* xw */, const char * /* s */); extern void unparseseq (XtermWidget /* xw */, ANSI * /* ap */); -extern void v_write (int /* f */, const Char * /* d */, unsigned /* len */); +extern void v_write (int /* f */, const Char * /* d */, size_t /* len */); extern void xtermAddInput (Widget /* w */); extern void xtermDecodeSCS (XtermWidget /* xw */, int /* which */, int /* sgroup */, int /* prefix */, int /* suffix */); @@ -1104,7 +1112,7 @@ extern void xterm_ResetDouble(XtermWidget /* xw */); #if OPT_DEC_CHRSET extern GC xterm_DoubleGC(XTermDraw * /* params */, GC /* old_gc */, int * /* inxp */); #if OPT_RENDERFONT -extern XftFont * xterm_DoubleFT(XTermDraw * /* params */, unsigned /* chrset */, unsigned /* attr_flags */); +extern XTermXftFonts * xterm_DoubleFT(XTermDraw * /* params */, unsigned /* chrset */, unsigned /* attr_flags */); extern void freeall_DoubleFT(XtermWidget /* xw */); #endif #endif @@ -1180,7 +1188,7 @@ extern Window WMFrameWindow (XtermWidget /* xw */); extern XtInputMask xtermAppPending (void); extern XrmOptionDescRec * sortedOptDescs (XrmOptionDescRec *, Cardinal); extern XtermWidget getXtermWidget (Widget /* w */); -extern int getVisualInfo (XtermWidget /* xw */); +extern XVisualInfo *getVisualInfo (XtermWidget /* xw */); extern char *udk_lookup (XtermWidget /* xw */, int /* keycode */, int * /* len */); extern char *xtermEnvEncoding (void); extern char *xtermFindShell (char * /* leaf */, Bool /* warning */); @@ -1384,7 +1392,7 @@ extern void xtermDumpSvg (XtermWidget /* xw */); extern Bool decodeUtf8 (TScreen * /* screen */, PtyData * /* data */); extern int readPtyData (XtermWidget /* xw */, PtySelect * /* select_mask */, PtyData * /* data */); -extern void fillPtyData (XtermWidget /* xw */, PtyData * /* data */, const char * /* value */, int /* length */); +extern void fillPtyData (XtermWidget /* xw */, PtyData * /* data */, const char * /* value */, size_t /* length */); extern void initPtyData (PtyData ** /* data */); extern void trimPtyData (XtermWidget /* xw */, PtyData * /* data */); @@ -1399,7 +1407,7 @@ extern Char *convertFromUTF8 (Char * /* lp */, unsigned * /* cp */); extern IChar nextPtyData (TScreen * /* screen */, PtyData * /* data */); extern PtyData * fakePtyData (PtyData * /* result */, Char * /* next */, Char * /* last */); extern void switchPtyData (TScreen * /* screen */, int /* f */); -extern void writePtyData (int /* f */, IChar * /* d */, unsigned /* len */); +extern void writePtyData (int /* f */, IChar * /* d */, size_t /* len */); #define morePtyData(screen, data) \ (((data)->last > (data)->next) \ diff --git a/app/xterm/xterm.log.html b/app/xterm/xterm.log.html index 03324b122..86adab8c1 100644 --- a/app/xterm/xterm.log.html +++ b/app/xterm/xterm.log.html @@ -30,7 +30,7 @@ * sale, use or other dealings in this Software without prior written * * authorization. * ***************************************************************************** - $XTermId: xterm.log.html,v 1.2406 2022/03/10 01:00:00 tom Exp $ + $XTermId: xterm.log.html,v 1.2447 2022/10/11 00:04:21 tom Exp $ --> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> @@ -70,6 +70,10 @@ CHANGELOG</a>).</p> <ul> + <li><a href="#xterm_374">Patch #374 - 2022/10/10</a></li> + + <li><a href="#xterm_373">Patch #373 - 2022/09/25</a></li> + <li><a href="#xterm_372">Patch #372 - 2022/03/09</a></li> <li><a href="#xterm_371">Patch #371 - 2022/02/24</a></li> @@ -1022,6 +1026,165 @@ <li><a href="#xterm_01">Patch #1 - 1996/1/6</a></li> </ul> + <h1><a name="xterm_374" id="xterm_374">Patch #374 - + 2022/10/10</a></h1> + + <ul> + <li>eliminate use of grep aliases from vttests scripts.</li> + + <li>amend discussion of <code>DECSDM</code> versus <em>Sixel + Scrolling</em> in <code>ctlseqs.ms</code> (reports by Hayaki + Saito, Ben Wong).</li> + + <li>change default for <code>sixelScrolling</code> resource to + better match VT330/VT340 <code>DECSDM</code> setting (patch by + Ben Wong).</li> + + <li>fix some gcc and coverity warnings.</li> + + <li>improve memory usage for <tt>OSC 52</tt> (report by + David Leadbeater).</li> + + <li>fix regression in <a href="#xterm_373">xterm-373</a> change + adding resources <tt>xftTrackMemUsage</tt> to + <tt>xftMaxGlyphMemory</tt>, which did not first cache the + server's resource-settings (report/testcase by Gabor Hauzer, as + well as Debian #1021243).</li> + + <li>fix regression in <a href="#xterm_373">xterm-373</a> change + for status-line vs alternate screen (report by Rajeev V. + Pillai).</li> + + <li>configure script improvements: + <ul> + <li>modify <tt>CF_XOPEN_SOURCE</tt> to handle more special + cases of Linux (reports by Adam Sampson, Sven + Joachim).</li> + + <li>modify checks for egrep/fgrep aliases to work around + warning messages from GNU grep 3.8</li> + </ul> + </li> + </ul> + + <h1><a name="xterm_373" id="xterm_373">Patch #373 - + 2022/09/25</a></h1> + + <ul> + <li>improve rendering of TrueType fonts: + <ul> + <li>add resource <tt>xftTrackMemUsage</tt> to + enable/disable a new feature of Xft which improves + performance.</li> + + <li>add resources <tt>xftMaxGlyphMemory</tt> and + <tt>xftMaxUnrefFonts</tt> to customize memory-usage of Xft + and fontconfig.</li> + + <li>provide for display of colored fonts in libXft + 2.3.5</li> + + <li>allow for an extra TrueType font to be specified using + the <code>-fa</code> option, as an override to the + <em>fontconfig</em> scheme of fallback fonts (request by + Nickolas Raymond Kaczynski).</li> + + <li>improve caching of TrueType missing-glyph tests.</li> + + <li>allow no more than 255 fonts to be scanned for a + fontset.</li> + + <li>eliminate a table-lookup in <tt>findXftGlyph</tt></li> + </ul> + </li> + + <li>improvements status-line feature: + <ul> + <li>save/restore wraparound flag when updating the + status-line (report by Rajeev V. Pillai).</li> + + <li>avoid clearing the status-line when switching between + normal and alternate screens (report by Valtteri + Vuorikoski).</li> + + <li>remove adjustment from <tt>update_winsize</tt> leftover + from initial work (report by Valtteri Vuorikoski).</li> + </ul> + </li> + + <li>modify <tt>wcwidth</tt> tables to separate Unicode + <em>Cf</em> category as <em>formatting</em> control-characters, + to better match the guideline for <a href= + "http://www.unicode.org/faq/unsup_char.html">unsupported + characters</a> (report by Tim Chase).</li> + + <li>add configure option + <tt>--disable-exec-selection</tt>.</li> + + <li>use <tt>mkstemp</tt> where <tt>mkdtemp</tt> is unavailable, + when initializing colored cursor.</li> + + <li>adapt fixes from OpenBSD xenocara: + <ul> + <li>improve ifdef's for a few optional features.</li> + + <li>correct <tt>#ifdef</tt> to <tt>#if</tt> in a few uses + of <tt>OPT_PRINT_ON_EXIT</tt>.</li> + </ul> + </li> + + <li>set <tt>StartupWMClass</tt> in + “<tt>.desktop</tt>” files, e.g., to help + <tt>cinnamon-session</tt> notice that xterm sets + <tt>WM_CLASS</tt> and use its icon (patch by Richard de + Boer).</li> + + <li>disable pixel computation when rgb width is greater than 8, + to work with depth 30 (patch by Denis Kaganovich).</li> + + <li>improve color-computation for SGR 2 faint/dim (patch by + Boian Bonev). Add resource <tt>faintIsRelative</tt> to specify + if the modified computation should be used (prompted by + discussion with Matthieu Herrb).</li> + + <li>correct comparison-length for environment variable cleanup + (patch by Brendan O' Dea).</li> + + <li>correct <tt>dsl</tt> capability for <tt>dec+sl</tt> block + in terminfo (report by Rajeev V. Pillai).</li> + + <li>improve output formatting by <tt>vttests/utf8.pl</tt></li> + + <li>repair test/demo scripts still using "vxt-" prefix, some + cleanup with shellcheck.</li> + + <li>enable page-number for <tt>DECXCPR</tt> response in + VT330.</li> + + <li>amend change for combining characters in <a href= + "#xterm_371">patch #371</a> to limit it to the + currently-defined codes (report by Thomas Wolff).</li> + + <li>add directory-template parameter to <tt>mktemp</tt> in + shell-scripts to improve portability to older systems (patch by + Ryan Schmidt).</li> + + <li>mention webpage <a href= + "https://invisible-island.net/xterm/xterm-paste64.html"><em>XTerm + – bracketed-paste</em></a> in + <code>ctlseqs.ms</code></li> + + <li>update manual-page descriptions for + <code>allowPasteControls</code> and + <code>disallowedPasteControls</code> (<a href= + "#xterm_363">patch #363</a>).</li> + + <li>further extended list of environment variables to purge on + startup (suggested by Thomas Wolff).</li> + + <li>update config.guess, config.sub</li> + </ul> + <h1><a name="xterm_372" id="xterm_372">Patch #372 - 2022/03/09</a></h1> diff --git a/app/xterm/xterm.man b/app/xterm/xterm.man index 522132459..25ee7f57d 100644 --- a/app/xterm/xterm.man +++ b/app/xterm/xterm.man @@ -1,5 +1,5 @@ '\" t -.\" $XTermId: xterm.man,v 1.856 2022/02/22 09:11:42 tom Exp $ +.\" $XTermId: xterm.man,v 1.864 2022/10/08 00:17:27 tom Exp $ .\" .\" Copyright 1996-2021,2022 by Thomas E. Dickey .\" @@ -2260,11 +2260,14 @@ The default is \*(``false\*(''. .TP 8 .B "allowPasteControls\fP (class\fB AllowPasteControls\fP)" If true, allow control characters such as BEL and CAN to be pasted. -Formatting characters (tab, newline) are always allowed. +Formatting characters (tab, newline) are normally allowed, +unless suppressed via the \fBdisallowedPasteControls\fP resource. Other C0 control characters are suppressed unless this resource is enabled. The exact set of control characters (C0 and C1) depends upon whether UTF-8 encoding is used, -as well as the \fBallowC1Printable\fP resource. +as well as +the \fBallowC1Printable\fP +and \fBdisallowedPasteControls\fP resources. The default is \*(``false\*(''. .TP 8 .B "allowScrollLock\fP (class\fB AllowScrollLock\fP)" @@ -3195,12 +3198,11 @@ This overrides the \fBalternateScroll\fP resource. .RE .TP 8 .B "disallowedPasteControls\fP (class\fB DisallowedPasteControls\fP)" -The \fBallowPasteControls\fP resource is normally used to prevent -pasting C1 controls, as well as non-formatting C0 controls such -as the ASCII escape character. -Those characters are simply ignored. -This resource further extends the set of control characters +Use this resource to disallow pasting specific C0 control characters +when the \fBallowPasteControls\fP resource is false (i.e., the default). +This resource defines the set of control characters which cannot be pasted, converting each into a space. +Other C0 controls are pasted without change. .IP The resource value is a comma-separated list of names. \fI\*N\fP ignores capitalization. @@ -3476,6 +3478,10 @@ For example, XTerm*faceName: x:fixed,xft:Bitstream Vera Sans Mono .NE .IP +Two TrueType fonts can be specified in this way. +The first is the primary font; +the second acts as a manual override to the fontconfig fontset. +.IP If no \fBfaceName\fP resource is specified, or if there is no match for both TrueType normal and bold fonts, \fI\*n\fR uses the XLFD (bitmap) \fBfont\fP and related resources. @@ -3563,6 +3569,14 @@ Specifies the pointsize of the sixth alternative font. .B "faceSize7\fP (class\fB FaceSize7\fP)" Specifies the pointsize of the seventh alternative font. .TP 8 +.B "faintIsRelative\fP (class\fB FaintIsRelative\fP)" +Faint colors are derived from the current text color, e.g., the ANSI colors, +by scaling the red, green and blue components. +Use this resource to specify whether that is done relative to the +current background color, +or as an absolute value. +The default is \*(``false\*(''. +.TP 8 .B "fastScroll\fP (class\fB FastScroll\fP)" Modifies the effect of jump scroll (\fBjumpScroll\fP) by suppressing screen refreshes @@ -3962,8 +3976,9 @@ which change character sets. The default is \*(``B\*('', which corresponds to US ASCII. .TP 8 .B "limitFontsets\fP (class\fB LimitFontsets\fP)" -Limits the number of TrueType fallback fonts (i.e., fontset) which can be used. +Limits the number of TrueType fallback fonts (i.e., fontset) which can be tested. The default is \*(``50\*(''. +No more than \*(``255\*('' will be scanned. .IP This limits the number of fallback fonts which \fI\*n\fP uses to display characters. @@ -5113,7 +5128,10 @@ If \fI\*n\fR is configured to support SIXEL graphics, this resource tells it whether to scroll up one line at a time when sixels would be written past the bottom line on the window. -The default is \*(``false\*('' which enables scrolling. +The default is \*(``true\*('' which enables scrolling. +.IP +Sixel scrolling is the opposite of DEC Sixel Display Mode (DECSDM): +when one is on, the other is off. .TP 8 .B "sixelScrollsRight\fP (class\fB SixelScrollsRight\fP)" If \fI\*n\fR is configured to support SIXEL graphics, @@ -5477,6 +5495,24 @@ draw normal text. If no double-width font is found, it will improvise, by stretching the normal font. .TP 8 +.B "xftMaxGlyphMemory\fP (class\fB XftMaxGlyphMemory\fP)" +Set the Xft library's limit on glyph memory (typically 4Mb). +When it reaches this limit, it discards \*(``randomly chosen\*('' +glyphs to make room for new ones. +The default is \*(``0\*('' to use Xft's default value. +.TP 8 +.B "xftMaxUnrefFonts\fP (class\fB XftMaxUnrefFonts\fP)" +Set the Xft library's limit on fonts which have been loaded (typically 16), +e.g., matching patterns for fallback searches, +but are not actually used. +The default is \*(``0\*('' to use Xft's default value. +.TP 8 +.B "xftTrackMemUsage\fP (class\fB XftTrackMemUsage\fP)" +Enables glyph memory tracking (introduced in Xft 2.3.5), +which allows Xft to efficiently discard obsolete data when running +short of memory. +The default is \*(``true\*(''. +.TP 8 .B "ximFont\fP (class\fB XimFont\fP)" This option specifies the font to be used for displaying the preedit string in the \*(``OverTheSpot\*('' input method. @@ -6661,15 +6697,29 @@ This corresponds to the \fB\-ai\fP option and the \fBactiveIcon\fP resource. . .TP .B Sixel Scrolling\fP (resource \fBsixelScrolling\fP) +This corresponds to the \fBsixelScrolling\fP resource. +It can also be turned off and on using the private mode DECSDM +(Sixel Display Mode). +.RS +.bP When enabled, -sixel graphics are positioned at the current text cursor location, scroll -the image vertically if larger than the screen, and leave the text cursor -at the start of the next complete line after the image when returning to text -mode (this is the default). +\fI\*n\fR draws sixel graphics at the current text cursor location, +scrolling the image vertically if it is larger than the screen, +and leaving the text cursor +at the same column in the next complete line after the image when +returning to text mode +.IP +This is the default, +which corresponds to the \fIreset\fP state of DECSDM. +.bP When disabled, -sixel graphics are positioned at the upper left of the screen, are -cropped to fit the screen, and do not affect the text cursor location. -This corresponds to the \fBsixelScrolling\fP resource. +\fI\*n\fR draws sixel graphics starting at the upper left of the screen, +cropping to fit the screen, +and does not alter the text cursor location. +.IP +This corresponds to the \fIset\fP state of DECSDM. +.RE +.IP There is no corresponding command-line option. . .TP @@ -8918,7 +8968,7 @@ Steve Pitschke (Stellar), Ron Newman (MIT-Athena), Jim Fulton (MIT X Consortium), Dave Serisky (HP), Jonathan Kamens (MIT-Athena). .PP Beginning with XFree86, there were far more identifiable contributors. -The \fITHANKS\fP file in \fI\*n\fP's source lists 234 in August 2021. +The \fITHANKS\fP file in \fI\*n\fP's source lists 243 in June 2022. Keep in mind these: Jason Bacon, Jens Schweikhardt, diff --git a/app/xterm/xtermcfg.h b/app/xterm/xtermcfg.h index 2235bef18..a18db09ad 100644 --- a/app/xterm/xtermcfg.h +++ b/app/xterm/xtermcfg.h @@ -84,6 +84,7 @@ /* #undef HAVE_LIB_XAWPLUS */ /* CF_X_ATHENA(--with-XawPlus) */ #define HAVE_LIB_XCURSOR 1 /* AC_CHECK_LIB(Xcursor) */ #define HAVE_MKDTEMP 1 /* AC_CHECK_FUNCS(mkdtemp) */ +#define HAVE_MKSTEMP /* CF_MKSTEMP */ /* #undef HAVE_NCURSES_CURSES_H */ /* AC_CHECK_HEADERS(ncurses/curses.h) */ /* #undef HAVE_NCURSES_TERM_H */ /* AC_CHECK_HEADERS(ncurses/term.h) */ #define HAVE_PATHS_H 1 /* CF_LASTLOG */ @@ -98,6 +99,7 @@ #define HAVE_SETPGID /* AC_CHECK_FUNCS(setpgid) */ #define HAVE_STDINT_H 1 /* AC_PROG_CC_STDC */ #define HAVE_STDLIB_H 1 /* AC_CHECK_HEADERS(stdlib.h) */ +#undef HAVE_STDNORETURN_H /* CF_C11_NORETURN */ #define HAVE_STRFTIME 1 /* AC_CHECK_FUNCS(strftime) */ /* #undef HAVE_SYS_TIME_H */ /* AC_HEADER_TIME */ #define HAVE_SYS_TTYDEFAULTS_H 1 /* AC_CHECK_HEADERS(sys/ttydefaults.h) */ @@ -156,6 +158,7 @@ /* #define OPT_DEC_RECTOPS */ /* CF_ARG_DISABLE(rectangles) */ #define OPT_DIRECT_COLOR 1 /* CF_ARG_ENABLE(direct-color) */ /* #undef OPT_DOUBLE_BUFFER */ /* CF_ARG_ENABLE(double-buffer) */ +#define OPT_EXEC_SELECTION 0 /* CF_ARG_ENABLE(exec-selection) */ /* #undef OPT_EXEC_XTERM */ /* CF_ARG_ENABLE(exec-xterm) */ /* #undef OPT_GRAPHICS */ /* CF_ARG_ENABLE(graphics) */ /* #undef OPT_HIGHLIGHT_COLOR */ /* CF_ARG_DISABLE(highlighting) */ @@ -199,6 +202,7 @@ /* #undef PROCFS_ROOT */ /* CF_ARG_ENABLE(exec-xterm) */ #define SCROLLBAR_RIGHT 1 /* CF_ARG_ENABLE(rightbar) */ #define SIG_ATOMIC_T volatile sig_atomic_t /* CF_SIG_ATOMIC_T */ +#undef STDC_NORETURN /* CF_C11_NORETURN */ /* #undef SVR4 */ /* CF_SVR4, imake */ /* #undef SYSV */ /* CF_SYSV, imake */ #define TIME_WITH_SYS_TIME 1 /* AC_HEADER_TIME */ diff --git a/app/xterm/xtermcfg.hin b/app/xterm/xtermcfg.hin index 65eaae357..d9344ecf8 100644 --- a/app/xterm/xtermcfg.hin +++ b/app/xterm/xtermcfg.hin @@ -1,4 +1,4 @@ -/* $XTermId: xtermcfg.hin,v 1.225 2022/02/13 13:50:45 tom Exp $ */ +/* $XTermId: xtermcfg.hin,v 1.227 2022/09/11 19:26:01 tom Exp $ */ /* * Copyright 1997-2021,2022 by Thomas E. Dickey @@ -84,6 +84,7 @@ #undef HAVE_LIB_XAWPLUS /* CF_X_ATHENA(--with-XawPlus) */ #undef HAVE_LIB_XCURSOR /* AC_CHECK_LIB(Xcursor) */ #undef HAVE_MKDTEMP /* AC_CHECK_FUNCS(mkdtemp) */ +#undef HAVE_MKSTEMP /* CF_MKSTEMP */ #undef HAVE_NCURSES_CURSES_H /* AC_CHECK_HEADERS(ncurses/curses.h) */ #undef HAVE_NCURSES_TERM_H /* AC_CHECK_HEADERS(ncurses/term.h) */ #undef HAVE_PATHS_H /* CF_LASTLOG */ @@ -157,6 +158,7 @@ #undef OPT_DEC_RECTOPS /* CF_ARG_DISABLE(rectangles) */ #undef OPT_DIRECT_COLOR /* CF_ARG_ENABLE(direct-color) */ #undef OPT_DOUBLE_BUFFER /* CF_ARG_ENABLE(double-buffer) */ +#undef OPT_EXEC_SELECTION /* CF_ARG_ENABLE(exec-selection) */ #undef OPT_EXEC_XTERM /* CF_ARG_ENABLE(exec-xterm) */ #undef OPT_GRAPHICS /* CF_ARG_ENABLE(graphics) */ #undef OPT_HIGHLIGHT_COLOR /* CF_ARG_DISABLE(highlighting) */ |