aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/programs/xterm/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'nx-X11/programs/xterm/util.c')
-rw-r--r--nx-X11/programs/xterm/util.c2951
1 files changed, 0 insertions, 2951 deletions
diff --git a/nx-X11/programs/xterm/util.c b/nx-X11/programs/xterm/util.c
deleted file mode 100644
index 84feac48f..000000000
--- a/nx-X11/programs/xterm/util.c
+++ /dev/null
@@ -1,2951 +0,0 @@
-/* $XTermId: util.c,v 1.255 2005/09/18 23:48:13 tom Exp $ */
-
-/*
- * $Xorg: util.c,v 1.3 2000/08/17 19:55:10 cpqbld Exp $
- */
-
-/* $XFree86: xc/programs/xterm/util.c,v 3.93 2005/09/18 23:48:13 dickey Exp $ */
-
-/*
- * Copyright 1999-2004,2005 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.
- *
- *
- * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
- *
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Digital Equipment
- * Corporation not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior permission.
- *
- *
- * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
-/* util.c */
-
-#include <xterm.h>
-
-#include <data.h>
-#include <error.h>
-#include <menu.h>
-#include <fontutils.h>
-#include <xstrings.h>
-
-#if OPT_WIDE_CHARS
-#if defined(HAVE_WCHAR_H) && defined(HAVE_WCWIDTH)
-#include <wchar.h>
-#endif
-#include <wcwidth.h>
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-#include <assert.h>
-
-static int ClearInLine(TScreen * screen, int row, int col, unsigned len);
-static int handle_translated_exposure(TScreen * screen,
- int rect_x,
- int rect_y,
- int rect_width,
- int rect_height);
-static void ClearLeft(TScreen * screen);
-static void CopyWait(TScreen * screen);
-static void horizontal_copy_area(TScreen * screen,
- int firstchar,
- int nchars,
- int amount);
-static void vertical_copy_area(TScreen * screen,
- int firstline,
- int nlines,
- int amount);
-
-#if OPT_WIDE_CHARS
-int (*my_wcwidth) (wchar_t);
-#endif
-
-/*
- * These routines are used for the jump scroll feature
- */
-void
-FlushScroll(TScreen * screen)
-{
- int i;
- int shift = -screen->topline;
- int bot = screen->max_row - shift;
- int refreshtop;
- int refreshheight;
- int scrolltop;
- int scrollheight;
-
- if (screen->cursor_state)
- HideCursor();
- if (screen->scroll_amt > 0) {
- refreshheight = screen->refresh_amt;
- scrollheight = screen->bot_marg - screen->top_marg -
- refreshheight + 1;
- if ((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
- (i = screen->max_row - screen->scroll_amt + 1))
- refreshtop = i;
- if (screen->scrollWidget && !screen->alternate
- && screen->top_marg == 0) {
- scrolltop = 0;
- if ((scrollheight += shift) > i)
- scrollheight = i;
- if ((i = screen->bot_marg - bot) > 0 &&
- (refreshheight -= i) < screen->scroll_amt)
- refreshheight = screen->scroll_amt;
- if ((i = screen->savedlines) < screen->savelines) {
- if ((i += screen->scroll_amt) >
- screen->savelines)
- i = screen->savelines;
- screen->savedlines = i;
- ScrollBarDrawThumb(screen->scrollWidget);
- }
- } else {
- scrolltop = screen->top_marg + shift;
- if ((i = bot - (screen->bot_marg - screen->refresh_amt +
- screen->scroll_amt)) > 0) {
- if (bot < screen->bot_marg)
- refreshheight = screen->scroll_amt + i;
- } else {
- scrollheight += i;
- refreshheight = screen->scroll_amt;
- if ((i = screen->top_marg + screen->scroll_amt -
- 1 - bot) > 0) {
- refreshtop += i;
- refreshheight -= i;
- }
- }
- }
- } else {
- refreshheight = -screen->refresh_amt;
- scrollheight = screen->bot_marg - screen->top_marg -
- refreshheight + 1;
- refreshtop = screen->top_marg + shift;
- scrolltop = refreshtop + refreshheight;
- if ((i = screen->bot_marg - bot) > 0)
- scrollheight -= i;
- if ((i = screen->top_marg + refreshheight - 1 - bot) > 0)
- refreshheight -= i;
- }
- scrolling_copy_area(screen, scrolltop + screen->scroll_amt,
- scrollheight, screen->scroll_amt);
- ScrollSelection(screen, -(screen->scroll_amt), False);
- screen->scroll_amt = 0;
- screen->refresh_amt = 0;
- if (refreshheight > 0) {
- ClearCurBackground(screen,
- (int) refreshtop * FontHeight(screen) + screen->border,
- (int) OriginX(screen),
- (unsigned) refreshheight * FontHeight(screen),
- (unsigned) Width(screen));
- ScrnRefresh(screen, refreshtop, 0, refreshheight,
- MaxCols(screen), False);
- }
- return;
-}
-
-int
-AddToRefresh(TScreen * screen)
-{
- int amount = screen->refresh_amt;
- int row = screen->cur_row;
-
- if (amount == 0) {
- return (0);
- } else if (amount > 0) {
- int bottom;
-
- if (row == (bottom = screen->bot_marg) - amount) {
- screen->refresh_amt++;
- return (1);
- }
- return (row >= bottom - amount + 1 && row <= bottom);
- } else {
- int top;
-
- amount = -amount;
- if (row == (top = screen->top_marg) + amount) {
- screen->refresh_amt--;
- return (1);
- }
- return (row <= top + amount - 1 && row >= top);
- }
-}
-
-/*
- * If we're scrolling, leave the selection intact if possible.
- * If it will bump into one of the extremes of the saved-lines, truncate that.
- * If the selection is not contained within the scrolled region, clear it.
- */
-static void
-adjustHiliteOnFwdScroll(TScreen * screen, int amount, Boolean all_lines)
-{
- int lo_row = (all_lines
- ? (screen->bot_marg - screen->savelines)
- : screen->top_marg);
- int hi_row = screen->bot_marg;
-
- TRACE2(("adjustSelection FWD %s by %d (%s)\n",
- screen->alternate ? "alternate" : "normal",
- amount,
- all_lines ? "all" : "visible"));
- TRACE2((" before highlite %d.%d .. %d.%d\n",
- screen->startHRow,
- screen->startHCol,
- screen->endHRow,
- screen->endHCol));
- TRACE2((" margins %d..%d\n", screen->top_marg, screen->bot_marg));
- TRACE2((" limits %d..%d\n", lo_row, hi_row));
-
- if (screen->startHRow >= lo_row
- && screen->startHRow - amount < lo_row) {
- /* truncate the selection because its start would move out of region */
- if (lo_row + amount <= screen->endHRow) {
- TRACE2(("truncate selection by changing start %d.%d to %d.%d\n",
- screen->startHRow,
- screen->startHCol,
- lo_row + amount,
- 0));
- screen->startHRow = lo_row + amount;
- screen->startHCol = 0;
- } else {
- TRACE2(("deselect because %d.%d .. %d.%d shifted %d is outside margins %d..%d\n",
- screen->startHRow,
- screen->startHCol,
- screen->endHRow,
- screen->endHCol,
- -amount,
- lo_row,
- hi_row));
- ScrnDisownSelection(screen);
- }
- } else if (screen->startHRow <= hi_row && screen->endHRow > hi_row) {
- ScrnDisownSelection(screen);
- } else if (screen->startHRow < lo_row && screen->endHRow > lo_row) {
- ScrnDisownSelection(screen);
- }
-
- TRACE2((" after highlite %d.%d .. %d.%d\n",
- screen->startHRow,
- screen->startHCol,
- screen->endHRow,
- screen->endHCol));
-}
-
-/*
- * This is the same as adjustHiliteOnFwdScroll(), but reversed. In this case,
- * only the visible lines are affected.
- */
-static void
-adjustHiliteOnBakScroll(TScreen * screen, int amount)
-{
- int lo_row = screen->top_marg;
- int hi_row = screen->bot_marg;
-
- TRACE2(("adjustSelection BAK %s by %d (%s)\n",
- screen->alternate ? "alternate" : "normal",
- amount,
- "visible"));
- TRACE2((" before highlite %d.%d .. %d.%d\n",
- screen->startHRow,
- screen->startHCol,
- screen->endHRow,
- screen->endHCol));
- TRACE2((" margins %d..%d\n", screen->top_marg, screen->bot_marg));
-
- if (screen->endHRow >= hi_row
- && screen->endHRow + amount > hi_row) {
- /* truncate the selection because its start would move out of region */
- if (hi_row - amount >= screen->startHRow) {
- TRACE2(("truncate selection by changing start %d.%d to %d.%d\n",
- screen->startHRow,
- screen->startHCol,
- hi_row - amount,
- 0));
- screen->endHRow = hi_row - amount;
- screen->endHCol = 0;
- } else {
- TRACE2(("deselect because %d.%d .. %d.%d shifted %d is outside margins %d..%d\n",
- screen->startHRow,
- screen->startHCol,
- screen->endHRow,
- screen->endHCol,
- amount,
- lo_row,
- hi_row));
- ScrnDisownSelection(screen);
- }
- } else if (screen->endHRow >= lo_row && screen->startHRow < lo_row) {
- ScrnDisownSelection(screen);
- } else if (screen->endHRow > hi_row && screen->startHRow > hi_row) {
- ScrnDisownSelection(screen);
- }
-
- TRACE2((" after highlite %d.%d .. %d.%d\n",
- screen->startHRow,
- screen->startHCol,
- screen->endHRow,
- screen->endHCol));
-}
-
-/*
- * scrolls the screen by amount lines, erases bottom, doesn't alter
- * cursor position (i.e. cursor moves down amount relative to text).
- * All done within the scrolling region, of course.
- * requires: amount > 0
- */
-void
-xtermScroll(TScreen * screen, int amount)
-{
- int i = screen->bot_marg - screen->top_marg + 1;
- int shift;
- int bot;
- int refreshtop = 0;
- int refreshheight;
- int scrolltop;
- int scrollheight;
- Boolean scroll_all_lines = (screen->scrollWidget
- && !screen->alternate
- && screen->top_marg == 0);
-
- TRACE(("xtermScroll count=%d\n", amount));
-
- screen->cursor_busy += 1;
- screen->cursor_moved = True;
-
- if (screen->cursor_state)
- HideCursor();
-
- if (amount > i)
- amount = i;
-
- if (ScrnHaveSelection(screen))
- adjustHiliteOnFwdScroll(screen, amount, scroll_all_lines);
-
- if (screen->jumpscroll) {
- if (screen->scroll_amt > 0) {
- if (screen->refresh_amt + amount > i)
- FlushScroll(screen);
- screen->scroll_amt += amount;
- screen->refresh_amt += amount;
- } else {
- if (screen->scroll_amt < 0)
- FlushScroll(screen);
- screen->scroll_amt = amount;
- screen->refresh_amt = amount;
- }
- refreshheight = 0;
- } else {
- ScrollSelection(screen, -(amount), False);
- if (amount == i) {
- ClearScreen(screen);
- screen->cursor_busy -= 1;
- return;
- }
-
- shift = -screen->topline;
- bot = screen->max_row - shift;
- scrollheight = i - amount;
- refreshheight = amount;
-
- if ((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
- (i = screen->max_row - refreshheight + 1))
- refreshtop = i;
-
- if (scroll_all_lines) {
- scrolltop = 0;
- if ((scrollheight += shift) > i)
- scrollheight = i;
- if ((i = screen->savedlines) < screen->savelines) {
- if ((i += amount) > screen->savelines)
- i = screen->savelines;
- screen->savedlines = i;
- ScrollBarDrawThumb(screen->scrollWidget);
- }
- } else {
- scrolltop = screen->top_marg + shift;
- if ((i = screen->bot_marg - bot) > 0) {
- scrollheight -= i;
- if ((i = screen->top_marg + amount - 1 - bot) >= 0) {
- refreshtop += i;
- refreshheight -= i;
- }
- }
- }
-
- if (screen->multiscroll && amount == 1 &&
- screen->topline == 0 && screen->top_marg == 0 &&
- screen->bot_marg == screen->max_row) {
- if (screen->incopy < 0 && screen->scrolls == 0)
- CopyWait(screen);
- screen->scrolls++;
- }
-
- scrolling_copy_area(screen, scrolltop + amount, scrollheight, amount);
-
- if (refreshheight > 0) {
- ClearCurBackground(screen,
- (int) refreshtop * FontHeight(screen) + screen->border,
- (int) OriginX(screen),
- (unsigned) refreshheight * FontHeight(screen),
- (unsigned) Width(screen));
- if (refreshheight > shift)
- refreshheight = shift;
- }
- }
-
- if (amount > 0) {
- if (scroll_all_lines) {
- ScrnDeleteLine(screen,
- screen->allbuf,
- screen->bot_marg + screen->savelines,
- 0,
- (unsigned) amount,
- (unsigned) MaxCols(screen));
- } else {
- ScrnDeleteLine(screen,
- screen->visbuf,
- screen->bot_marg,
- screen->top_marg,
- (unsigned) amount,
- (unsigned) MaxCols(screen));
- }
- }
-
- if (refreshheight > 0) {
- ScrnRefresh(screen, refreshtop, 0, refreshheight,
- MaxCols(screen), False);
- }
-
- screen->cursor_busy -= 1;
- return;
-}
-
-/*
- * Reverse scrolls the screen by amount lines, erases top, doesn't alter
- * cursor position (i.e. cursor moves up amount relative to text).
- * All done within the scrolling region, of course.
- * Requires: amount > 0
- */
-void
-RevScroll(TScreen * screen, int amount)
-{
- int i = screen->bot_marg - screen->top_marg + 1;
- int shift;
- int bot;
- int refreshtop;
- int refreshheight;
- int scrolltop;
- int scrollheight;
-
- TRACE(("RevScroll count=%d\n", amount));
-
- screen->cursor_busy += 1;
- screen->cursor_moved = True;
-
- if (screen->cursor_state)
- HideCursor();
-
- if (amount > i)
- amount = i;
-
- if (ScrnHaveSelection(screen))
- adjustHiliteOnBakScroll(screen, amount);
-
- if (screen->jumpscroll) {
- if (screen->scroll_amt < 0) {
- if (-screen->refresh_amt + amount > i)
- FlushScroll(screen);
- screen->scroll_amt -= amount;
- screen->refresh_amt -= amount;
- } else {
- if (screen->scroll_amt > 0)
- FlushScroll(screen);
- screen->scroll_amt = -amount;
- screen->refresh_amt = -amount;
- }
- } else {
- shift = -screen->topline;
- bot = screen->max_row - shift;
- refreshheight = amount;
- scrollheight = screen->bot_marg - screen->top_marg -
- refreshheight + 1;
- refreshtop = screen->top_marg + shift;
- scrolltop = refreshtop + refreshheight;
- if ((i = screen->bot_marg - bot) > 0)
- scrollheight -= i;
- if ((i = screen->top_marg + refreshheight - 1 - bot) > 0)
- refreshheight -= i;
-
- if (screen->multiscroll && amount == 1 &&
- screen->topline == 0 && screen->top_marg == 0 &&
- screen->bot_marg == screen->max_row) {
- if (screen->incopy < 0 && screen->scrolls == 0)
- CopyWait(screen);
- screen->scrolls++;
- }
-
- scrolling_copy_area(screen, scrolltop - amount, scrollheight, -amount);
-
- if (refreshheight > 0) {
- ClearCurBackground(screen,
- (int) refreshtop * FontHeight(screen) + screen->border,
- (int) OriginX(screen),
- (unsigned) refreshheight * FontHeight(screen),
- (unsigned) Width(screen));
- }
- }
- if (amount > 0) {
- ScrnInsertLine(screen,
- screen->visbuf,
- screen->bot_marg,
- screen->top_marg,
- (unsigned) amount,
- (unsigned) MaxCols(screen));
- }
- screen->cursor_busy -= 1;
- return;
-}
-
-/*
- * If cursor not in scrolling region, returns. Else,
- * inserts n blank lines at the cursor's position. Lines above the
- * bottom margin are lost.
- */
-void
-InsertLine(TScreen * screen, int n)
-{
- int i;
- int shift;
- int bot;
- int refreshtop;
- int refreshheight;
- int scrolltop;
- int scrollheight;
-
- if (!ScrnIsLineInMargins(screen, screen->cur_row - screen->topline))
- return;
-
- TRACE(("InsertLine count=%d\n", n));
-
- if (screen->cursor_state)
- HideCursor();
-
- if (ScrnHaveSelection(screen)
- && ScrnAreLinesInSelection(screen, screen->top_marg, screen->bot_marg)) {
- ScrnDisownSelection(screen);
- }
-
- screen->do_wrap = 0;
- if (n > (i = screen->bot_marg - screen->cur_row + 1))
- n = i;
- if (screen->jumpscroll) {
- if (screen->scroll_amt <= 0 &&
- screen->cur_row <= -screen->refresh_amt) {
- if (-screen->refresh_amt + n > MaxRows(screen))
- FlushScroll(screen);
- screen->scroll_amt -= n;
- screen->refresh_amt -= n;
- } else if (screen->scroll_amt)
- FlushScroll(screen);
- }
- if (!screen->scroll_amt) {
- shift = -screen->topline;
- bot = screen->max_row - shift;
- refreshheight = n;
- scrollheight = screen->bot_marg - screen->cur_row - refreshheight + 1;
- refreshtop = screen->cur_row + shift;
- scrolltop = refreshtop + refreshheight;
- if ((i = screen->bot_marg - bot) > 0)
- scrollheight -= i;
- if ((i = screen->cur_row + refreshheight - 1 - bot) > 0)
- refreshheight -= i;
- vertical_copy_area(screen, scrolltop - n, scrollheight, -n);
- if (refreshheight > 0) {
- ClearCurBackground(screen,
- (int) refreshtop * FontHeight(screen) + screen->border,
- (int) OriginX(screen),
- (unsigned) refreshheight * FontHeight(screen),
- (unsigned) Width(screen));
- }
- }
- if (n > 0) {
- ScrnInsertLine(screen,
- screen->visbuf,
- screen->bot_marg,
- screen->cur_row,
- (unsigned) n,
- (unsigned) MaxCols(screen));
- }
-}
-
-/*
- * If cursor not in scrolling region, returns. Else, deletes n lines
- * at the cursor's position, lines added at bottom margin are blank.
- */
-void
-DeleteLine(TScreen * screen, int n)
-{
- int i;
- int shift;
- int bot;
- int refreshtop;
- int refreshheight;
- int scrolltop;
- int scrollheight;
-
- if (!ScrnIsLineInMargins(screen, screen->cur_row - screen->topline))
- return;
-
- TRACE(("DeleteLine count=%d\n", n));
-
- if (screen->cursor_state)
- HideCursor();
-
- if (ScrnHaveSelection(screen)
- && ScrnAreLinesInSelection(screen, screen->top_marg, screen->bot_marg)) {
- ScrnDisownSelection(screen);
- }
-
- screen->do_wrap = 0;
- if (n > (i = screen->bot_marg - screen->cur_row + 1))
- n = i;
- if (screen->jumpscroll) {
- if (screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
- if (screen->refresh_amt + n > MaxRows(screen))
- FlushScroll(screen);
- screen->scroll_amt += n;
- screen->refresh_amt += n;
- } else if (screen->scroll_amt)
- FlushScroll(screen);
- }
- if (!screen->scroll_amt) {
-
- shift = -screen->topline;
- bot = screen->max_row - shift;
- scrollheight = i - n;
- refreshheight = n;
- if ((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
- (i = screen->max_row - refreshheight + 1))
- refreshtop = i;
- if (screen->scrollWidget && !screen->alternate && screen->cur_row == 0) {
- scrolltop = 0;
- if ((scrollheight += shift) > i)
- scrollheight = i;
- if ((i = screen->savedlines) < screen->savelines) {
- if ((i += n) > screen->savelines)
- i = screen->savelines;
- screen->savedlines = i;
- ScrollBarDrawThumb(screen->scrollWidget);
- }
- } else {
- scrolltop = screen->cur_row + shift;
- if ((i = screen->bot_marg - bot) > 0) {
- scrollheight -= i;
- if ((i = screen->cur_row + n - 1 - bot) >= 0) {
- refreshheight -= i;
- }
- }
- }
- vertical_copy_area(screen, scrolltop + n, scrollheight, n);
- if (refreshheight > 0) {
- ClearCurBackground(screen,
- (int) refreshtop * FontHeight(screen) + screen->border,
- (int) OriginX(screen),
- (unsigned) refreshheight * FontHeight(screen),
- (unsigned) Width(screen));
- }
- }
- /* adjust screen->buf */
- if (n > 0) {
- if (screen->scrollWidget
- && !screen->alternate
- && screen->cur_row == 0)
- ScrnDeleteLine(screen,
- screen->allbuf,
- screen->bot_marg + screen->savelines,
- 0,
- (unsigned) n,
- (unsigned) MaxCols(screen));
- else
- ScrnDeleteLine(screen,
- screen->visbuf,
- screen->bot_marg,
- screen->cur_row,
- (unsigned) n,
- (unsigned) MaxCols(screen));
- }
-}
-
-/*
- * Insert n blanks at the cursor's position, no wraparound
- */
-void
-InsertChar(TScreen * screen, unsigned n)
-{
- unsigned limit;
- int row = screen->cur_row - screen->topline;
-
- if (screen->cursor_state)
- HideCursor();
-
- TRACE(("InsertChar count=%d\n", n));
-
- if (ScrnHaveSelection(screen)
- && ScrnIsLineInSelection(screen, row)) {
- ScrnDisownSelection(screen);
- }
- screen->do_wrap = 0;
-
- assert(screen->cur_col <= screen->max_col);
- limit = MaxCols(screen) - screen->cur_col;
-
- if (n > limit)
- n = limit;
-
- assert(n != 0);
- if (row <= screen->max_row) {
- if (!AddToRefresh(screen)) {
- int col = MaxCols(screen) - n;
- if (screen->scroll_amt)
- FlushScroll(screen);
-
-#if OPT_DEC_CHRSET
- if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, screen->cur_row)[0])) {
- col = MaxCols(screen) / 2 - n;
- }
-#endif
- /*
- * prevent InsertChar from shifting the end of a line over
- * if it is being appended to
- */
- if (non_blank_line(screen->visbuf, screen->cur_row,
- screen->cur_col, MaxCols(screen)))
- horizontal_copy_area(screen, screen->cur_col,
- col - screen->cur_col,
- (int) n);
-
- ClearCurBackground(screen,
- CursorY(screen, screen->cur_row),
- CurCursorX(screen, screen->cur_row, screen->cur_col),
- (unsigned) FontHeight(screen),
- n * CurFontWidth(screen, screen->cur_row));
- }
- }
- /* adjust screen->buf */
- ScrnInsertChar(screen, n);
-}
-
-/*
- * Deletes n chars at the cursor's position, no wraparound.
- */
-void
-DeleteChar(TScreen * screen, unsigned n)
-{
- unsigned limit;
- int row = screen->cur_row - screen->topline;
-
- if (screen->cursor_state)
- HideCursor();
-
- TRACE(("DeleteChar count=%d\n", n));
-
- if (ScrnHaveSelection(screen)
- && ScrnIsLineInSelection(screen, row)) {
- ScrnDisownSelection(screen);
- }
- screen->do_wrap = 0;
-
- assert(screen->cur_col <= screen->max_col);
- limit = MaxCols(screen) - screen->cur_col;
-
- if (n > limit)
- n = limit;
-
- assert(n != 0);
- if (row <= screen->max_row) {
- if (!AddToRefresh(screen)) {
- int col = MaxCols(screen) - n;
- if (screen->scroll_amt)
- FlushScroll(screen);
-
-#if OPT_DEC_CHRSET
- if (CSET_DOUBLE(SCRN_BUF_CSETS(screen, screen->cur_row)[0])) {
- col = MaxCols(screen) / 2 - n;
- }
-#endif
- horizontal_copy_area(screen,
- (int) (screen->cur_col + n),
- col - screen->cur_col,
- -((int) n));
-
- ClearCurBackground(screen,
- CursorY(screen, screen->cur_row),
- CurCursorX(screen, screen->cur_row, col),
- (unsigned) FontHeight(screen),
- n * CurFontWidth(screen, screen->cur_row));
- }
- }
- if (n > 0) {
- /* adjust screen->buf */
- ScrnDeleteChar(screen, (unsigned) n);
- }
-}
-
-/*
- * Clear from cursor position to beginning of display, inclusive.
- */
-static void
-ClearAbove(TScreen * screen)
-{
- if (screen->protected_mode != OFF_PROTECT) {
- int row;
- unsigned len = MaxCols(screen);
-
- assert(screen->max_col >= 0);
- for (row = 0; row <= screen->max_row; row++)
- ClearInLine(screen, row, 0, len);
- } else {
- int top, height;
-
- if (screen->cursor_state)
- HideCursor();
- if ((top = -screen->topline) <= screen->max_row) {
- if (screen->scroll_amt)
- FlushScroll(screen);
- if ((height = screen->cur_row + top) > screen->max_row)
- height = screen->max_row;
- if ((height -= top) > 0) {
- ClearCurBackground(screen,
- top * FontHeight(screen) + screen->border,
- OriginX(screen),
- (unsigned) (height * FontHeight(screen)),
- (unsigned) (Width(screen)));
- }
- }
- ClearBufRows(screen, 0, screen->cur_row - 1);
- }
-
- if (screen->cur_row - screen->topline <= screen->max_row)
- ClearLeft(screen);
-}
-
-/*
- * Clear from cursor position to end of display, inclusive.
- */
-static void
-ClearBelow(TScreen * screen)
-{
- ClearRight(screen, -1);
-
- if (screen->protected_mode != OFF_PROTECT) {
- int row;
- unsigned len = MaxCols(screen);
-
- assert(screen->max_col >= 0);
- for (row = screen->cur_row + 1; row <= screen->max_row; row++)
- ClearInLine(screen, row, 0, len);
- } else {
- int top;
-
- if ((top = screen->cur_row - screen->topline) <= screen->max_row) {
- if (screen->scroll_amt)
- FlushScroll(screen);
- if (++top <= screen->max_row) {
- ClearCurBackground(screen,
- top * FontHeight(screen) + screen->border,
- OriginX(screen),
- (unsigned) ((screen->max_row - top + 1)
- * FontHeight(screen)),
- (unsigned) (Width(screen)));
- }
- }
- ClearBufRows(screen, screen->cur_row + 1, screen->max_row);
- }
-}
-
-/*
- * Clear the given row, for the given range of columns, returning 1 if no
- * protected characters were found, 0 otherwise.
- */
-static int
-ClearInLine(TScreen * screen, int row, int col, unsigned len)
-{
- int rc = 1;
- int flags = TERM_COLOR_FLAGS(term);
-
- TRACE(("ClearInLine(row=%d, col=%d, len=%d) vs %d..%d\n",
- row, col, len,
- screen->startHRow,
- screen->startHCol));
-
- if (ScrnHaveSelection(screen)
- && ScrnIsLineInSelection(screen, row)) {
- ScrnDisownSelection(screen);
- }
-
- /*
- * If we're clearing to the end of the line, we won't count this as
- * "drawn" characters. We'll only do cut/paste on "drawn" characters,
- * so this has the effect of suppressing trailing blanks from a
- * selection.
- */
- if (col + (int) len < MaxCols(screen)) {
- flags |= CHARDRAWN;
- } else {
- len = MaxCols(screen) - col;
- }
-
- /* If we've marked protected text on the screen, we'll have to
- * check each time we do an erase.
- */
- if (screen->protected_mode != OFF_PROTECT) {
- unsigned n;
- Char *attrs = SCRN_BUF_ATTRS(screen, row) + col;
- int saved_mode = screen->protected_mode;
- Bool done;
-
- /* disable this branch during recursion */
- screen->protected_mode = OFF_PROTECT;
-
- do {
- done = True;
- for (n = 0; n < len; n++) {
- if (attrs[n] & PROTECTED) {
- rc = 0; /* found a protected segment */
- if (n != 0)
- ClearInLine(screen, row, col, n);
- while ((n < len)
- && (attrs[n] & PROTECTED))
- n++;
- done = False;
- break;
- }
- }
- /* setup for another segment, past the protected text */
- if (!done) {
- attrs += n;
- col += n;
- len -= n;
- }
- } while (!done);
-
- screen->protected_mode = saved_mode;
- if (len <= 0)
- return 0;
- }
- /* fall through to the final non-protected segment */
-
- if (screen->cursor_state)
- HideCursor();
- screen->do_wrap = 0;
-
- if (row - screen->topline <= screen->max_row) {
- if (!AddToRefresh(screen)) {
- if (screen->scroll_amt)
- FlushScroll(screen);
- ClearCurBackground(screen,
- CursorY(screen, row),
- CurCursorX(screen, row, col),
- (unsigned) FontHeight(screen),
- len * CurFontWidth(screen, row));
- }
- }
-
- memset(SCRN_BUF_CHARS(screen, row) + col, ' ', len);
- memset(SCRN_BUF_ATTRS(screen, row) + col, flags, len);
-
- if_OPT_EXT_COLORS(screen, {
- memset(SCRN_BUF_FGRND(screen, row) + col, term->sgr_foreground, len);
- memset(SCRN_BUF_BGRND(screen, row) + col, term->cur_background, len);
- });
- if_OPT_ISO_TRADITIONAL_COLORS(screen, {
- memset(SCRN_BUF_COLOR(screen, row) + col, xtermColorPair(), len);
- });
- if_OPT_DEC_CHRSET({
- memset(SCRN_BUF_CSETS(screen, row) + col,
- curXtermChrSet(screen->cur_row), len);
- });
- if_OPT_WIDE_CHARS(screen, {
- memset(SCRN_BUF_WIDEC(screen, row) + col, 0, len);
- memset(SCRN_BUF_COM1L(screen, row) + col, 0, len);
- memset(SCRN_BUF_COM1H(screen, row) + col, 0, len);
- memset(SCRN_BUF_COM2L(screen, row) + col, 0, len);
- memset(SCRN_BUF_COM2H(screen, row) + col, 0, len);
- });
-
- return rc;
-}
-
-/*
- * Clear the next n characters on the cursor's line, including the cursor's
- * position.
- */
-void
-ClearRight(TScreen * screen, int n)
-{
- unsigned len = (MaxCols(screen) - screen->cur_col);
-
- assert(screen->max_col >= 0);
- assert(screen->max_col >= screen->cur_col);
-
- if (n < 0) /* the remainder of the line */
- n = MaxCols(screen);
- if (n == 0) /* default for 'ECH' */
- n = 1;
-
- if (len > (unsigned) n)
- len = n;
-
- (void) ClearInLine(screen, screen->cur_row, screen->cur_col, len);
-
- /* with the right part cleared, we can't be wrapping */
- ScrnClrWrapped(screen, screen->cur_row);
-}
-
-/*
- * Clear first part of cursor's line, inclusive.
- */
-static void
-ClearLeft(TScreen * screen)
-{
- unsigned len = screen->cur_col + 1;
- assert(screen->cur_col >= 0);
-
- (void) ClearInLine(screen, screen->cur_row, 0, len);
-}
-
-/*
- * Erase the cursor's line.
- */
-static void
-ClearLine(TScreen * screen)
-{
- unsigned len = MaxCols(screen);
-
- assert(screen->max_col >= 0);
- (void) ClearInLine(screen, screen->cur_row, 0, len);
-}
-
-void
-ClearScreen(TScreen * screen)
-{
- int top;
-
- if (screen->cursor_state)
- HideCursor();
-
- ScrnDisownSelection(screen);
- screen->do_wrap = 0;
- if ((top = -screen->topline) <= screen->max_row) {
- if (screen->scroll_amt)
- FlushScroll(screen);
- ClearCurBackground(screen,
- top * FontHeight(screen) + screen->border,
- OriginX(screen),
- (unsigned) ((screen->max_row - top + 1)
- * FontHeight(screen)),
- (unsigned) Width(screen));
- }
- ClearBufRows(screen, 0, screen->max_row);
-}
-
-/*
- * If we've written protected text DEC-style, and are issuing a non-DEC
- * erase, temporarily reset the protected_mode flag so that the erase will
- * ignore the protected flags.
- */
-void
-do_erase_line(TScreen * screen, int param, int mode)
-{
- int saved_mode = screen->protected_mode;
-
- if (saved_mode == DEC_PROTECT
- && saved_mode != mode)
- screen->protected_mode = OFF_PROTECT;
-
- switch (param) {
- case -1: /* DEFAULT */
- case 0:
- ClearRight(screen, -1);
- break;
- case 1:
- ClearLeft(screen);
- break;
- case 2:
- ClearLine(screen);
- break;
- }
- screen->protected_mode = saved_mode;
-}
-
-/*
- * Just like 'do_erase_line()', except that this intercepts ED controls. If we
- * clear the whole screen, we'll get the return-value from ClearInLine, and
- * find if there were any protected characters left. If not, reset the
- * protected mode flag in the screen data (it's slower).
- */
-void
-do_erase_display(TScreen * screen, int param, int mode)
-{
- int saved_mode = screen->protected_mode;
-
- if (saved_mode == DEC_PROTECT
- && saved_mode != mode)
- screen->protected_mode = OFF_PROTECT;
-
- switch (param) {
- case -1: /* DEFAULT */
- case 0:
- if (screen->cur_row == 0
- && screen->cur_col == 0) {
- screen->protected_mode = saved_mode;
- do_erase_display(screen, 2, mode);
- saved_mode = screen->protected_mode;
- } else
- ClearBelow(screen);
- break;
-
- case 1:
- if (screen->cur_row == screen->max_row
- && screen->cur_col == screen->max_col) {
- screen->protected_mode = saved_mode;
- do_erase_display(screen, 2, mode);
- saved_mode = screen->protected_mode;
- } else
- ClearAbove(screen);
- break;
-
- case 2:
- /*
- * We use 'ClearScreen()' throughout the remainder of the
- * program for places where we don't care if the characters are
- * protected or not. So we modify the logic around this call
- * on 'ClearScreen()' to handle protected characters.
- */
- if (screen->protected_mode != OFF_PROTECT) {
- int row;
- int rc = 1;
- unsigned len = MaxCols(screen);
-
- assert(screen->max_col >= 0);
- for (row = 0; row <= screen->max_row; row++)
- rc &= ClearInLine(screen, row, 0, len);
- if (rc != 0)
- saved_mode = OFF_PROTECT;
- } else {
- ClearScreen(screen);
- }
- break;
-
- case 3:
- /* xterm addition - erase saved lines. */
- screen->savedlines = 0;
- ScrollBarDrawThumb(screen->scrollWidget);
- break;
- }
- screen->protected_mode = saved_mode;
-}
-
-static void
-CopyWait(TScreen * screen)
-{
- XEvent reply;
- XEvent *rep = &reply;
-
- while (1) {
- XWindowEvent(screen->display, VWindow(screen),
- ExposureMask, &reply);
- switch (reply.type) {
- case Expose:
- HandleExposure(screen, &reply);
- break;
- case NoExpose:
- case GraphicsExpose:
- if (screen->incopy <= 0) {
- screen->incopy = 1;
- if (screen->scrolls > 0)
- screen->scrolls--;
- }
- if (reply.type == GraphicsExpose)
- HandleExposure(screen, &reply);
-
- if ((reply.type == NoExpose) ||
- ((XExposeEvent *) rep)->count == 0) {
- if (screen->incopy <= 0 && screen->scrolls > 0)
- screen->scrolls--;
- if (screen->scrolls == 0) {
- screen->incopy = 0;
- return;
- }
- screen->incopy = -1;
- }
- break;
- }
- }
-}
-
-/*
- * used by vertical_copy_area and and horizontal_copy_area
- */
-static void
-copy_area(TScreen * screen,
- int src_x,
- int src_y,
- unsigned width,
- unsigned height,
- int dest_x,
- int dest_y)
-{
- if (width != 0 && height != 0) {
- /* wait for previous CopyArea to complete unless
- multiscroll is enabled and active */
- if (screen->incopy && screen->scrolls == 0)
- CopyWait(screen);
- screen->incopy = -1;
-
- /* save for translating Expose events */
- screen->copy_src_x = src_x;
- screen->copy_src_y = src_y;
- screen->copy_width = width;
- screen->copy_height = height;
- screen->copy_dest_x = dest_x;
- screen->copy_dest_y = dest_y;
-
- XCopyArea(screen->display,
- VWindow(screen), VWindow(screen),
- NormalGC(screen),
- src_x, src_y, width, height, dest_x, dest_y);
- }
-}
-
-/*
- * use when inserting or deleting characters on the current line
- */
-static void
-horizontal_copy_area(TScreen * screen,
- int firstchar, /* char pos on screen to start copying at */
- int nchars,
- int amount) /* number of characters to move right */
-{
- int src_x = CurCursorX(screen, screen->cur_row, firstchar);
- int src_y = CursorY(screen, screen->cur_row);
-
- copy_area(screen, src_x, src_y,
- (unsigned) nchars * CurFontWidth(screen, screen->cur_row),
- (unsigned) FontHeight(screen),
- src_x + amount * CurFontWidth(screen, screen->cur_row), src_y);
-}
-
-/*
- * use when inserting or deleting lines from the screen
- */
-static void
-vertical_copy_area(TScreen * screen,
- int firstline, /* line on screen to start copying at */
- int nlines,
- int amount) /* number of lines to move up (neg=down) */
-{
- if (nlines > 0) {
- int src_x = OriginX(screen);
- int src_y = firstline * FontHeight(screen) + screen->border;
-
- copy_area(screen, src_x, src_y,
- (unsigned) Width(screen),
- (unsigned) (nlines * FontHeight(screen)),
- src_x, src_y - amount * FontHeight(screen));
- }
-}
-
-/*
- * use when scrolling the entire screen
- */
-void
-scrolling_copy_area(TScreen * screen,
- int firstline, /* line on screen to start copying at */
- int nlines,
- int amount) /* number of lines to move up (neg=down) */
-{
-
- if (nlines > 0) {
- vertical_copy_area(screen, firstline, nlines, amount);
- }
-}
-
-/*
- * Handler for Expose events on the VT widget.
- * Returns 1 iff the area where the cursor was got refreshed.
- */
-int
-HandleExposure(TScreen * screen, XEvent * event)
-{
- XExposeEvent *reply = (XExposeEvent *) event;
-
-#ifndef NO_ACTIVE_ICON
- if (reply->window == screen->iconVwin.window) {
- WhichVWin(screen) = &screen->iconVwin;
- TRACE(("HandleExposure - icon"));
- } else {
- WhichVWin(screen) = &screen->fullVwin;
- TRACE(("HandleExposure - normal"));
- }
- TRACE((" event %d,%d %dx%d\n",
- reply->y,
- reply->x,
- reply->height,
- reply->width));
-#endif /* NO_ACTIVE_ICON */
-
- /* if not doing CopyArea or if this is a GraphicsExpose, don't translate */
- if (!screen->incopy || event->type != Expose)
- return handle_translated_exposure(screen, reply->x, reply->y,
- reply->width,
- reply->height);
- else {
- /* compute intersection of area being copied with
- area being exposed. */
- int both_x1 = Max(screen->copy_src_x, reply->x);
- int both_y1 = Max(screen->copy_src_y, reply->y);
- int both_x2 = Min(screen->copy_src_x + screen->copy_width,
- (unsigned) (reply->x + reply->width));
- int both_y2 = Min(screen->copy_src_y + screen->copy_height,
- (unsigned) (reply->y + reply->height));
- int value = 0;
-
- /* was anything copied affected? */
- if (both_x2 > both_x1 && both_y2 > both_y1) {
- /* do the copied area */
- value = handle_translated_exposure
- (screen, reply->x + screen->copy_dest_x - screen->copy_src_x,
- reply->y + screen->copy_dest_y - screen->copy_src_y,
- reply->width, reply->height);
- }
- /* was anything not copied affected? */
- if (reply->x < both_x1 || reply->y < both_y1
- || reply->x + reply->width > both_x2
- || reply->y + reply->height > both_y2)
- value = handle_translated_exposure(screen, reply->x, reply->y,
- reply->width, reply->height);
-
- return value;
- }
-}
-
-/*
- * Called by the ExposeHandler to do the actual repaint after the coordinates
- * have been translated to allow for any CopyArea in progress.
- * The rectangle passed in is pixel coordinates.
- */
-static int
-handle_translated_exposure(TScreen * screen,
- int rect_x,
- int rect_y,
- int rect_width,
- int rect_height)
-{
- int toprow, leftcol, nrows, ncols;
- int x0, x1;
- int y0, y1;
-
- TRACE(("handle_translated_exposure at %d,%d size %dx%d\n",
- rect_y, rect_x, rect_height, rect_width));
-
- x0 = (rect_x - OriginX(screen));
- x1 = (x0 + rect_width);
-
- y0 = (rect_y - OriginY(screen));
- y1 = (y0 + rect_height);
-
- toprow = y0 / FontHeight(screen);
- if (toprow < 0)
- toprow = 0;
-
- leftcol = x0 / CurFontWidth(screen, screen->cur_row);
- if (leftcol < 0)
- leftcol = 0;
-
- nrows = (y1 - 1) / FontHeight(screen) - toprow + 1;
- ncols = (x1 - 1) / FontWidth(screen) - leftcol + 1;
- toprow -= screen->scrolls;
- if (toprow < 0) {
- nrows += toprow;
- toprow = 0;
- }
- if (toprow + nrows > MaxRows(screen))
- nrows = MaxRows(screen) - toprow;
- if (leftcol + ncols > MaxCols(screen))
- ncols = MaxCols(screen) - leftcol;
-
- if (nrows > 0 && ncols > 0) {
- ScrnRefresh(screen, toprow, leftcol, nrows, ncols, False);
- if (waiting_for_initial_map) {
- first_map_occurred();
- }
- if (screen->cur_row >= toprow &&
- screen->cur_row < toprow + nrows &&
- screen->cur_col >= leftcol &&
- screen->cur_col < leftcol + ncols)
- return (1);
-
- }
- return (0);
-}
-
-/***====================================================================***/
-
-void
-GetColors(XtermWidget tw, ScrnColors * pColors)
-{
- TScreen *screen = &tw->screen;
- int n;
-
- pColors->which = 0;
- for (n = 0; n < NCOLORS; ++n) {
- SET_COLOR_VALUE(pColors, n, T_COLOR(screen, n));
- }
-}
-
-void
-ChangeColors(XtermWidget tw, ScrnColors * pNew)
-{
- TScreen *screen = &tw->screen;
-#if OPT_TEK4014
- Window tek = TWindow(screen);
-#endif
-
- TRACE(("ChangeColors\n"));
-
- if (COLOR_DEFINED(pNew, TEXT_CURSOR)) {
- T_COLOR(screen, TEXT_CURSOR) = COLOR_VALUE(pNew, TEXT_CURSOR);
- TRACE(("... TEXT_CURSOR: %#lx\n", T_COLOR(screen, TEXT_CURSOR)));
- } else if ((T_COLOR(screen, TEXT_CURSOR) == T_COLOR(screen, TEXT_FG)) &&
- (COLOR_DEFINED(pNew, TEXT_FG))) {
- T_COLOR(screen, TEXT_CURSOR) = COLOR_VALUE(pNew, TEXT_FG);
- TRACE(("... TEXT_CURSOR: %#lx\n", T_COLOR(screen, TEXT_CURSOR)));
- }
-
- if (COLOR_DEFINED(pNew, TEXT_FG)) {
- Pixel fg = COLOR_VALUE(pNew, TEXT_FG);
- T_COLOR(screen, TEXT_FG) = fg;
- TRACE(("... TEXT_FG: %#lx\n", T_COLOR(screen, TEXT_FG)));
- XSetForeground(screen->display, NormalGC(screen), fg);
- XSetBackground(screen->display, ReverseGC(screen), fg);
- XSetForeground(screen->display, NormalBoldGC(screen), fg);
- XSetBackground(screen->display, ReverseBoldGC(screen), fg);
- }
-
- if (COLOR_DEFINED(pNew, TEXT_BG)) {
- Pixel bg = COLOR_VALUE(pNew, TEXT_BG);
- T_COLOR(screen, TEXT_BG) = bg;
- TRACE(("... TEXT_BG: %#lx\n", T_COLOR(screen, TEXT_BG)));
- XSetBackground(screen->display, NormalGC(screen), bg);
- XSetForeground(screen->display, ReverseGC(screen), bg);
- XSetBackground(screen->display, NormalBoldGC(screen), bg);
- XSetForeground(screen->display, ReverseBoldGC(screen), bg);
- XSetWindowBackground(screen->display, VWindow(screen),
- T_COLOR(screen, TEXT_BG));
- }
-#if OPT_HIGHLIGHT_COLOR
- if (COLOR_DEFINED(pNew, HIGHLIGHT_BG)) {
- T_COLOR(screen, HIGHLIGHT_BG) = COLOR_VALUE(pNew, HIGHLIGHT_BG);
- TRACE(("... HIGHLIGHT_BG: %#lx\n", T_COLOR(screen, HIGHLIGHT_BG)));
- }
-#endif
-
- if (COLOR_DEFINED(pNew, MOUSE_FG) || (COLOR_DEFINED(pNew, MOUSE_BG))) {
- if (COLOR_DEFINED(pNew, MOUSE_FG)) {
- T_COLOR(screen, MOUSE_FG) = COLOR_VALUE(pNew, MOUSE_FG);
- TRACE(("... MOUSE_FG: %#lx\n", T_COLOR(screen, MOUSE_FG)));
- }
- if (COLOR_DEFINED(pNew, MOUSE_BG)) {
- T_COLOR(screen, MOUSE_BG) = COLOR_VALUE(pNew, MOUSE_BG);
- TRACE(("... MOUSE_BG: %#lx\n", T_COLOR(screen, MOUSE_BG)));
- }
-
- recolor_cursor(screen->pointer_cursor,
- T_COLOR(screen, MOUSE_FG),
- T_COLOR(screen, MOUSE_BG));
- recolor_cursor(screen->arrow,
- T_COLOR(screen, MOUSE_FG),
- T_COLOR(screen, MOUSE_BG));
- XDefineCursor(screen->display, VWindow(screen),
- screen->pointer_cursor);
-
-#if OPT_TEK4014
- if (tek)
- XDefineCursor(screen->display, tek, screen->arrow);
-#endif
- }
-#if OPT_TEK4014
- if (COLOR_DEFINED(pNew, TEK_FG) ||
- COLOR_DEFINED(pNew, TEK_BG) ||
- COLOR_DEFINED(pNew, TEK_CURSOR)) {
- ChangeTekColors(screen, pNew);
- }
-#endif
- set_cursor_gcs(screen);
- XClearWindow(screen->display, VWindow(screen));
- ScrnRefresh(screen, 0, 0, MaxRows(screen),
- MaxCols(screen), False);
-#if OPT_TEK4014
- if (screen->Tshow) {
- XClearWindow(screen->display, tek);
- TekExpose((Widget) NULL, (XEvent *) NULL, (Region) NULL);
- }
-#endif
-}
-
-void
-ChangeAnsiColors(XtermWidget tw)
-{
- TScreen *screen = &tw->screen;
-
- XClearWindow(screen->display, VWindow(screen));
- ScrnRefresh(screen, 0, 0,
- MaxRows(screen),
- MaxCols(screen), False);
-}
-
-/***====================================================================***/
-
-void
-ReverseVideo(XtermWidget termw)
-{
- TScreen *screen = &termw->screen;
- GC tmpGC;
- Pixel tmp;
-#if OPT_TEK4014
- Window tek = TWindow(screen);
-#endif
-
- /*
- * Swap SGR foreground and background colors. By convention, these are
- * the colors assigned to "black" (SGR #0) and "white" (SGR #7). Also,
- * SGR #8 and SGR #15 are the bold (or bright) versions of SGR #0 and
- * #7, respectively.
- *
- * We don't swap colors that happen to match the screen's foreground
- * and background because that tends to produce bizarre effects.
- */
- if_OPT_ISO_COLORS(screen, {
- ColorRes tmp2;
- EXCHANGE(screen->Acolors[0], screen->Acolors[7], tmp2);
- EXCHANGE(screen->Acolors[8], screen->Acolors[15], tmp2);
- });
-
- tmp = T_COLOR(screen, TEXT_BG);
- if (T_COLOR(screen, TEXT_CURSOR) == T_COLOR(screen, TEXT_FG))
- T_COLOR(screen, TEXT_CURSOR) = tmp;
- T_COLOR(screen, TEXT_BG) = T_COLOR(screen, TEXT_FG);
- T_COLOR(screen, TEXT_FG) = tmp;
-
- EXCHANGE(T_COLOR(screen, MOUSE_FG), T_COLOR(screen, MOUSE_BG), tmp);
- EXCHANGE(NormalGC(screen), ReverseGC(screen), tmpGC);
- EXCHANGE(NormalBoldGC(screen), ReverseBoldGC(screen), tmpGC);
-#ifndef NO_ACTIVE_ICON
- tmpGC = screen->iconVwin.normalGC;
- screen->iconVwin.normalGC = screen->iconVwin.reverseGC;
- screen->iconVwin.reverseGC = tmpGC;
-
- tmpGC = screen->iconVwin.normalboldGC;
- screen->iconVwin.normalboldGC = screen->iconVwin.reverseboldGC;
- screen->iconVwin.reverseboldGC = tmpGC;
-#endif /* NO_ACTIVE_ICON */
-
- recolor_cursor(screen->pointer_cursor,
- T_COLOR(screen, MOUSE_FG),
- T_COLOR(screen, MOUSE_BG));
- recolor_cursor(screen->arrow,
- T_COLOR(screen, MOUSE_FG),
- T_COLOR(screen, MOUSE_BG));
-
- termw->misc.re_verse = !termw->misc.re_verse;
-
- if (XtIsRealized((Widget) termw)) {
- XDefineCursor(screen->display, VWindow(screen), screen->pointer_cursor);
- }
-#if OPT_TEK4014
- if (tek)
- XDefineCursor(screen->display, tek, screen->arrow);
-#endif
-
- if (screen->scrollWidget)
- ScrollBarReverseVideo(screen->scrollWidget);
-
- if (XtIsRealized((Widget) termw)) {
- XSetWindowBackground(screen->display, VWindow(screen),
- T_COLOR(screen, TEXT_BG));
-
- /* the shell-window's background will be used in the first repainting
- * on resizing
- */
- XSetWindowBackground(screen->display, VShellWindow,
- T_COLOR(screen, TEXT_BG));
- }
-#if OPT_TEK4014
- TekReverseVideo(screen);
-#endif
- if (XtIsRealized((Widget) termw)) {
- XClearWindow(screen->display, VWindow(screen));
- ScrnRefresh(screen, 0, 0, MaxRows(screen),
- MaxCols(screen), False);
- }
-#if OPT_TEK4014
- if (screen->Tshow) {
- XClearWindow(screen->display, tek);
- TekExpose((Widget) NULL, (XEvent *) NULL, (Region) NULL);
- }
-#endif
- ReverseOldColors();
- update_reversevideo();
-}
-
-void
-recolor_cursor(Cursor cursor, /* X cursor ID to set */
- unsigned long fg, /* pixel indexes to look up */
- unsigned long bg) /* pixel indexes to look up */
-{
- TScreen *screen = &term->screen;
- Display *dpy = screen->display;
- XColor colordefs[2]; /* 0 is foreground, 1 is background */
-
- colordefs[0].pixel = fg;
- colordefs[1].pixel = bg;
- XQueryColors(dpy, DefaultColormap(dpy, DefaultScreen(dpy)),
- colordefs, 2);
- XRecolorCursor(dpy, cursor, colordefs, colordefs + 1);
- return;
-}
-
-#if OPT_RENDERFONT
-static XftColor *
-getColor(Pixel pixel)
-{
-#define CACHE_SIZE 4
- static struct {
- XftColor color;
- int use;
- } cache[CACHE_SIZE];
- static int use;
- int i;
- int oldest, oldestuse;
- XColor color;
-
- oldestuse = 0x7fffffff;
- oldest = 0;
- for (i = 0; i < CACHE_SIZE; i++) {
- if (cache[i].use) {
- if (cache[i].color.pixel == pixel) {
- cache[i].use = ++use;
- return &cache[i].color;
- }
- }
- if (cache[i].use < oldestuse) {
- oldestuse = cache[i].use;
- oldest = i;
- }
- }
- i = oldest;
- color.pixel = pixel;
- XQueryColor(term->screen.display, term->core.colormap, &color);
- cache[i].color.color.red = color.red;
- cache[i].color.color.green = color.green;
- cache[i].color.color.blue = color.blue;
- cache[i].color.color.alpha = 0xffff;
- cache[i].color.pixel = pixel;
- cache[i].use = ++use;
- return &cache[i].color;
-}
-
-/*
- * fontconfig/Xft combination prior to 2.2 has a problem with
- * CJK truetype 'double-width' (bi-width/monospace) fonts leading
- * to the 's p a c e d o u t' rendering. Consequently, we can't
- * rely on XftDrawString8/16 when one of those fonts is used.
- * Instead, we need to roll out our own using XftDrawCharSpec.
- * A patch in the same spirit (but in a rather different form)
- * was applied to gnome vte and gtk2 port of vim.
- * See http://bugzilla.mozilla.org/show_bug.cgi?id=196312
- */
-static void
-xtermXftDrawString(TScreen * screen,
- unsigned flags GCC_UNUSED,
- XftColor * color,
- XftFont * font,
- int x,
- int y,
- PAIRED_CHARS(Char * text, Char * text2),
- int len,
- int fwidth,
- int *deltax)
-{
-#if OPT_RENDERWIDE
- XftFont *wfont;
- int n;
- int ncells = 0; /* # of 'half-width' charcells */
- static XftCharSpec *sbuf;
- static int slen = 0;
- XftFont *lastFont = 0;
- XftFont *currFont = 0;
- int start = 0;
- int charWidth;
- FcChar32 wc;
- int fontnum = screen->menu_font_number;
-
- if (len == 0 || !(*text || *text2)) {
- return;
- }
-#if OPT_ISO_COLORS
- if ((flags & UNDERLINE)
- && screen->italicULMode
- && screen->renderWideItal[fontnum]) {
- wfont = screen->renderWideItal[fontnum];
- } else
-#endif
- if ((flags & BOLDATTR(screen))
- && screen->renderWideBold[fontnum]) {
- wfont = screen->renderWideBold[fontnum];
- } else {
- wfont = screen->renderWideNorm[fontnum];
- }
-
- if ((int) slen < len) {
- slen = (len + 1) * 2;
- sbuf = (XftCharSpec *) XtRealloc((char *) sbuf,
- slen * sizeof(XftCharSpec));
- }
-
- for (n = 0; n < len; n++) {
- if (text2)
- wc = *text++ | (*text2++ << 8);
- else
- wc = *text++;
- sbuf[n].ucs4 = wc;
- sbuf[n].x = x + fwidth * ncells;
- sbuf[n].y = y;
- charWidth = my_wcwidth((int) wc);
- currFont = (charWidth == 2 && wfont != 0) ? wfont : font;
- ncells += charWidth;
- if (lastFont != currFont) {
- if (lastFont != 0) {
- XftDrawCharSpec(screen->renderDraw,
- color,
- lastFont,
- sbuf + start,
- n - start);
- }
- start = n;
- lastFont = currFont;
- }
- }
- XftDrawCharSpec(screen->renderDraw,
- color,
- lastFont,
- sbuf + start,
- n - start);
-
- if (deltax)
- *deltax = ncells * fwidth;
-#else
-
- XftDrawString8(screen->renderDraw,
- color,
- font,
- x, y, (unsigned char *) text, len);
- if (deltax)
- *deltax = len * fwidth;
-#endif
-}
-#endif /* OPT_RENDERFONT */
-
-#define DrawX(col) x + (col * (font_width))
-#define DrawSegment(first,last) (void)drawXtermText(screen, flags|NOTRANSLATION, gc, DrawX(first), y, chrset, PAIRED_CHARS(text+first, text2+first), (unsigned)(last - first), on_wide)
-
-#if OPT_WIDE_CHARS
-/*
- * Actually this should be called "groff_workaround()" - for the places where
- * groff stomps on compatibility. Still, if enough people get used to it,
- * this might someday become a quasi-standard.
- */
-static int
-ucs_workaround(TScreen * screen,
- unsigned ch,
- unsigned flags,
- GC gc,
- int x,
- int y,
- int chrset,
- int on_wide)
-{
- int fixed = False;
-
- if (screen->wide_chars && screen->utf8_mode && ch > 256) {
- switch (ch) {
- case 0x2010: /* groff "-" */
- case 0x2011:
- case 0x2012:
- case 0x2013:
- case 0x2014:
- case 0x2015:
- case 0x2212: /* groff "\-" */
- ch = '-';
- fixed = True;
- break;
- case 0x2018: /* groff "`" */
- ch = '`';
- fixed = True;
- break;
- case 0x2019: /* groff ' */
- ch = '\'';
- fixed = True;
- break;
- case 0x201C: /* groff lq */
- case 0x201D: /* groff rq */
- ch = '"';
- fixed = True;
- break;
- }
- if (fixed) {
- Char text[2];
- Char text2[2];
-
- text[0] = ch;
- text2[0] = 0;
- drawXtermText(screen,
- flags,
- gc,
- x,
- y,
- chrset,
- PAIRED_CHARS(text, text2),
- 1,
- on_wide);
- }
- }
- return fixed;
-}
-#endif
-
-#if OPT_CLIP_BOLD
-/*
- * This special case is a couple of percent slower, but avoids a lot of pixel
- * trash in rxcurses' hanoi.cmd demo (e.g., 10x20 font).
- */
-#define beginClipping(screen,gc,pwidth,plength) \
- if (pwidth > 2) { \
- XRectangle clip; \
- int clip_x = x; \
- int clip_y = y - FontHeight(screen) + FontDescent(screen); \
- clip.x = 0; \
- clip.y = 0; \
- clip.height = FontHeight(screen); \
- clip.width = pwidth * plength; \
- XSetClipRectangles(screen->display, gc, \
- clip_x, clip_y, \
- &clip, 1, Unsorted); \
- }
-#define endClipping(screen,gc) \
- XSetClipMask(screen->display, gc, None)
-#else
-#define beginClipping(screen,gc,pwidth,plength) /* nothing */
-#define endClipping(screen,gc) /* nothing */
-#endif /* OPT_CLIP_BOLD */
-
-/*
- * Draws text with the specified combination of bold/underline. The return
- * value is the updated x position.
- */
-int
-drawXtermText(TScreen * screen,
- unsigned flags,
- GC gc,
- int x,
- int y,
- int chrset,
- PAIRED_CHARS(Char * text, Char * text2),
- Cardinal len,
- int on_wide)
-{
- int real_length = len;
- int underline_len;
- /* Intended width of the font to draw (as opposed to the actual width of
- the X font, and the width of the default font) */
- int font_width = ((flags & DOUBLEWFONT) ? 2 : 1) * screen->fnt_wide;
- Bool did_ul = False;
-
-#if OPT_WIDE_CHARS
- /*
- * It's simpler to pass in a null pointer for text2 in places where
- * we only use codes through 255. Fix text2 here so we can increment
- * it, etc.
- */
- if (text2 == 0) {
- static Char *dbuf;
- static unsigned dlen;
- if (dlen <= len) {
- dlen = (len + 1) * 2;
- dbuf = (Char *) XtRealloc((char *) dbuf, dlen);
- memset(dbuf, 0, dlen);
- }
- text2 = dbuf;
- }
-#endif
-#if OPT_DEC_CHRSET
- if (CSET_DOUBLE(chrset)) {
- /* We could try drawing double-size characters in the icon, but
- * given that the icon font is usually nil or nil2, there
- * doesn't seem to be much point.
- */
- GC gc2 = ((!IsIcon(screen) && screen->font_doublesize)
- ? xterm_DoubleGC((unsigned) chrset, flags, gc)
- : 0);
-
- TRACE(("DRAWTEXT%c[%4d,%4d] (%d) %d:%.*s\n",
- screen->cursor_state == OFF ? ' ' : '*',
- y, x, chrset, len, (int) len, text));
-
- if (gc2 != 0) { /* draw actual double-sized characters */
- /* Update the last-used cache of double-sized fonts */
- int inx = xterm_Double_index((unsigned) chrset, flags);
- XFontStruct *fs = screen->double_fonts[inx].fs;
- XRectangle rect, *rp = &rect;
- int nr = 1;
- int adjust;
-
- font_width *= 2;
- flags |= DOUBLEWFONT;
-
- rect.x = 0;
- rect.y = 0;
- rect.width = len * font_width;
- rect.height = FontHeight(screen);
-
- switch (chrset) {
- case CSET_DHL_TOP:
- rect.y = -(rect.height / 2);
- y -= rect.y;
- flags |= DOUBLEHFONT;
- break;
- case CSET_DHL_BOT:
- rect.y = (rect.height / 2);
- y -= rect.y;
- flags |= DOUBLEHFONT;
- break;
- default:
- nr = 0;
- break;
- }
-
- /*
- * Though it is the right "size", a given bold font may
- * be shifted up by a pixel or two. Shift it back into
- * the clipping rectangle.
- */
- if (nr != 0) {
- adjust = fs->ascent
- + fs->descent
- - (2 * FontHeight(screen));
- rect.y -= adjust;
- y += adjust;
- }
-
- if (nr)
- XSetClipRectangles(screen->display, gc2,
- x, y, rp, nr, YXBanded);
- else
- XSetClipMask(screen->display, gc2, None);
-
- /* Call ourselves recursively with the new gc */
-
- /*
- * If we're trying to use proportional font, or if the
- * font server didn't give us what we asked for wrt
- * width, position each character independently.
- */
- if (screen->fnt_prop
- || (fs->min_bounds.width != fs->max_bounds.width)
- || (fs->min_bounds.width != 2 * FontWidth(screen))) {
- /* It is hard to fall-through to the main
- branch: in a lot of places the check
- for the cached font info is for
- normal/bold fonts only. */
- while (len--) {
- x = drawXtermText(screen, flags, gc2,
- x, y, 0,
- PAIRED_CHARS(text++, text2++),
- 1, on_wide);
- x += FontWidth(screen);
- }
- } else {
- x = drawXtermText(screen, flags, gc2,
- x, y, 0,
- PAIRED_CHARS(text, text2),
- len, on_wide);
- x += len * FontWidth(screen);
- }
-
- TRACE(("drawtext [%4d,%4d]\n", y, x));
- } else { /* simulate double-sized characters */
-#if OPT_WIDE_CHARS
- Char *wide = 0;
-#endif
- unsigned need = 2 * len;
- Char *temp = TypeMallocN(Char, need);
- unsigned n = 0;
- if_OPT_WIDE_CHARS(screen, {
- wide = TypeMallocN(Char, need);
- });
- while (len--) {
- if_OPT_WIDE_CHARS(screen, {
- wide[n] = *text2++;
- wide[n + 1] = 0;
- });
- temp[n++] = *text++;
- temp[n++] = ' ';
- }
- x = drawXtermText(screen,
- flags,
- gc,
- x, y,
- 0,
- PAIRED_CHARS(temp, wide),
- n,
- on_wide);
- free(temp);
- if_OPT_WIDE_CHARS(screen, {
- free(wide);
- });
- }
- return x;
- }
-#endif
-#if OPT_RENDERFONT
- if (UsingRenderFont(term)) {
- Display *dpy = screen->display;
- XftFont *font;
- XGCValues values;
- int fontnum = screen->menu_font_number;
-
- if (!screen->renderDraw) {
- int scr;
- Drawable draw = VWindow(screen);
- Visual *visual;
-
- scr = DefaultScreen(dpy);
- visual = DefaultVisual(dpy, scr);
- screen->renderDraw = XftDrawCreate(dpy, draw, visual,
- DefaultColormap(dpy, scr));
- }
-#if OPT_ISO_COLORS
- if ((flags & UNDERLINE)
- && screen->italicULMode
- && screen->renderFontItal[fontnum]) {
- font = screen->renderFontItal[fontnum];
- did_ul = True;
- } else
-#endif
- if ((flags & BOLDATTR(screen))
- && screen->renderFontBold[fontnum]) {
- font = screen->renderFontBold[fontnum];
- } else {
- font = screen->renderFontNorm[fontnum];
- }
- XGetGCValues(dpy, gc, GCForeground | GCBackground, &values);
- if (!(flags & NOBACKGROUND))
- XftDrawRect(screen->renderDraw,
- getColor(values.background),
- x, y,
- len * FontWidth(screen),
- (unsigned) FontHeight(screen));
-
- y += font->ascent;
-#if OPT_BOX_CHARS
- if (!screen->force_box_chars) {
- /* adding code to substitute simulated line-drawing characters */
- int last, first = 0;
- Dimension old_wide, old_high = 0;
- int curX = x;
-
- for (last = 0; last < (int) len; last++) {
- unsigned ch = text[last];
- int deltax = 0;
-
- /*
- * If we're reading UTF-8 from the client, we may have a
- * line-drawing character. Translate it back to our box-code
- * if it is really a line-drawing character (since the
- * fonts used by Xft generally do not have correct glyphs),
- * or if Xft can tell us that the glyph is really missing.
- */
- if_OPT_WIDE_CHARS(screen, {
- unsigned full = (ch | (text2[last] << 8));
- unsigned part = ucs2dec(full);
- if (xtermIsDecGraphic(part) &&
- (xtermIsLineDrawing(part)
- || xtermXftMissing(term, font, full)))
- ch = part;
- else
- ch = full;
- });
- /*
- * If we have one of our box-codes, draw it directly.
- */
- if (xtermIsDecGraphic(ch)) {
- /* line drawing character time */
- if (last > first) {
- xtermXftDrawString(screen, flags,
- getColor(values.foreground),
- font, curX, y,
- PAIRED_CHARS(text + first,
- text2 + first),
- last - first,
- FontWidth(screen),
- &deltax);
- curX += deltax;
- }
- old_wide = screen->fnt_wide;
- old_high = screen->fnt_high;
- screen->fnt_wide = FontWidth(screen);
- screen->fnt_high = FontHeight(screen);
- xtermDrawBoxChar(term, ch, flags, gc,
- curX, y - FontAscent(screen));
- curX += FontWidth(screen);
- screen->fnt_wide = old_wide;
- screen->fnt_high = old_high;
- first = last + 1;
- }
- }
- if (last > first) {
- xtermXftDrawString(screen, flags,
- getColor(values.foreground),
- font, curX, y,
- PAIRED_CHARS(text + first, text2 + first),
- last - first,
- FontWidth(screen),
- NULL);
- }
- } else
-#endif /* OPT_BOX_CHARS */
- {
- xtermXftDrawString(screen, flags,
- getColor(values.foreground),
- font, x, y, PAIRED_CHARS(text, text2),
- (int) len, FontWidth(screen), NULL);
- }
-
- if ((flags & UNDERLINE) && screen->underline && !did_ul) {
- if (FontDescent(screen) > 1)
- y++;
- XDrawLine(screen->display, VWindow(screen), gc,
- x, y,
- x + (int) len * FontWidth(screen) - 1,
- y);
- }
- return x + len * FontWidth(screen);
- }
-#endif /* OPT_RENDERFONT */
- /*
- * If we're asked to display a proportional font, do this with a fixed
- * pitch. Yes, it's ugly. But we cannot distinguish the use of xterm
- * as a dumb terminal vs its use as in fullscreen programs such as vi.
- * Hint: do not try to use a proportional font in the icon.
- */
- if (!IsIcon(screen) && !(flags & CHARBYCHAR) && screen->fnt_prop) {
- int adj, width;
- GC fillGC = gc; /* might be cursorGC */
- XFontStruct *fs = ((flags & BOLDATTR(screen))
- ? BoldFont(screen)
- : NormalFont(screen));
-
-#define GC_PAIRS(a,b) \
- if (gc == a) fillGC = b; \
- if (gc == b) fillGC = a
-
- /*
- * Fill the area where we'll write the characters, otherwise
- * we'll get gaps between them. The cursor is a special case,
- * because the XFillRectangle call only uses the foreground,
- * while we've set the cursor color in the background. So we
- * need a special GC for that.
- */
- if (gc == screen->cursorGC
- || gc == screen->reversecursorGC)
- fillGC = screen->fillCursorGC;
- GC_PAIRS(NormalGC(screen), ReverseGC(screen));
- GC_PAIRS(NormalBoldGC(screen), ReverseBoldGC(screen));
-
- if (!(flags & NOBACKGROUND))
- XFillRectangle(screen->display, VWindow(screen), fillGC,
- x, y,
- len * FontWidth(screen),
- (unsigned) FontHeight(screen));
-
- while (len--) {
- width = XTextWidth(fs, (char *) text, 1);
- adj = (FontWidth(screen) - width) / 2;
- (void) drawXtermText(screen, flags | NOBACKGROUND | CHARBYCHAR,
- gc, x + adj, y, chrset,
- PAIRED_CHARS(text++, text2++), 1, on_wide);
- x += FontWidth(screen);
- }
- return x;
- }
-#if OPT_BOX_CHARS
- /* If the font is incomplete, draw some substitutions */
- if (!IsIcon(screen)
- && !(flags & NOTRANSLATION)
- && (!screen->fnt_boxes || screen->force_box_chars)) {
- /* Fill in missing box-characters.
- Find regions without missing characters, and draw
- them calling ourselves recursively. Draw missing
- characters via xtermDrawBoxChar(). */
- XFontStruct *font = ((flags & BOLD)
- ? BoldFont(screen)
- : NormalFont(screen));
- int last, first = 0;
- for (last = 0; last < (int) len; last++) {
- unsigned ch = text[last];
- Bool isMissing;
-#if OPT_WIDE_CHARS
- if (text2 != 0)
- ch |= (text2[last] << 8);
- isMissing = (ch != HIDDEN_CHAR)
- && (xtermMissingChar(term, ch,
- ((on_wide || iswide((int) ch))
- && screen->fnt_dwd)
- ? screen->fnt_dwd
- : font));
-#else
- isMissing = xtermMissingChar(term, ch, font);
-#endif
- if (isMissing) {
- if (last > first)
- DrawSegment(first, last);
-#if OPT_WIDE_CHARS
- if (!ucs_workaround(screen, ch, flags, gc, DrawX(last), y,
- chrset, on_wide))
-#endif
- xtermDrawBoxChar(term, ch, flags, gc, DrawX(last), y);
- first = last + 1;
- }
- }
- if (last <= first) {
- return x + real_length * FontWidth(screen);
- }
- text += first;
-#if OPT_WIDE_CHARS
- text2 += first;
-#endif
- len = last - first;
- flags |= NOTRANSLATION;
- if (DrawX(first) != x) {
- return drawXtermText(screen,
- flags,
- gc,
- DrawX(first),
- y,
- chrset,
- PAIRED_CHARS(text, text2),
- len,
- on_wide);
- }
- }
-#endif /* OPT_BOX_CHARS */
- /*
- * Behave as if the font has (maybe Unicode-replacements for) drawing
- * characters in the range 1-31 (either we were not asked to ignore them,
- * or the caller made sure that there is none). The only translation we do
- * in this branch is the removal of HIDDEN_CHAR (for the wide-char case).
- */
- TRACE(("drawtext%c[%4d,%4d] (%d) %d:%s\n",
- screen->cursor_state == OFF ? ' ' : '*',
- y, x, chrset, len,
- visibleChars(PAIRED_CHARS(text, text2), len)));
- y += FontAscent(screen);
-
-#if OPT_WIDE_CHARS
- if (screen->wide_chars || screen->unicode_font) {
- int ascent_adjust = 0;
- static XChar2b *sbuf;
- static Cardinal slen;
- int n;
- unsigned ch = text[0] | (text2[0] << 8);
- int wideness = (!IsIcon(screen)
- && ((on_wide || iswide((int) ch) != 0)
- && (screen->fnt_dwd != NULL)));
- unsigned char *endtext = text + len;
- if (slen < len) {
- slen = (len + 1) * 2;
- sbuf = (XChar2b *) XtRealloc((char *) sbuf, slen * sizeof(*sbuf));
- }
- for (n = 0; n < (int) len; n++) {
- sbuf[n].byte2 = *text;
- sbuf[n].byte1 = *text2;
-#if OPT_MINI_LUIT
-#define UCS2SBUF(n,value) sbuf[n].byte2 = (value & 0xff);\
- sbuf[n].byte1 = (value >> 8)
-#define Map2Sbuf(n,from,to) (*text == from) { UCS2SBUF(n,to); }
- if (screen->latin9_mode && !screen->utf8_mode && *text2 == 0) {
-
- /* see http://www.cs.tut.fi/~jkorpela/latin9.html */
- /* *INDENT-OFF* */
- if Map2Sbuf(n, 0xa4, 0x20ac)
- else if Map2Sbuf(n, 0xa6, 0x0160)
- else if Map2Sbuf(n, 0xa8, 0x0161)
- else if Map2Sbuf(n, 0xb4, 0x017d)
- else if Map2Sbuf(n, 0xb8, 0x017e)
- else if Map2Sbuf(n, 0xbc, 0x0152)
- else if Map2Sbuf(n, 0xbd, 0x0153)
- else if Map2Sbuf(n, 0xbe, 0x0178)
- /* *INDENT-ON* */
-
- }
- if (screen->unicode_font
- && *text2 == 0
- && (*text == 0x7f || *text < 0x20)) {
- int ni = dec2ucs(*text == 0x7f ? 0 : *text);
- UCS2SBUF(n, ni);
- }
-#endif /* OPT_MINI_LUIT */
- text++;
- text2++;
- if (wideness) {
- /* filter out those pesky fake characters. */
- while (text < endtext
- && *text == HIDDEN_HI
- && *text2 == HIDDEN_LO) {
- text++;
- text2++;
- len--;
- }
- }
- }
- /* This is probably wrong. But it works. */
- underline_len = len;
-
- /* Set the drawing font */
- if (flags & (DOUBLEHFONT | DOUBLEWFONT)) {
- ; /* Do nothing: font is already set */
- } else if (wideness
- && (screen->fnt_dwd->fid || screen->fnt_dwdb->fid)) {
- underline_len = real_length = len * 2;
- if ((flags & BOLDATTR(screen)) != 0
- && screen->fnt_dwdb->fid) {
- XSetFont(screen->display, gc, screen->fnt_dwdb->fid);
- ascent_adjust = (screen->fnt_dwdb->ascent
- - NormalFont(screen)->ascent);
- } else {
- XSetFont(screen->display, gc, screen->fnt_dwd->fid);
- ascent_adjust = (screen->fnt_dwd->ascent
- - NormalFont(screen)->ascent);
- }
- /* fix ascent */
- } else if ((flags & BOLDATTR(screen)) != 0
- && BoldFont(screen)->fid) {
- XSetFont(screen->display, gc, BoldFont(screen)->fid);
- } else {
- XSetFont(screen->display, gc, NormalFont(screen)->fid);
- }
-
- if (flags & NOBACKGROUND)
- XDrawString16(screen->display,
- VWindow(screen), gc,
- x, y + ascent_adjust,
- sbuf, n);
- else
- XDrawImageString16(screen->display,
- VWindow(screen), gc,
- x, y + ascent_adjust,
- sbuf, n);
-
- if ((flags & BOLDATTR(screen)) && screen->enbolden) {
- beginClipping(screen, gc, font_width, len);
- XDrawString16(screen->display, VWindow(screen), gc,
- x + 1, y + ascent_adjust, sbuf, n);
- endClipping(screen, gc);
- }
-
- } else
-#endif /* OPT_WIDE_CHARS */
- {
- int length = len; /* X should have used unsigned */
-
- if (flags & NOBACKGROUND)
- XDrawString(screen->display, VWindow(screen), gc,
- x, y, (char *) text, length);
- else
- XDrawImageString(screen->display, VWindow(screen), gc,
- x, y, (char *) text, length);
- underline_len = length;
- if ((flags & BOLDATTR(screen)) && screen->enbolden) {
- beginClipping(screen, gc, font_width, length);
- XDrawString(screen->display, VWindow(screen), gc,
- x + 1, y, (char *) text, length);
- endClipping(screen, gc);
- }
- }
-
- if ((flags & UNDERLINE) && screen->underline && !did_ul) {
- if (FontDescent(screen) > 1)
- y++;
- XDrawLine(screen->display, VWindow(screen), gc,
- x, y, x + underline_len * font_width - 1, y);
- }
-
- return x + real_length * FontWidth(screen);
-}
-
-/* set up size hints for window manager; min 1 char by 1 char */
-void
-xtermSizeHints(XtermWidget xw, XSizeHints * sizehints, int scrollbarWidth)
-{
- TScreen *screen = &xw->screen;
-
- TRACE(("xtermSizeHints\n"));
- TRACE((" border %d\n", xw->core.border_width));
- TRACE((" scrollbar %d\n", scrollbarWidth));
-
- sizehints->base_width = 2 * screen->border + scrollbarWidth;
- sizehints->base_height = 2 * screen->border;
-
-#if OPT_TOOLBAR
- TRACE((" toolbar %d\n", ToolbarHeight(xw)));
-
- sizehints->base_height += ToolbarHeight(xw);
- sizehints->base_height += xw->core.border_width * 2;
- sizehints->base_width += xw->core.border_width * 2;
-#endif
-
- sizehints->width_inc = FontWidth(screen);
- sizehints->height_inc = FontHeight(screen);
- sizehints->min_width = sizehints->base_width + sizehints->width_inc;
- sizehints->min_height = sizehints->base_height + sizehints->height_inc;
-
- sizehints->width = MaxCols(screen) * FontWidth(screen) + sizehints->min_width;
- sizehints->height = MaxRows(screen) * FontHeight(screen) + sizehints->min_height;
-
- sizehints->flags |= (PSize | PBaseSize | PMinSize | PResizeInc);
-
- TRACE_HINTS(sizehints);
-}
-
-/*
- * Returns a GC, selected according to the font (reverse/bold/normal) that is
- * required for the current position (implied). The GC is updated with the
- * current screen foreground and background colors.
- */
-GC
-updatedXtermGC(TScreen * screen, unsigned flags, unsigned fg_bg, Bool hilite)
-{
- int my_fg = extract_fg(fg_bg, flags);
- int my_bg = extract_bg(fg_bg, flags);
- Pixel fg_pix = getXtermForeground(flags, my_fg);
- Pixel bg_pix = getXtermBackground(flags, my_bg);
- Pixel xx_pix;
-#if OPT_HIGHLIGHT_COLOR
- Pixel hi_pix = T_COLOR(screen, HIGHLIGHT_BG);
-#endif
- GC gc;
-
- checkVeryBoldColors(flags, my_fg);
-
- if (ReverseOrHilite(screen, flags, hilite)) {
- if (flags & BOLDATTR(screen))
- gc = ReverseBoldGC(screen);
- else
- gc = ReverseGC(screen);
-
-#if OPT_HIGHLIGHT_COLOR
- if (hi_pix != T_COLOR(screen, TEXT_FG)
- && hi_pix != fg_pix
- && hi_pix != bg_pix
- && hi_pix != term->dft_foreground) {
- bg_pix = fg_pix;
- fg_pix = hi_pix;
- }
-#endif
- xx_pix = bg_pix;
- bg_pix = fg_pix;
- fg_pix = xx_pix;
- } else {
- if (flags & BOLDATTR(screen))
- gc = NormalBoldGC(screen);
- else
- gc = NormalGC(screen);
-
- }
-
-#if OPT_BLINK_TEXT
- if ((screen->blink_state == ON) && (!screen->blink_as_bold) && (flags & BLINK)) {
- fg_pix = bg_pix;
- }
-#endif
-
- XSetForeground(screen->display, gc, fg_pix);
- XSetBackground(screen->display, gc, bg_pix);
- return gc;
-}
-
-/*
- * Resets the foreground/background of the GC returned by 'updatedXtermGC()'
- * to the values that would be set in SGR_Foreground and SGR_Background. This
- * duplicates some logic, but only modifies 1/4 as many GC's.
- */
-void
-resetXtermGC(TScreen * screen, unsigned flags, Bool hilite)
-{
- Pixel fg_pix = getXtermForeground(flags, term->cur_foreground);
- Pixel bg_pix = getXtermBackground(flags, term->cur_background);
- GC gc;
-
- checkVeryBoldColors(flags, term->cur_foreground);
-
- if (ReverseOrHilite(screen, flags, hilite)) {
- if (flags & BOLDATTR(screen))
- gc = ReverseBoldGC(screen);
- else
- gc = ReverseGC(screen);
-
- XSetForeground(screen->display, gc, bg_pix);
- XSetBackground(screen->display, gc, fg_pix);
-
- } else {
- if (flags & BOLDATTR(screen))
- gc = NormalBoldGC(screen);
- else
- gc = NormalGC(screen);
-
- XSetForeground(screen->display, gc, fg_pix);
- XSetBackground(screen->display, gc, bg_pix);
- }
-}
-
-#if OPT_ISO_COLORS
-/*
- * Extract the foreground-color index from a one-byte color pair. If we've got
- * BOLD or UNDERLINE color-mode active, those will be used.
- */
-unsigned
-extract_fg(unsigned color, unsigned flags)
-{
- unsigned fg = ExtractForeground(color);
-
- if (term->screen.colorAttrMode
- || (fg == ExtractBackground(color))) {
- if (term->screen.colorULMode && (flags & UNDERLINE))
- fg = COLOR_UL;
- if (term->screen.colorBDMode && (flags & BOLD))
- fg = COLOR_BD;
- if (term->screen.colorBLMode && (flags & BLINK))
- fg = COLOR_BL;
- }
- return fg;
-}
-
-/*
- * Extract the background-color index from a one-byte color pair.
- * If we've got INVERSE color-mode active, that will be used.
- */
-unsigned
-extract_bg(unsigned color, unsigned flags)
-{
- unsigned bg = ExtractBackground(color);
-
- if (term->screen.colorAttrMode
- || (bg == ExtractForeground(color))) {
- if (term->screen.colorRVMode && (flags & INVERSE))
- bg = COLOR_RV;
- }
- return bg;
-}
-
-/*
- * Combine the current foreground and background into a single 8-bit number.
- * Note that we're storing the SGR foreground, since cur_foreground may be set
- * to COLOR_UL, COLOR_BD or COLOR_BL, which would make the code larger than 8
- * bits.
- *
- * This assumes that fg/bg are equal when we override with one of the special
- * attribute colors.
- */
-unsigned
-makeColorPair(int fg, int bg)
-{
- unsigned my_bg = (bg >= 0) && (bg < NUM_ANSI_COLORS) ? (unsigned) bg : 0;
- unsigned my_fg = (fg >= 0) && (fg < NUM_ANSI_COLORS) ? (unsigned) fg : my_bg;
-#if OPT_EXT_COLORS
- return (my_fg << 8) | my_bg;
-#else
- return (my_fg << 4) | my_bg;
-#endif
-}
-
-/*
- * Using the "current" SGR background, clear a rectangle.
- */
-void
-ClearCurBackground(TScreen * screen,
- int top,
- int left,
- unsigned height,
- unsigned width)
-{
- XSetWindowBackground(screen->display,
- VWindow(screen),
- getXtermBackground(term->flags, term->cur_background));
-
- XClearArea(screen->display, VWindow(screen),
- left, top, width, height, False);
-
- XSetWindowBackground(screen->display,
- VWindow(screen),
- getXtermBackground(term->flags, MAXCOLORS));
-}
-#endif /* OPT_ISO_COLORS */
-
-/*
- * Returns a single 8/16-bit number for the given cell
- */
-unsigned
-getXtermCell(TScreen * screen, int row, int col)
-{
- unsigned ch = SCRN_BUF_CHARS(screen, row)[col];
- if_OPT_WIDE_CHARS(screen, {
- ch |= (SCRN_BUF_WIDEC(screen, row)[col] << 8);
- });
- return ch;
-}
-
-/*
- * Sets a single 8/16-bit number for the given cell
- */
-void
-putXtermCell(TScreen * screen, int row, int col, int ch)
-{
- SCRN_BUF_CHARS(screen, row)[col] = ch;
- if_OPT_WIDE_CHARS(screen, {
- SCRN_BUF_WIDEC(screen, row)[col] = (ch >> 8);
- SCRN_BUF_COM1L(screen, row)[col] = 0;
- SCRN_BUF_COM1H(screen, row)[col] = 0;
- SCRN_BUF_COM2L(screen, row)[col] = 0;
- SCRN_BUF_COM2H(screen, row)[col] = 0;
- });
-}
-
-#if OPT_WIDE_CHARS
-unsigned
-getXtermCellComb1(TScreen * screen, int row, int col)
-{
- unsigned ch = SCRN_BUF_COM1L(screen, row)[col];
- ch |= (SCRN_BUF_COM1H(screen, row)[col] << 8);
- return ch;
-}
-
-unsigned
-getXtermCellComb2(TScreen * screen, int row, int col)
-{
- unsigned ch = SCRN_BUF_COM2L(screen, row)[col];
- ch |= (SCRN_BUF_COM2H(screen, row)[col] << 8);
- return ch;
-}
-
-/*
- * Add a combining character for the given cell
- */
-void
-addXtermCombining(TScreen * screen, int row, int col, unsigned ch)
-{
- if (!SCRN_BUF_COM1L(screen, row)[col]
- && !SCRN_BUF_COM1H(screen, row)[col]) {
- SCRN_BUF_COM1L(screen, row)[col] = ch & 0xff;
- SCRN_BUF_COM1H(screen, row)[col] = ch >> 8;
- } else if (!SCRN_BUF_COM2H(screen, row)[col]) {
- SCRN_BUF_COM2L(screen, row)[col] = ch & 0xff;
- SCRN_BUF_COM2H(screen, row)[col] = ch >> 8;
- }
-}
-#endif
-
-#ifdef HAVE_CONFIG_H
-#ifdef USE_MY_MEMMOVE
-char *
-my_memmove(char *s1, char *s2, size_t n)
-{
- if (n != 0) {
- if ((s1 + n > s2) && (s2 + n > s1)) {
- static char *bfr;
- static size_t length;
- size_t j;
- if (length < n) {
- length = (n * 3) / 2;
- bfr = ((bfr != 0)
- ? TypeRealloc(char, length, bfr)
- : TypeMallocN(char, length));
- if (bfr == NULL)
- SysError(ERROR_MMALLOC);
- }
- for (j = 0; j < n; j++)
- bfr[j] = s2[j];
- s2 = bfr;
- }
- while (n-- != 0)
- s1[n] = s2[n];
- }
- return s1;
-}
-#endif /* USE_MY_MEMMOVE */
-
-#ifndef HAVE_STRERROR
-char *
-my_strerror(int n)
-{
- extern char *sys_errlist[];
- extern int sys_nerr;
- if (n > 0 && n < sys_nerr)
- return sys_errlist[n];
- return "?";
-}
-#endif
-#endif
-
-int
-char2lower(int ch)
-{
- if (isascii(ch) && isupper(ch)) { /* lowercasify */
-#ifdef _tolower
- ch = _tolower(ch);
-#else
- ch = tolower(ch);
-#endif
- }
- return ch;
-}
-
-void
-update_keyboard_type(void)
-{
- update_delete_del();
- update_old_fkeys();
- update_hp_fkeys();
- update_sco_fkeys();
- update_sun_fkeys();
- update_sun_kbd();
-}
-
-void
-set_keyboard_type(xtermKeyboardType type, Bool set)
-{
- xtermKeyboardType save = term->keyboard.type;
-
- TRACE(("set_keyboard_type(%s, %s) currently %s\n",
- visibleKeyboardType(type),
- BtoS(set),
- visibleKeyboardType(term->keyboard.type)));
- if (set) {
- term->keyboard.type = type;
- } else {
- term->keyboard.type = keyboardIsDefault;
- }
-
- if (save != term->keyboard.type) {
- update_keyboard_type();
- }
-}
-
-void
-toggle_keyboard_type(xtermKeyboardType type)
-{
- xtermKeyboardType save = term->keyboard.type;
-
- TRACE(("toggle_keyboard_type(%s) currently %s\n",
- visibleKeyboardType(type),
- visibleKeyboardType(term->keyboard.type)));
- if (term->keyboard.type == type) {
- term->keyboard.type = keyboardIsDefault;
- } else {
- term->keyboard.type = type;
- }
-
- if (save != term->keyboard.type) {
- update_keyboard_type();
- }
-}
-
-void
-init_keyboard_type(xtermKeyboardType type, Bool set)
-{
- static Bool wasSet = False;
-
- TRACE(("init_keyboard_type(%s, %s) currently %s\n",
- visibleKeyboardType(type),
- BtoS(set),
- visibleKeyboardType(term->keyboard.type)));
- if (set) {
- if (wasSet) {
- fprintf(stderr, "Conflicting keyboard type option (%u/%u)\n",
- term->keyboard.type, type);
- }
- term->keyboard.type = type;
- wasSet = True;
- update_keyboard_type();
- }
-}
-
-/*
- * If the keyboardType resource is set, use that, overriding the individual
- * boolean resources for different keyboard types.
- */
-void
-decode_keyboard_type(XTERM_RESOURCE * rp)
-{
-#define DATA(n, t, f) { n, t, XtOffsetOf(XTERM_RESOURCE, f) }
-#define FLAG(n) *(Boolean *)(((char *)rp) + table[n].offset)
- static struct {
- const char *name;
- xtermKeyboardType type;
- unsigned offset;
- } table[] = {
-#if OPT_HP_FUNC_KEYS
- DATA(NAME_HP_KT, keyboardIsHP, hpFunctionKeys),
-#endif
-#if OPT_SCO_FUNC_KEYS
- DATA(NAME_SCO_KT, keyboardIsSCO, scoFunctionKeys),
-#endif
- DATA(NAME_SUN_KT, keyboardIsSun, sunFunctionKeys),
-#if OPT_SUNPC_KBD
- DATA(NAME_VT220_KT, keyboardIsVT220, sunKeyboard),
-#endif
- };
- Cardinal n;
-
- if (x_strcasecmp(rp->keyboardType, "unknown")) {
- Bool found = False;
- for (n = 0; n < XtNumber(table); ++n) {
- if (!x_strcasecmp(rp->keyboardType, table[n].name + 1)) {
- FLAG(n) = True;
- found = True;
- init_keyboard_type(table[n].type, FLAG(n));
- } else {
- FLAG(n) = False;
- }
- }
- if (!found) {
- fprintf(stderr,
- "KeyboardType resource \"%s\" not found\n",
- rp->keyboardType);
- }
- } else {
- for (n = 0; n < XtNumber(table); ++n)
- init_keyboard_type(table[n].type, FLAG(n));
- }
-#undef DATA
-#undef FLAG
-}
-
-#if OPT_WIDE_CHARS
-#if defined(HAVE_WCHAR_H) && defined(HAVE_WCWIDTH)
-/*
- * If xterm is running in a UTF-8 locale, it is still possible to encounter
- * old runtime configurations which yield incomplete or inaccurate data.
- */
-static Bool
-systemWcwidthOk(void)
-{
- wchar_t n;
- int oops = 0;
- int last = 1024;
-
- for (n = 0; n < last; ++n) {
- int system_code = wcwidth(n);
- int intern_code = mk_wcwidth(n);
-
- /*
- * Since mk_wcwidth() is designed to check for nonspacing characters,
- * and has rough range-checks for double-width characters, it will
- * generally not detect cases where a code has not been assigned.
- *
- * Some experimentation with GNU libc suggests that up to 1/4 of the
- * codes would differ, simply because the runtime library would have a
- * table listing the unassigned codes, and return -1 for those. If
- * mk_wcwidth() has no information about a code, it returns 1. On the
- * other hand, if the runtime returns a positive number, the two should
- * agree.
- *
- * The "up to" is measured for 4k, 8k, 16k of data. With only 1k, the
- * number of differences was only 77. However, that is only one
- * system, and this is only a sanity check to avoid using broken
- * libraries.
- */
- if ((system_code < 0 && intern_code >= 1)
- || (system_code >= 0 && intern_code != system_code)) {
- ++oops;
- }
- }
- TRACE(("systemWcwidthOk: %d/%d mismatches\n", oops, last));
- return (oops < (last / 4));
-}
-#endif /* HAVE_WCWIDTH */
-
-void
-decode_wcwidth(int mode)
-{
- switch (mode) {
- default:
-#if defined(HAVE_WCHAR_H) && defined(HAVE_WCWIDTH)
- if (xtermEnvUTF8() && systemWcwidthOk()) {
- my_wcwidth = wcwidth;
- TRACE(("using system wcwidth() function\n"));
- break;
- }
- /* FALLTHRU */
- case 2:
-#endif
- my_wcwidth = &mk_wcwidth;
- TRACE(("using MK wcwidth() function\n"));
- break;
- case 3:
- case 4:
- my_wcwidth = &mk_wcwidth_cjk;
- TRACE(("using MK-CJK wcwidth() function\n"));
- break;
- }
-}
-#endif