XFree86 3.1.2Ec - xterm patch #22 - 1996/7/26 - T.Dickey I looked more closely at my "double-negative" and realized that I had been confused by the default color scheme (black on white) in combination with reverse video. However, I did see that the original_fg and original_bg data weren't really used - so I removed that logic. Also: + during initialization, check if ANSI colors are set with non fg/bg values, disable color mode if not. This makes xterm tolerant of applications that allocate the whole color map. + implemented blinking cursor (default is _off_) To do (time permitting ;-): + implement ech/ech1 + implement "protected" characters. -------------------------------------------------------------------------------- charproc.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- ptyx.h | 7 ++- util.c | 7 --- xterm.man | 15 ++++++-- 4 files changed, 106 insertions, 27 deletions -------------------------------------------------------------------------------- Index: charproc.c --- xterm-21+/charproc.c Fri Jul 26 07:05:47 1996 +++ xterm-22/charproc.c Sat Jul 27 15:57:12 1996 @@ -121,9 +121,12 @@ static int finput PROTO((void)); static int in_put PROTO((void)); static int set_character_class PROTO((char *s)); +static void BlinkCursor PROTO(( XtPointer closure, XtIntervalId* id)); static void DoSetSelectedFont PROTO_XT_SEL_CB_ARGS; static void FromAlternate PROTO((TScreen *screen)); static void RequestResize PROTO((XtermWidget termw, int rows, int cols, int text)); +static void StartBlinking PROTO((TScreen *screen)); +static void StopBlinking PROTO((TScreen *screen)); static void SwitchBufs PROTO((TScreen *screen)); static void ToAlternate PROTO((TScreen *screen)); static void VTGraphicsOrNoExpose PROTO((XEvent *event)); @@ -136,8 +139,8 @@ static void bitset PROTO((unsigned *p, int mask)); static void dotext PROTO((TScreen *screen, unsigned flags, int charset, Char *buf, Char *ptr, unsigned fg, unsigned bg)); static void dpmodes PROTO((XtermWidget termw, void (*func)(unsigned *p, int mask))); -static void restoremodes PROTO((XtermWidget termw)); static void report_win_label PROTO((TScreen *screen, int code, XTextProperty *text, Status ok)); +static void restoremodes PROTO((XtermWidget termw)); static void savemodes PROTO((XtermWidget termw)); static void set_vt_box PROTO((TScreen *screen)); static void unparseputn PROTO((unsigned int n, int fd)); @@ -160,6 +163,7 @@ #define XtNcurses "curses" #define XtNhpLowerleftBugCompat "hpLowerleftBugCompat" #define XtNcursorColor "cursorColor" +#define XtNcursorBlinkTime "cursorBlinkTime" #define XtNcutNewline "cutNewline" #define XtNcutToBeginningOfLine "cutToBeginningOfLine" #define XtNeightBitInput "eightBitInput" @@ -233,6 +237,7 @@ #define XtCHpLowerleftBugCompat "HpLowerleftBugCompat" #define XtCCutNewline "CutNewline" #define XtCCutToBeginningOfLine "CutToBeginningOfLine" +#define XtCCursorBlinkTime "CursorBlinkTime" #define XtCEightBitInput "EightBitInput" #define XtCEightBitOutput "EightBitOutput" #define XtCGeometry "Geometry" @@ -308,6 +313,7 @@ static int defaultScrollLines = SCROLLLINES; static int defaultNMarginBell = N_MARGINBELL; static int defaultMultiClickTime = MULTICLICKTIME; +static int defaultBlinkTime = 0; static int defaultBellSuppressTime = BELLSUPPRESSMSEC; static char * _Font_Selected_ = "yes"; /* string is arbitrary */ @@ -441,6 +447,9 @@ {XtNcursorColor, XtCForeground, XtRPixel, sizeof(Pixel), XtOffsetOf(XtermWidgetRec, screen.cursorcolor), XtRString, "XtDefaultForeground"}, +{XtNcursorBlinkTime, XtCCursorBlinkTime, XtRInt, sizeof(int), + XtOffsetOf(XtermWidgetRec, screen.cursor_blink), + XtRInt, (XtPointer) &defaultBlinkTime}, {XtNeightBitInput, XtCEightBitInput, XtRBoolean, sizeof(Boolean), XtOffsetOf(XtermWidgetRec, screen.input_eight_bits), XtRBoolean, (XtPointer) &defaultTRUE}, @@ -1735,7 +1744,10 @@ * The blocking is optional, because it tends to increase the load * on the host. */ - if (XtAppPending(app_con)) + if (XtAppPending(app_con) + || (screen->cursor_blink > 0 + && (screen->select || screen->always_highlight)) + || screen->cursor_state == BLINKED_OFF) select_timeout.tv_usec = 0; else select_timeout.tv_usec = 50000; @@ -2610,6 +2622,7 @@ screen->cursor_state = OFF; screen->cursor_set = ON; + StartBlinking(screen); bcnt = 0; bptr = buffer; @@ -2623,6 +2636,7 @@ bptr = buffer; if(!setjmp(VTend)) VTparse(); + StopBlinking(screen); HideCursor(); screen->cursor_set = OFF; } @@ -2808,6 +2822,7 @@ XtermWidget request = (XtermWidget) wrequest; XtermWidget new = (XtermWidget) wnew; int i; + Boolean color_ok; /* Zero out the entire "screen" component of "new" widget, then do field-by-field assigment of "screen" fields @@ -2819,6 +2834,7 @@ new->screen.hp_ll_bc = request->screen.hp_ll_bc; new->screen.foreground = request->screen.foreground; new->screen.cursorcolor = request->screen.cursorcolor; + new->screen.cursor_blink = request->screen.cursor_blink; new->screen.border = request->screen.border; new->screen.jumpscroll = request->screen.jumpscroll; #ifdef ALLOWLOGGING @@ -2858,20 +2874,24 @@ new->screen.menu_font_number = fontMenu_fontdefault; #if OPT_ISO_COLORS - new->num_ptrs = request->screen.colorMode ? 4 : 2; new->screen.colorMode = request->screen.colorMode; new->screen.colorULMode = request->screen.colorULMode; new->screen.colorBDMode = request->screen.colorBDMode; - for (i = 0; i < MAXCOLORS; i++) { + for (i = 0, color_ok = False; i < MAXCOLORS; i++) { new->screen.Acolors[i] = request->screen.Acolors[i]; + if (new->screen.Acolors[i] != request->screen.foreground + && new->screen.Acolors[i] != request->core.background_pixel) + color_ok = True; } - if (request->misc.re_verse) { - new->screen.original_bg = request->screen.foreground; - new->screen.original_fg = request->core.background_pixel; - } else { - new->screen.original_fg = request->screen.foreground; - new->screen.original_bg = request->core.background_pixel; - } + /* If none of the colors are anything other than the foreground or + * background, we'll assume this isn't color, no matter what the colorMode + * resource says. (There doesn't seem to be any good way to determine if + * the resource lookup failed versus the user having misconfigured this). + */ + if (!color_ok) + new->screen.colorMode = False; + + new->num_ptrs = new->screen.colorMode ? 4 : 2; #endif /* OPT_ISO_COLORS */ new->screen.underline = request->screen.underline; @@ -3301,6 +3321,9 @@ GC currentGC; Boolean in_selection; + if (screen->cursor_state == BLINKED_OFF) + return; + if (eventMode != NORMAL) return; if (screen->cur_row - screen->topline > screen->max_row) @@ -3358,7 +3381,7 @@ } } - x = CursorX (screen, screen->cur_col); + x = CursorX(screen, screen->cur_col); y = CursorY(screen, screen->cur_row) + screen->fnt_norm->ascent; XDrawImageString(screen->display, TextWindow(screen), currentGC, @@ -3418,7 +3441,7 @@ if (c == 0) c = ' '; - x = CursorX (screen, screen->cursor_col); + x = CursorX(screen, screen->cursor_col); y = (((screen->cursor_row - screen->topline) * FontHeight(screen))) + screen->border; y = y+screen->fnt_norm->ascent; @@ -3432,6 +3455,61 @@ x, y+1, x + FontWidth(screen), y+1); screen->cursor_state = OFF; resetXtermGC(screen, flags, in_selection); +} + +static void +StartBlinking(screen) + TScreen *screen; +{ + if (screen->cursor_blink > 0 + && screen->cursor_timer == 0) { + unsigned long half = screen->cursor_blink / 2; + if (half == 0) /* wow! */ + half = 1; /* let's humor him anyway */ + screen->cursor_timer = XtAppAddTimeOut( + app_con, + half, + BlinkCursor, + screen); + } +} + +static void +StopBlinking(screen) + TScreen *screen; +{ + if (screen->cursor_blink > 0) + XtRemoveTimeOut(screen->cursor_timer); + screen->cursor_timer = 0; +} + +/* + * Blink the cursor by alternately showing/hiding cursor. We leave the timer + * running all the time (even though that's a little inefficient) to make the + * logic simple. + */ +static void +BlinkCursor(closure, id) /* XtTimerCallbackProc */ + XtPointer closure; + XtIntervalId* id; +{ + TScreen *screen = (TScreen *)closure; + + screen->cursor_timer = 0; + if (screen->cursor_state == ON) { + if(screen->select || screen->always_highlight) { + HideCursor(); + if (screen->cursor_state == OFF) + screen->cursor_state = BLINKED_OFF; + } + } else if (screen->cursor_state == BLINKED_OFF) { + screen->cursor_state = OFF; + ShowCursor(); + if (screen->cursor_state == OFF) + screen->cursor_state = BLINKED_OFF; + } + StartBlinking(screen); + xevents(); } void Index: ptyx.h --- xterm-21+/ptyx.h Fri Jul 26 07:05:47 1996 +++ xterm-22/ptyx.h Sat Jul 27 11:17:14 1996 @@ -357,8 +357,6 @@ Pixel mousecolorback; /* Mouse color background */ #if OPT_ISO_COLORS Pixel Acolors[MAXCOLORS]; /* ANSI color emulation */ - Pixel original_fg; /* reference for SGR reset fg */ - Pixel original_bg; /* reference for SGR reset bg */ Boolean colorMode; /* are we using color mode? */ Boolean colorULMode; /* use color for underline? */ Boolean colorBDMode; /* use color for bold? */ @@ -398,7 +396,9 @@ int enbolden; /* overstrike for bold font */ XPoint *box; /* draw unselected cursor */ - int cursor_state; /* ON or OFF */ + int cursor_state; /* ON, OFF, or BLINKED_OFF */ + int cursor_blink; /* blink-rate (0=off) msecs */ + XtIntervalId cursor_timer; /* timer-id for cursor-proc */ int cursor_set; /* requested state */ int cursor_col; /* previous cursor column */ int cursor_row; /* previous cursor row */ @@ -697,6 +697,7 @@ /* flags for cursors */ #define OFF 0 #define ON 1 +#define BLINKED_OFF 2 #define CLEAR 0 #define TOGGLE 1 Index: util.c --- xterm-21+/util.c Fri Jul 26 07:05:47 1996 +++ xterm-22/util.c Sat Jul 27 08:20:46 1996 @@ -1226,9 +1226,6 @@ ? term->screen.Acolors[color] : term->screen.foreground; - if (term->misc.re_verse && (fg == term->screen.original_fg)) - fg = term->screen.original_bg; - return fg; } @@ -1240,10 +1237,6 @@ Pixel bg = (flags & BG_COLOR) && (color >= 0) ? term->screen.Acolors[color] : term->core.background_pixel; - - if (term->misc.re_verse && (bg == term->screen.original_bg)) - bg = term->screen.original_fg; - return bg; } Index: xterm.man --- xterm-21+/xterm.man Mon Jun 10 13:03:46 1996 +++ xterm-22/xterm.man Sat Jul 27 16:17:57 1996 @@ -25,6 +25,8 @@ .\" not be used in advertising or otherwise to promote the sale, use or .\" other dealings in this Software without prior written authorization .\" from the X Consortium. +.\" +.\" updated by Thomas Dickey for XFree86, July 1996. .TH XTERM 1 "Release 6.1" "X Version 11" .SH NAME xterm \- terminal emulator for X @@ -54,9 +56,9 @@ menu in the 4014 window. .SH EMULATIONS The VT102 emulation is fairly complete, but does not support -smooth scrolling, VT52 mode, -the blinking -character attribute nor the double-wide and double-size character sets. +VT52 mode, +the blinking character attribute +nor the double-wide and double-size character sets. .IR Termcap (5) entries that work with .I xterm @@ -420,7 +422,7 @@ ownership of the console device in order to get this option to work. .TP 8 .B \-S\fIccn\fP -This option specifies the last two letters of the name of a pseudoterminal +This option specifies the last two letters of the name of a pseudo-terminal to use in slave mode, plus the number of the inherited file descriptor. The option is parsed ``%c%c%d''. This allows \fIxterm\fP to be used as an input and @@ -717,6 +719,11 @@ class name instead of the instance name is an easy way to have everything that would normally appear in the text color change color. The default is ``black.'' +.TP 8 +.B "cursorBlinkTime (\fPclass\fB CursorBlinkTime)" +Specifies the cursor blink cycle-time +(i.e., the time to turn the cursor on and off). +The default is 0, which disables blinking. .TP 8 .B "cursorColor (\fPclass\fB Foreground)" Specifies the color to use for the text cursor. The default is ``black.''