# ------------------------------------------------------------------------------
# charproc.c | 8 +--
# doublechr.c | 79 +++++++++++++++++++++++++++++++++++++-
# fontutils.c | 112 ++++++++++++++++++++++++++++++++++++-------------------
# fontutils.h | 4 +
# main.c | 10 ++--
# ptyx.h | 10 +++-
# resize.c | 4 -
# util.c | 54 +++++++++++++++++++++++---
# version.h | 2
# xterm.h | 5 +-
# xterm.log.html | 32 +++++++++++++++
# xterm.man | 4 +
# 12 files changed, 257 insertions, 67 deletions
# ------------------------------------------------------------------------------
Index: charproc.c
--- xterm-88+/charproc.c Sun Oct 25 13:31:39 1998
+++ xterm-89/charproc.c Wed Nov 18 20:35:49 1998
@@ -4419,7 +4419,7 @@
}
}
- TRACE(("%s @%d, calling drawXtermText\n", __FILE__, __LINE__))
+ TRACE(("%s @%d, ShowCursor calling drawXtermText\n", __FILE__, __LINE__))
drawXtermText(screen, flags, currentGC,
x = CurCursorX(screen, screen->cur_row, screen->cur_col),
@@ -4485,11 +4485,11 @@
if (c == 0)
c = ' ';
- TRACE(("%s @%d, calling drawXtermText\n", __FILE__, __LINE__))
+ TRACE(("%s @%d, HideCursor calling drawXtermText\n", __FILE__, __LINE__))
drawXtermText(screen, flags, currentGC,
- CursorX(screen, screen->cursor_col),
+ CurCursorX(screen, screen->cursor_row, screen->cursor_col),
CursorY(screen, screen->cursor_row),
- curXtermChrSet(screen->cur_row),
+ curXtermChrSet(screen->cursor_row),
&c, 1);
screen->cursor_state = OFF;
Index: doublechr.c
--- xterm-88+/doublechr.c Sun Oct 25 13:31:39 1998
+++ xterm-89/doublechr.c Fri Nov 20 06:22:59 1998
@@ -36,6 +36,7 @@
#include <xterm.h>
#include <data.h>
+#include <fontutils.h>
/*
* The first column is all that matters for double-size characters (since the
@@ -50,10 +51,19 @@
{
register TScreen *screen = &term->screen;
int curcol = screen->cur_col;
+ int currow = screen->cur_row;
int len = screen->max_col + 1;
int width = len;
+ unsigned oldChrSet = SCRN_BUF_CSETS(screen, currow)[0];
- TRACE(("repaint_line(%2d,%2d) (%d)\n", screen->cur_row, screen->cur_col, newChrSet))
+ /*
+ * Ignore repetition.
+ */
+ if (oldChrSet == newChrSet)
+ return;
+
+ TRACE(("repaint_line(%2d,%2d) (%d)\n", currow, screen->cur_col, newChrSet))
+ HideCursor();
/* If switching from single-width, keep the cursor in the visible part
* of the line.
@@ -64,11 +74,24 @@
curcol = width;
}
+ /*
+ * ScrnRefresh won't paint blanks for us if we're switching between a
+ * single-size and double-size font.
+ */
+ if (CSET_DOUBLE(oldChrSet) != CSET_DOUBLE(newChrSet)) {
+ ClearCurBackground(
+ screen,
+ CursorY (screen, currow),
+ CurCursorX (screen, currow, 0),
+ FontHeight(screen),
+ len * CurFontWidth(screen,currow));
+ }
+
/* FIXME: do VT220 softchars allow double-sizes? */
- memset(SCRN_BUF_CSETS(screen, screen->cur_row), newChrSet, len);
+ memset(SCRN_BUF_CSETS(screen, currow), newChrSet, len);
screen->cur_col = 0;
- ScrnRefresh (screen, screen->cur_row, 0, 1, len, True);
+ ScrnRefresh (screen, currow, 0, 1, len, True);
screen->cur_col = curcol;
}
#endif
@@ -106,3 +129,53 @@
repaint_line(CSET_DWL);
#endif
}
+
+
+#if OPT_DEC_CHRSET
+/*
+ * Lookup/cache a GC for the double-size character display. We save up to
+ * NUM_CHRSET values.
+ */
+GC
+xterm_DoubleGC(unsigned chrset, unsigned flags, GC old_gc)
+{
+ XGCValues gcv;
+ register TScreen *screen = &term->screen;
+ unsigned long mask = (GCForeground | GCBackground | GCFont);
+ int n = (chrset % NUM_CHRSET);
+ char *name = xtermSpecialFont(flags, chrset);
+
+ if (name == 0)
+ return 0;
+
+ if (screen->double_fn[n] != 0) {
+ if (!strcmp(screen->double_fn[n], name)) {
+ if (screen->double_fs[n] != 0) {
+ XCopyGC(screen->display, old_gc, ~GCFont, screen->double_gc[n]);
+ return screen->double_gc[n];
+ }
+ }
+ }
+ screen->double_fn[n] = name;
+
+ if (screen->double_fs[n] != 0) {
+ XFreeFont(screen->display, screen->double_fs[n]);
+ screen->double_fs[n] = 0;
+ }
+
+ TRACE(("xterm_DoubleGC %s %d: %s\n", flags&BOLD ? "BOLD" : "NORM", chrset, name))
+
+ if ((screen->double_fs[n] = XLoadQueryFont (screen->display, name)) == 0)
+ return 0;
+ TRACE(("-> OK\n"))
+
+ gcv.graphics_exposures = TRUE; /* default */
+ gcv.font = screen->double_fs[n]->fid;
+ gcv.foreground = screen->foreground;
+ gcv.background = term->core.background_pixel;
+
+ screen->double_gc[n] = XCreateGC (screen->display, TextWindow(screen), mask, &gcv);
+ XCopyGC(screen->display, old_gc, ~GCFont, screen->double_gc[n]);
+ return screen->double_gc[n];
+}
+#endif
Index: fontutils.c
--- xterm-88+/fontutils.c Sun Nov 1 14:10:30 1998
+++ xterm-89/fontutils.c Wed Nov 18 20:25:57 1998
@@ -121,6 +121,7 @@
get_font_name_props(Display *dpy, XFontStruct *fs)
{
static FontNameProperties props;
+ static char *last_name;
register XFontProp *fp;
register int i;
@@ -141,6 +142,13 @@
return 0;
/*
+ * XGetAtomName allocates memory - don't leak
+ */
+ if (last_name != 0)
+ XFree(last_name);
+ last_name = name;
+
+ /*
* Now split it up into parts and put them in
* their places. Since we are using parts of
* the original string, we must not free the Atom Name
@@ -222,59 +230,86 @@
return ret;
}
-#if 0
#ifdef OPT_DEC_CHRSET
/*
* Take the given font props and try to make a well formed font name specifying
- * the same base font but changed depending on the given attributes and lflags.
+ * the same base font but changed depending on the given attributes and chrset.
*
* For double width fonts, we just double the X-resolution, for double height
* fonts we double the pixel-size and Y-resolution
*/
char *
-special_font_name(FontNameProperties *props, unsigned char atts,
- LineFlagsElem lflags)
+xtermSpecialFont(unsigned atts, unsigned chrset)
{
- char tmp[MAX_FONTNAME];
- char *ret;
+#if OPT_TRACE
+ static char old_spacing[80];
+ static FontNameProperties old_props;
+#endif
+ TScreen *screen = &term->screen;
+ FontNameProperties *props;
+ char tmp[MAX_FONTNAME];
+ char *ret;
+ char *width;
+ int pixel_size;
+ int res_x;
+ int res_y;
+
+ props = get_font_name_props(screen->display, screen->fnt_norm);
+ if (props == 0)
+ return 0;
+
+ pixel_size = props->pixel_size;
+ res_x = props->res_x;
+ res_y = props->res_y;
+ if (atts & BOLD)
+ width = "bold";
+ else
+ width = props->width;
+
+ if (CSET_DOUBLE(chrset))
+ res_x *= 2;
+
+ if (chrset == CSET_DHL_TOP
+ || chrset == CSET_DHL_BOT) {
+ res_y *= 2;
+ pixel_size *= 2;
+ }
- char *width;
- int pixel_size = props->pixel_size;
- int res_x = props->res_x;
- int res_y = props->res_y;
-
- if (atts & ATT_BOLD)
- width = "bold";
- else
- width = props->width;
-
- if (lflags & LINE_D_WIDE)
- res_x *= 2;
-
- if (lflags & (LINE_D_UPPER | LINE_D_LOWER)) {
- res_x *= 2;
- res_y *= 2;
- pixel_size *= 2;
- }
+#if OPT_TRACE
+ if (old_props.res_x != res_x
+ || old_props.res_x != res_y
+ || old_props.pixel_size != pixel_size
+ || strcmp(old_props.spacing, props->spacing)) {
+ TRACE(("xtermSpecialFont(atts = %#x, chrset = %#x)\n", atts, chrset))
+ TRACE(("res_x = %d\n", res_x))
+ TRACE(("res_y = %d\n", res_y))
+ TRACE(("point_size = %s\n", props->point_size))
+ TRACE(("pixel_size = %d\n", pixel_size))
+ TRACE(("spacing = %s\n", props->spacing))
+ old_props.res_x = res_x;
+ old_props.res_x = res_y;
+ old_props.pixel_size = pixel_size;
+ old_props.spacing = strcpy(old_spacing, props->spacing);
+ }
+#endif
- sprintf(tmp, "%s-%s-%s-%d-%s-%d-%d-%s-*-%s",
- props->beginning,
- width,
- props->middle,
- pixel_size,
- props->point_size,
- res_x,
- res_y,
- props->spacing,
- props->end);
+ sprintf(tmp, "%s-%s-%s-%d-%s-%d-%d-%s-*-%s",
+ props->beginning,
+ width,
+ props->middle,
+ pixel_size,
+ props->point_size,
+ res_x,
+ res_y,
+ props->spacing,
+ props->end);
- ret = XtMalloc(strlen(tmp) + 1);
- strcpy(ret, tmp);
+ ret = XtMalloc(strlen(tmp) + 1);
+ strcpy(ret, tmp);
- return ret;
+ return ret;
}
#endif /* OPT_DEC_CHRSET */
-#endif
/*
* Double-check the fontname that we asked for versus what the font server
@@ -330,6 +365,7 @@
Bool doresize,
int fontnum)
{
+ /* FIXME: use XFreeFontInfo */
FontNameProperties *fp;
XFontStruct *nfs = NULL;
XFontStruct *bfs = NULL;
Index: fontutils.h
--- xterm-88+/fontutils.h Sun Oct 25 13:31:39 1998
+++ xterm-89/fontutils.h Tue Nov 3 21:40:32 1998
@@ -43,4 +43,8 @@
extern void xtermUpdateFontInfo (TScreen *screen, Bool doresize);
extern void xtermSetCursorBox (TScreen *screen);
+#if OPT_DEC_CHRSET
+extern char *xtermSpecialFont(unsigned atts, unsigned chrset);
+#endif
+
#endif /* included_fontutils_h */
Index: main.c
--- xterm-88+/main.c Sun Oct 25 13:31:39 1998
+++ xterm-89/main.c Fri Nov 20 06:23:47 1998
@@ -3122,7 +3122,7 @@
sizeof(utmp.ut_name));
utmp.ut_pid = getpid();
-#if defined(SVR4) || defined(SCO325) || (defined(linux) && __GLIBC__ >= 2)
+#if defined(SVR4) || defined(SCO325) || (defined(linux) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
utmp.ut_session = getsid(0);
utmp.ut_xtime = time ((time_t *) 0);
utmp.ut_tv.tv_usec = 0;
@@ -3138,7 +3138,7 @@
if (term->misc.login_shell)
updwtmpx(WTMPX_FILE, &utmp);
#else
-#if defined(linux) && __GLIBC__ >= 2
+#if defined(linux) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
if (term->misc.login_shell)
updwtmp(etc_wtmp, &utmp);
#else
@@ -3899,7 +3899,7 @@
#endif
char* ptyname;
char* ptynameptr = 0;
-#if defined(WTMP) && !defined(SVR4) && !(defined(linux) && __GLIBC__ >= 2)
+#if defined(WTMP) && !defined(SVR4) && !(defined(linux) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
int fd; /* for /etc/wtmp */
int i;
#endif
@@ -3931,7 +3931,7 @@
/* write it out only if it exists, and the pid's match */
if (utptr && (utptr->ut_pid == screen->pid)) {
utptr->ut_type = DEAD_PROCESS;
-#if defined(SVR4) || defined(SCO325) || (defined(linux) && __GLIBC__ >= 2)
+#if defined(SVR4) || defined(SCO325) || (defined(linux) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0))
utptr->ut_session = getsid(0);
utptr->ut_xtime = time ((time_t *) 0);
utptr->ut_tv.tv_usec = 0;
@@ -3945,7 +3945,7 @@
if (term->misc.login_shell)
updwtmpx(WTMPX_FILE, utptr);
#else
-#if defined(linux) && __GLIBC__ >= 2
+#if defined(linux) && __GLIBC__ >= 2 && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
strncpy (utmp.ut_line, utptr->ut_line, sizeof (utmp.ut_line));
if (term->misc.login_shell)
updwtmp(etc_wtmp, utptr);
Index: ptyx.h
--- xterm-88+/ptyx.h Sun Oct 25 13:31:39 1998
+++ xterm-89/ptyx.h Fri Nov 20 06:20:11 1998
@@ -421,15 +421,16 @@
#if OPT_DEC_CHRSET
#define if_OPT_DEC_CHRSET(code) code
- /* Use 3 bits for encoding the double high/wide sense of characters */
+ /* Use 2 bits for encoding the double high/wide sense of characters */
#define CSET_SWL 0
#define CSET_DHL_TOP 1
#define CSET_DHL_BOT 2
-#define CSET_DWL 4
+#define CSET_DWL 3
+#define NUM_CHRSET 4
/* Use remaining bits for encoding the other character-sets */
#define CSET_NORMAL(code) ((code) == CSET_SWL)
#define CSET_DOUBLE(code) (!CSET_NORMAL(code) && !CSET_EXTEND(code))
-#define CSET_EXTEND(code) ((code) >= 8)
+#define CSET_EXTEND(code) ((code) > CSET_DWL)
#define CurMaxCol(screen, row) \
(CSET_DOUBLE(SCRN_BUF_CSETS(screen, row)[0]) \
? (screen->max_col / 2) \
@@ -627,6 +628,9 @@
#endif
#if OPT_DEC_CHRSET
Char chrset; /* character-set index & code */
+ XFontStruct * double_fs[NUM_CHRSET];
+ GC double_gc[NUM_CHRSET];
+ char * double_fn[NUM_CHRSET];
#endif
int border; /* inner border */
Cursor arrow; /* arrow cursor */
Index: resize.c
--- xterm-88+/resize.c Sun Oct 25 13:31:39 1998
+++ xterm-89/resize.c Fri Nov 20 06:38:44 1998
@@ -536,10 +536,8 @@
setname, termcap);
#endif /* USE_TERMCAP */
#ifdef USE_TERMINFO
-#ifndef SVR4
printf ("%sCOLUMNS=%d;\nLINES=%d;\nexport COLUMNS LINES;\n",
setname, cols, rows);
-#endif /* !SVR4 */
#endif /* USE_TERMINFO */
} else { /* not Bourne shell */
@@ -550,10 +548,8 @@
setname, termcap);
#endif /* USE_TERMCAP */
#ifdef USE_TERMINFO
-#ifndef SVR4
printf ("set noglob;\n%ssetenv COLUMNS '%d';\nsetenv LINES '%d';\nunset noglob;\n",
setname, cols, rows);
-#endif /* !SVR4 */
#endif /* USE_TERMINFO */
}
exit(0);
Index: util.c
--- xterm-88+/util.c Sun Oct 25 13:31:39 1998
+++ xterm-89/util.c Tue Nov 3 21:40:32 1998
@@ -1310,17 +1310,57 @@
{
#if OPT_DEC_CHRSET
if (CSET_DOUBLE(chrset)) {
- Char *temp = (Char *) malloc(2 * len);
- int n = 0;
+ GC gc2 = xterm_DoubleGC(chrset, flags, gc);
+
TRACE(("DRAWTEXT%c[%4d,%4d] (%d) %d:%.*s\n",
screen->cursor_state == OFF ? ' ' : '*',
y, x, chrset, len, len, text))
- while (len--) {
- temp[n++] = *text++;
- temp[n++] = ' ';
+
+ if (gc2 != 0) { /* draw actual double-sized characters */
+ XRectangle rect, *rp = ▭
+ Cardinal nr = 1;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = 2 * len * FontWidth(screen);
+ rect.height = FontHeight(screen);
+
+ switch (chrset) {
+ case CSET_DHL_TOP:
+ rect.y = - (rect.height / 2);
+ y -= rect.y;
+ break;
+ case CSET_DHL_BOT:
+ rect.y = (rect.height / 2);
+ y -= rect.y;
+ break;
+ default:
+ nr = 0;
+ break;
+ }
+
+ if (nr)
+ XSetClipRectangles(screen->display, gc2,
+ x, y, rp, nr, YXBanded);
+ else
+ XSetClipMask(screen->display, gc2, None);
+
+ x = drawXtermText(screen, flags, gc2,
+ x, y, 0, text, len);
+ x += len * FontWidth(screen);
+
+ TRACE(("drewtext [%4d,%4d]\n", y, x))
+
+ } else { /* simulate double-sized characters */
+ Char *temp = (Char *) malloc(2 * len);
+ int n = 0;
+ while (len--) {
+ temp[n++] = *text++;
+ temp[n++] = ' ';
+ }
+ x = drawXtermText(screen, flags, gc, x, y, 0, temp, n);
+ free(temp);
}
- x = drawXtermText(screen, flags, gc, x, y, 0, temp, n);
- free(temp);
return x;
}
#endif
Index: version.h
--- xterm-88+/version.h Sun Nov 1 14:10:30 1998
+++ xterm-89/version.h Thu Nov 19 06:43:45 1998
@@ -6,4 +6,4 @@
* version of xterm has been built. The number in parentheses is my patch
* number (T.Dickey).
*/
-#define XTERM_VERSION "XFree86 3.9Nk(88)"
+#define XTERM_VERSION "XFree86 3.9Nm(89)"
Index: xterm.h
--- xterm-88+/xterm.h Sun Oct 25 13:31:39 1998
+++ xterm-89/xterm.h Fri Nov 20 06:21:03 1998
@@ -36,8 +36,8 @@
#ifndef X_NOT_STDC_ENV
#define HAVE_STDLIB_H 1
-#else
#define DECL_ERRNO 1
+#else
#define size_t int
#define time_t long
#endif
@@ -167,6 +167,9 @@
extern void xterm_DECDHL (Bool top);
extern void xterm_DECSWL (void);
extern void xterm_DECDWL (void);
+#if OPT_DEC_CHRSET
+extern GC xterm_DoubleGC(unsigned chrset, unsigned flags, GC old_gc);
+#endif
/* input.c */
extern void Input (TKeyboard *keyboard, TScreen *screen, XKeyEvent *event, Bool eightbit);
Index: xterm.log.html
--- xterm-88+/xterm.log.html Sun Nov 1 14:10:30 1998
+++ xterm-89/xterm.log.html Fri Nov 20 06:48:21 1998
@@ -41,6 +41,7 @@
xc/programs/Xserver/hw/xfree86).
<UL>
+<LI><A HREF="#xterm_89">Patch #89 - 1998/11/20 - XFree86 3.9Nm</A>
<LI><A HREF="#xterm_88">Patch #88 - 1998/10/31 - XFree86 3.9Nk and 3.3.2h</A>
<LI><A HREF="#xterm_87">Patch #87 - 1998/10/21 - XFree86 3.9Nj and 3.3.2f</A>
<LI><A HREF="#xterm_86">Patch #86 - 1998/10/14 - XFree86 3.9Nj and 3.3.2e</A>
@@ -131,6 +132,37 @@
<LI><A HREF="#xterm_02">Patch #2 - 1996/1/7</A>
<LI><A HREF="#xterm_01">Patch #1 - 1996/1/6</A>
</UL>
+
+<H1><A NAME="xterm_89">Patch #89 - 1998/11/20 - XFree86 3.9Nm</A></H1>
+This patch completes the implementation of double-sized character support
+for the VT100 emulation, and fixes a few minor bugs:
+
+<ul>
+<li>corrected the cursor position in HideCursor, which did not multiply
+the column by two when in doublesize mode.
+This bug, which did not appear in normal use,
+dates back to my original <a href="#xterm_44">changes</a> to partly implement
+double-sized characters.
+I noticed it when cat'ing a typescript from vttest's double-sized character
+test.
+<li>ensure that the current line is repainted when switching between
+single and double width characters.
+<li>reduce the number of bits used for double-sized character coding
+from 3 to 2, to make more room for soft-font codes.
+<li>copy newer ifdef's from the XFree86 3.3.3 release's main.c,
+which address details of glibc and powerpc.
+<li>moved definition of DECL_ERRNO in xterm.h to match XFree86 3.3.3
+<li>modify <em>resize</em> to remove the ifdef on SVr4 that suppressed
+printing the script for $LINES and $COLUMNS.
+Solaris' resize utility does this; suppressing the behavior is unnecessary.
+</ul>
+I tested the double-sized characters using vttest and the xfsft patch.
+These fonts worked reasonably well:
+<pre>
+ -bitstream-courier-medium-r-normal--0-0-0-0-m-0-iso8859-1
+ 9x15
+</pre>
+The iso8859 font does not include box characters, of course, but looks good.
<H1><A NAME="xterm_88">Patch #88 - 1998/10/31 - XFree86 3.9Nk and 3.3.2h</A></H1>
This refines my #85 patch by checking for a case where the font server
Index: xterm.man
--- xterm-88+/xterm.man Sun Oct 11 13:00:35 1998
+++ xterm-89/xterm.man Wed Nov 11 19:44:01 1998
@@ -58,7 +58,9 @@
.SH EMULATIONS
The VT102 emulation is fairly complete, but does not support
autorepeat.
-Double-size and blinking characters are partially implemented;
+Double-size characters are displayed properly if your font server supports
+scalable fonts.
+Blinking characters are partially implemented;
the emulation is functional but does not have the appearance of a real VT102.
The VT220 emulation does not support soft fonts, it is otherwise complete.
.IR Termcap (5)