diff options
Diffstat (limited to 'app/xterm/util.c')
-rw-r--r-- | app/xterm/util.c | 671 |
1 files changed, 487 insertions, 184 deletions
diff --git a/app/xterm/util.c b/app/xterm/util.c index 3b4f2bc6c..7fabe1aa3 100644 --- a/app/xterm/util.c +++ b/app/xterm/util.c @@ -1,7 +1,7 @@ -/* $XTermId: util.c,v 1.554 2011/12/30 21:56:42 tom Exp $ */ +/* $XTermId: util.c,v 1.587 2012/05/10 11:06:37 tom Exp $ */ /* - * Copyright 1999-2010,2011 by Thomas E. Dickey + * Copyright 1999-2011,2012 by Thomas E. Dickey * * All Rights Reserved * @@ -87,7 +87,9 @@ static void horizontal_copy_area(XtermWidget xw, static void vertical_copy_area(XtermWidget xw, int firstline, int nlines, - int amount); + int amount, + int left, + int right); #if OPT_WIDE_CHARS unsigned first_widechar; @@ -175,72 +177,117 @@ FlushScroll(XtermWidget xw) int refreshheight; int scrolltop; int scrollheight; + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); + Boolean full_lines = (Boolean) ((left == 0) && (right == screen->max_col)); if (screen->cursor_state) HideCursor(); + + TRACE(("FlushScroll %s-lines scroll:%d refresh %d\n", + full_lines ? "full" : "partial", + screen->scroll_amt, + screen->refresh_amt)); + if (screen->scroll_amt > 0) { + /* + * Lines will be scrolled "up". + */ 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)) + scrollheight = screen->bot_marg - screen->top_marg - refreshheight + 1; + refreshtop = screen->bot_marg - refreshheight + 1 + shift; + i = screen->max_row - screen->scroll_amt + 1; + if (refreshtop > i) { refreshtop = i; + } + + /* + * If this is the normal (not alternate) screen, and the top margin is + * at the top of the screen, then we will shift full lines scrolled out + * of the scrolling region into the saved-lines. + */ if (screen->scrollWidget && !screen->whichBuf + && full_lines && screen->top_marg == 0) { scrolltop = 0; - if ((scrollheight += shift) > i) + scrollheight += shift; + if (scrollheight > 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->bot_marg - bot; + if (i > 0) { + refreshheight -= i; + if (refreshheight < screen->scroll_amt) { + refreshheight = screen->scroll_amt; + } + } + i = screen->savedlines; + if (i < screen->savelines) { + i += screen->scroll_amt; + if (i > 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) + i = bot - (screen->bot_marg - screen->refresh_amt + screen->scroll_amt); + if (i > 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) { + i = screen->top_marg + screen->scroll_amt - 1 - bot; + if (i > 0) { refreshtop += i; refreshheight -= i; } } } } else { + /* + * Lines will be scrolled "down". + */ refreshheight = -screen->refresh_amt; - scrollheight = screen->bot_marg - screen->top_marg - - refreshheight + 1; + scrollheight = screen->bot_marg - screen->top_marg - refreshheight + 1; refreshtop = screen->top_marg + shift; scrolltop = refreshtop + refreshheight; - if ((i = screen->bot_marg - bot) > 0) + i = screen->bot_marg - bot; + if (i > 0) { scrollheight -= i; - if ((i = screen->top_marg + refreshheight - 1 - bot) > 0) + } + i = screen->top_marg + refreshheight - 1 - bot; + if (i > 0) { refreshheight -= i; + } } - scrolling_copy_area(xw, scrolltop + screen->scroll_amt, - scrollheight, screen->scroll_amt); + + vertical_copy_area(xw, + scrolltop + screen->scroll_amt, + scrollheight, + screen->scroll_amt, + left, + right); ScrollSelection(screen, -(screen->scroll_amt), False); screen->scroll_amt = 0; screen->refresh_amt = 0; + if (refreshheight > 0) { ClearCurBackground(xw, - (int) refreshtop * FontHeight(screen) + screen->border, - (int) OriginX(screen), - (unsigned) (refreshheight * FontHeight(screen)), - (unsigned) Width(screen)); - ScrnRefresh(xw, refreshtop, 0, refreshheight, - MaxCols(screen), False); + refreshtop, + left, + (unsigned) refreshheight, + (unsigned) (right + 1 - left), + (unsigned) FontWidth(screen)); + ScrnRefresh(xw, + refreshtop, + 0, + refreshheight, + MaxCols(screen), + False); } return; } @@ -250,22 +297,22 @@ FlushScroll(XtermWidget xw) * include the current line. If false, the line is visible and we should * paint it now rather than waiting for the line to become visible. */ -int +static Bool AddToRefresh(XtermWidget xw) { TScreen *screen = TScreenOf(xw); int amount = screen->refresh_amt; int row = screen->cur_row; - int result; + Bool result; if (amount == 0) { - result = 0; + result = False; } else if (amount > 0) { int bottom; if (row == (bottom = screen->bot_marg) - amount) { screen->refresh_amt++; - result = 1; + result = True; } else { result = (row >= bottom - amount + 1 && row <= bottom); } @@ -275,7 +322,7 @@ AddToRefresh(XtermWidget xw) amount = -amount; if (row == (top = screen->top_marg) + amount) { screen->refresh_amt--; - result = 1; + result = True; } else { result = (row <= top + amount - 1 && row >= top); } @@ -313,7 +360,8 @@ AddToVisible(XtermWidget xw) /* * 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. + * If the selection is not entirely contained within the margins and not + * entirely outside the margins, clear it. */ static void adjustHiliteOnFwdScroll(XtermWidget xw, int amount, Bool all_lines) @@ -323,6 +371,8 @@ adjustHiliteOnFwdScroll(XtermWidget xw, int amount, Bool all_lines) ? (screen->bot_marg - screen->savelines) : screen->top_marg); int hi_row = screen->bot_marg; + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); TRACE2(("adjustSelection FWD %s by %d (%s)\n", screen->whichBuf ? "alternate" : "normal", @@ -336,8 +386,19 @@ adjustHiliteOnFwdScroll(XtermWidget xw, int amount, Bool all_lines) TRACE2((" margins %d..%d\n", screen->top_marg, screen->bot_marg)); TRACE2((" limits %d..%d\n", lo_row, hi_row)); - if (screen->startH.row >= lo_row - && screen->startH.row - amount < lo_row) { + if ((left > 0 || right < screen->max_col) && + ((screen->startH.row >= lo_row && + screen->startH.row - amount <= hi_row) || + (screen->endH.row >= lo_row && + screen->endH.row - amount <= hi_row))) { + /* + * This could be improved slightly by excluding the special case where + * the selection is on a single line outside left/right margins. + */ + TRACE2(("deselect because selection overlaps with scrolled partial-line\n")); + ScrnDisownSelection(xw); + } else if (screen->startH.row >= lo_row + && screen->startH.row - amount < lo_row) { /* truncate the selection because its start would move out of region */ if (lo_row + amount <= screen->endH.row) { TRACE2(("truncate selection by changing start %d.%d to %d.%d\n", @@ -359,8 +420,10 @@ adjustHiliteOnFwdScroll(XtermWidget xw, int amount, Bool all_lines) ScrnDisownSelection(xw); } } else if (screen->startH.row <= hi_row && screen->endH.row > hi_row) { + TRACE2(("deselect because selection straddles top-margin\n")); ScrnDisownSelection(xw); } else if (screen->startH.row < lo_row && screen->endH.row > lo_row) { + TRACE2(("deselect because selection straddles bottom-margin\n")); ScrnDisownSelection(xw); } @@ -429,6 +492,46 @@ adjustHiliteOnBakScroll(XtermWidget xw, int amount) } /* + * Move cells in LineData's on the current screen to simulate scrolling by the + * given amount of lines. + */ +static void +scrollInMargins(XtermWidget xw, int amount, int top) +{ + TScreen *screen = TScreenOf(xw); + LineData *src; + LineData *dst; + int row; + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); + int length = right + 1 - left; + + if (amount > 0) { + for (row = top; row <= screen->bot_marg - amount; ++row) { + if ((src = getLineData(screen, row + amount)) != 0 + && (dst = getLineData(screen, row)) != 0) { + CopyCells(screen, src, dst, left, length); + } + } + while (row <= screen->bot_marg) { + ClearCells(xw, 0, (unsigned) length, row, left); + ++row; + } + } else if (amount < 0) { + for (row = screen->bot_marg; row >= top - amount; --row) { + if ((src = getLineData(screen, row + amount)) != 0 + && (dst = getLineData(screen, row)) != 0) { + CopyCells(screen, src, dst, left, length); + } + } + while (row >= top) { + ClearCells(xw, 0, (unsigned) length, row, left); + --row; + } + } +} + +/* * 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. @@ -438,13 +541,15 @@ void xtermScroll(XtermWidget xw, int amount) { TScreen *screen = TScreenOf(xw); - int i = screen->bot_marg - screen->top_marg + 1; + int i; int shift; int bot; int refreshtop = 0; int refreshheight; int scrolltop; int scrollheight; + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); Boolean scroll_all_lines = (Boolean) (screen->scrollWidget && !screen->whichBuf && screen->top_marg == 0); @@ -457,6 +562,7 @@ xtermScroll(XtermWidget xw, int amount) if (screen->cursor_state) HideCursor(); + i = screen->bot_marg - screen->top_marg + 1; if (amount > i) amount = i; @@ -541,14 +647,20 @@ xtermScroll(XtermWidget xw, int amount) screen->scrolls++; } - scrolling_copy_area(xw, scrolltop + amount, scrollheight, amount); + vertical_copy_area(xw, + scrolltop + amount, + scrollheight, + amount, + left, + right); if (refreshheight > 0) { ClearCurBackground(xw, - (int) refreshtop * FontHeight(screen) + screen->border, - (int) OriginX(screen), - (unsigned) (refreshheight * FontHeight(screen)), - (unsigned) Width(screen)); + refreshtop, + left, + (unsigned) refreshheight, + (unsigned) (right + 1 - left), + (unsigned) FontWidth(screen)); if (refreshheight > shift) refreshheight = shift; } @@ -556,7 +668,9 @@ xtermScroll(XtermWidget xw, int amount) } if (amount > 0) { - if (scroll_all_lines) { + if (left > 0 || right < screen->max_col) { + scrollInMargins(xw, amount, screen->top_marg); + } else if (scroll_all_lines) { ScrnDeleteLine(xw, screen->saveBuf_index, screen->bot_marg + screen->savelines, @@ -572,8 +686,12 @@ xtermScroll(XtermWidget xw, int amount) } if (refreshheight > 0) { - ScrnRefresh(xw, refreshtop, 0, refreshheight, - MaxCols(screen), False); + ScrnRefresh(xw, + refreshtop, + left, + refreshheight, + right + 1 - left, + False); } screen->cursor_busy -= 1; @@ -598,18 +716,21 @@ void xtermColIndex(XtermWidget xw, Bool toLeft) { TScreen *screen = TScreenOf(xw); + int margin; if (toLeft) { - if (screen->cur_col) { + margin = ScrnLeftMargin(xw); + if (screen->cur_col > margin) { CursorBack(xw, 1); - } else { - xtermColScroll(xw, 1, False, 0); + } else if (screen->cur_col == margin) { + xtermColScroll(xw, 1, False, screen->cur_col); } } else { - if (screen->cur_col < screen->max_col) { - CursorForward(screen, 1); - } else { - xtermColScroll(xw, 1, True, 0); + margin = ScrnRightMargin(xw); + if (screen->cur_col < margin) { + CursorForward(xw, 1); + } else if (screen->cur_col == margin) { + xtermColScroll(xw, 1, True, ScrnLeftMargin(xw)); } } } @@ -620,27 +741,44 @@ xtermColIndex(XtermWidget xw, Bool toLeft) void xtermColScroll(XtermWidget xw, int amount, Bool toLeft, int at_col) { + TScreen *screen = TScreenOf(xw); + if (amount > 0) { - TScreen *screen = TScreenOf(xw); - int save_row = screen->cur_row; - int save_col = screen->cur_col; - int row; + int min_row; + int max_row; - screen->cur_col = at_col; - if (toLeft) { - for (row = 0; row <= screen->max_row; row++) { - screen->cur_row = row; - ScrnDeleteChar(xw, (unsigned) amount); - } + if (ScrnHaveRowMargins(screen)) { + min_row = screen->top_marg; + max_row = screen->bot_marg; } else { - for (row = 0; row <= screen->max_row; row++) { - screen->cur_row = row; - ScrnInsertChar(xw, (unsigned) amount); + min_row = 0; + max_row = screen->max_row; + } + + if (screen->cur_row >= min_row + && screen->cur_row <= max_row + && screen->cur_col >= screen->lft_marg + && screen->cur_col <= screen->rgt_marg) { + int save_row = screen->cur_row; + int save_col = screen->cur_col; + int row; + + screen->cur_col = at_col; + if (toLeft) { + for (row = min_row; row <= max_row; row++) { + screen->cur_row = row; + ScrnDeleteChar(xw, (unsigned) amount); + } + } else { + for (row = min_row; row <= max_row; row++) { + screen->cur_row = row; + ScrnInsertChar(xw, (unsigned) amount); + } } + screen->cur_row = save_row; + screen->cur_col = save_col; + xtermRepaint(xw); } - screen->cur_row = save_row; - screen->cur_col = save_col; - xtermRepaint(xw); } } @@ -661,6 +799,8 @@ RevScroll(XtermWidget xw, int amount) int refreshheight; int scrolltop; int scrollheight; + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); TRACE(("RevScroll count=%d\n", amount)); @@ -692,8 +832,7 @@ RevScroll(XtermWidget xw, int amount) shift = INX2ROW(screen, 0); bot = screen->max_row - shift; refreshheight = amount; - scrollheight = screen->bot_marg - screen->top_marg - - refreshheight + 1; + scrollheight = screen->bot_marg - screen->top_marg - refreshheight + 1; refreshtop = screen->top_marg + shift; scrolltop = refreshtop + refreshheight; if ((i = screen->bot_marg - bot) > 0) @@ -709,27 +848,165 @@ RevScroll(XtermWidget xw, int amount) screen->scrolls++; } - scrolling_copy_area(xw, scrolltop - amount, scrollheight, -amount); + vertical_copy_area(xw, + scrolltop - amount, + scrollheight, + -amount, + left, + right); if (refreshheight > 0) { ClearCurBackground(xw, - (int) refreshtop * FontHeight(screen) + screen->border, - (int) OriginX(screen), - (unsigned) (refreshheight * FontHeight(screen)), - (unsigned) Width(screen)); + refreshtop, + left, + (unsigned) refreshheight, + (unsigned) (right + 1 - left), + (unsigned) FontWidth(screen)); } } if (amount > 0) { - ScrnInsertLine(xw, - screen->visbuf, - screen->bot_marg, - screen->top_marg, - (unsigned) amount); + if (left > 0 || right < screen->max_col) { + scrollInMargins(xw, -amount, screen->top_marg); + } else { + ScrnInsertLine(xw, + screen->visbuf, + screen->bot_marg, + screen->top_marg, + (unsigned) amount); + } } screen->cursor_busy -= 1; return; } +#if OPT_ZICONBEEP +void +initZIconBeep(void) +{ + if (resource.zIconBeep > 100 || resource.zIconBeep < -100) { + resource.zIconBeep = 0; /* was 100, but I prefer to defaulting off. */ + xtermWarning("a number between -100 and 100 is required for zIconBeep. 0 used by default\n"); + } +} + +static void +setZIconBeep(XtermWidget xw) +{ + TScreen *screen = TScreenOf(xw); + + /* Flag icon name with "***" on window output when iconified. + */ + if (resource.zIconBeep && mapstate == IsUnmapped && !screen->zIconBeep_flagged) { + static char *icon_name; + static Arg args[] = + { + {XtNiconName, (XtArgVal) & icon_name} + }; + + icon_name = NULL; + XtGetValues(toplevel, args, XtNumber(args)); + + if (icon_name != NULL) { + screen->zIconBeep_flagged = True; + ChangeIconName(xw, icon_name); + } + xtermBell(xw, XkbBI_Info, 0); + } + mapstate = -1; +} + +/* + * If warning should be given then give it + */ +Boolean +showZIconBeep(XtermWidget xw, char *name) +{ + Boolean code = False; + + if (resource.zIconBeep && TScreenOf(xw)->zIconBeep_flagged) { + char *format = resource.zIconFormat; + char *newname = CastMallocN(char, strlen(name) + strlen(format) + 1); + if (!newname) { + xtermWarning("malloc failed in showZIconBeep\n"); + } else { + char *marker = strstr(format, "%s"); + char *result = newname; + if (marker != 0) { + size_t skip = (size_t) (marker - format); + if (skip) { + strncpy(result, format, skip); + result += skip; + } + strcpy(result, name); + strcat(result, marker + 2); + } else { + strcpy(result, format); + strcat(result, name); + } + ChangeGroup(xw, XtNiconName, newname); + free(newname); + } + code = True; + } + return code; +} + +/* + * Restore the icon name, resetting the state for zIconBeep. + */ +void +resetZIconBeep(XtermWidget xw) +{ + static char *icon_name; + static Arg args[] = + { + {XtNiconName, (XtArgVal) & icon_name} + }; + TScreen *screen = TScreenOf(xw); + + if (screen->zIconBeep_flagged) { + screen->zIconBeep_flagged = False; + icon_name = NULL; + XtGetValues(toplevel, args, XtNumber(args)); + if (icon_name != NULL) { + char *buf = CastMallocN(char, strlen(icon_name)); + if (buf == NULL) { + screen->zIconBeep_flagged = True; + } else { + char *format = resource.zIconFormat; + char *marker = strstr(format, "%s"); + Boolean found = False; + + if (marker != 0) { + if (marker == format + || !strncmp(icon_name, format, (size_t) (marker - format))) { + found = True; + strcpy(buf, icon_name + (marker - format)); + marker += 2; + if (*marker != '\0') { + size_t len_m = strlen(marker); + size_t len_b = strlen(buf); + if (len_m < len_b + && !strcmp(buf + len_b - len_m, marker)) { + buf[len_b - len_m] = '\0'; + } + } + } + } else if (!strncmp(icon_name, format, strlen(format))) { + strcpy(buf, icon_name + strlen(format)); + found = True; + } + if (found) + ChangeIconName(xw, buf); + free(buf); + } + } + } +} +#else +#define setZIconBeep(xw) /* nothing */ +#endif /* OPT_ZICONBEEP */ + /* * write a string str of length len onto the screen at * the current cursor position. update cursor position. @@ -757,7 +1034,7 @@ WriteText(XtermWidget xw, IChar * str, Cardinal len) } if (ScrnHaveSelection(screen) - && ScrnIsLineInSelection(screen, INX2ROW(screen, screen->cur_row))) { + && ScrnIsRowInSelection(screen, INX2ROW(screen, screen->cur_row))) { ScrnDisownSelection(xw); } @@ -816,28 +1093,8 @@ WriteText(XtermWidget xw, IChar * str, Cardinal len) } ScrnWriteText(xw, str, flags, fg_bg, len); - CursorForward(screen, (int) cells); -#if OPT_ZICONBEEP - /* Flag icon name with "***" on window output when iconified. - */ - if (resource.zIconBeep && mapstate == IsUnmapped && !screen->zIconBeep_flagged) { - static char *icon_name; - static Arg args[] = - { - {XtNiconName, (XtArgVal) & icon_name} - }; - - icon_name = NULL; - XtGetValues(toplevel, args, XtNumber(args)); - - if (icon_name != NULL) { - screen->zIconBeep_flagged = True; - ChangeIconName(xw, icon_name); - } - xtermBell(xw, XkbBI_Info, 0); - } - mapstate = -1; -#endif /* OPT_ZICONBEEP */ + CursorForward(xw, (int) cells); + setZIconBeep(xw); return; } @@ -857,8 +1114,12 @@ InsertLine(XtermWidget xw, int n) int refreshheight; int scrolltop; int scrollheight; + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); - if (!ScrnIsLineInMargins(screen, screen->cur_row)) + if (!ScrnIsRowInMargins(screen, screen->cur_row) + || screen->cur_col < left + || screen->cur_col > right) return; TRACE(("InsertLine count=%d\n", n)); @@ -867,12 +1128,12 @@ InsertLine(XtermWidget xw, int n) HideCursor(); if (ScrnHaveSelection(screen) - && ScrnAreLinesInSelection(screen, - INX2ROW(screen, screen->top_marg), - INX2ROW(screen, screen->cur_row - 1)) - && ScrnAreLinesInSelection(screen, - INX2ROW(screen, screen->cur_row), - INX2ROW(screen, screen->bot_marg))) { + && ScrnAreRowsInSelection(screen, + INX2ROW(screen, screen->top_marg), + INX2ROW(screen, screen->cur_row - 1)) + && ScrnAreRowsInSelection(screen, + INX2ROW(screen, screen->cur_row), + INX2ROW(screen, screen->bot_marg))) { ScrnDisownSelection(xw); } @@ -902,21 +1163,26 @@ InsertLine(XtermWidget xw, int n) scrollheight -= i; if ((i = screen->cur_row + refreshheight - 1 - bot) > 0) refreshheight -= i; - vertical_copy_area(xw, scrolltop - n, scrollheight, -n); + vertical_copy_area(xw, scrolltop - n, scrollheight, -n, left, right); if (refreshheight > 0) { ClearCurBackground(xw, - (int) refreshtop * FontHeight(screen) + screen->border, - (int) OriginX(screen), - (unsigned) (refreshheight * FontHeight(screen)), - (unsigned) Width(screen)); + refreshtop, + left, + (unsigned) refreshheight, + (unsigned) (right + 1 - left), + (unsigned) FontWidth(screen)); } } if (n > 0) { - ScrnInsertLine(xw, - screen->visbuf, - screen->bot_marg, - screen->cur_row, - (unsigned) n); + if (left > 0 || right < screen->max_col) { + scrollInMargins(xw, -n, screen->cur_row); + } else { + ScrnInsertLine(xw, + screen->visbuf, + screen->bot_marg, + screen->cur_row, + (unsigned) n); + } } } @@ -935,11 +1201,15 @@ DeleteLine(XtermWidget xw, int n) int refreshheight; int scrolltop; int scrollheight; + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); Boolean scroll_all_lines = (Boolean) (screen->scrollWidget && !screen->whichBuf && screen->cur_row == 0); - if (!ScrnIsLineInMargins(screen, screen->cur_row)) + if (!ScrnIsRowInMargins(screen, screen->cur_row) + || screen->cur_col < left + || screen->cur_col > right) return; TRACE(("DeleteLine count=%d\n", n)); @@ -951,9 +1221,9 @@ DeleteLine(XtermWidget xw, int n) n = i; } if (ScrnHaveSelection(screen) - && ScrnAreLinesInSelection(screen, - INX2ROW(screen, screen->cur_row), - INX2ROW(screen, screen->cur_row + n - 1))) { + && ScrnAreRowsInSelection(screen, + INX2ROW(screen, screen->cur_row), + INX2ROW(screen, screen->cur_row + n - 1))) { ScrnDisownSelection(xw); } @@ -972,18 +1242,21 @@ DeleteLine(XtermWidget xw, int n) /* adjust screen->buf */ if (n > 0) { - if (scroll_all_lines) + if (left > 0 || right < screen->max_col) { + scrollInMargins(xw, n, screen->cur_row); + } else if (scroll_all_lines) { ScrnDeleteLine(xw, screen->saveBuf_index, screen->bot_marg + screen->savelines, 0, (unsigned) n); - else + } else { ScrnDeleteLine(xw, screen->visbuf, screen->bot_marg, screen->cur_row, (unsigned) n); + } } /* repaint the screen, as needed */ @@ -1014,7 +1287,7 @@ DeleteLine(XtermWidget xw, int n) } } } - vertical_copy_area(xw, scrolltop + n, scrollheight, n); + vertical_copy_area(xw, scrolltop + n, scrollheight, n, left, right); if (shift > 0 && refreshheight > 0) { int rows = refreshheight; if (rows > shift) @@ -1025,10 +1298,11 @@ DeleteLine(XtermWidget xw, int n) } if (refreshheight > 0) { ClearCurBackground(xw, - (int) refreshtop * FontHeight(screen) + screen->border, - (int) OriginX(screen), - (unsigned) (refreshheight * FontHeight(screen)), - (unsigned) Width(screen)); + refreshtop, + left, + (unsigned) refreshheight, + (unsigned) (right + 1 - left), + (unsigned) FontWidth(screen)); } } } @@ -1043,6 +1317,8 @@ InsertChar(XtermWidget xw, unsigned n) LineData *ld; unsigned limit; int row = INX2ROW(screen, screen->cur_row); + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); if (screen->cursor_state) HideCursor(); @@ -1050,21 +1326,21 @@ InsertChar(XtermWidget xw, unsigned n) TRACE(("InsertChar count=%d\n", n)); if (ScrnHaveSelection(screen) - && ScrnIsLineInSelection(screen, row)) { + && ScrnIsRowInSelection(screen, row)) { ScrnDisownSelection(xw); } screen->do_wrap = False; - assert(screen->cur_col <= screen->max_col); - limit = (unsigned) (MaxCols(screen) - screen->cur_col); + limit = (unsigned) (right + 1 - screen->cur_col); if (n > limit) n = limit; - assert(n != 0); - if (AddToVisible(xw) - && (ld = getLineData(screen, screen->cur_row)) != 0) { - int col = MaxCols(screen) - (int) n; + if (screen->cur_col < left || screen->cur_col > right) { + n = 0; + } else if (AddToVisible(xw) + && (ld = getLineData(screen, screen->cur_row)) != 0) { + int col = right + 1 - (int) n; /* * If we shift part of a multi-column character, fill the rest @@ -1102,13 +1378,16 @@ InsertChar(XtermWidget xw, unsigned n) } ClearCurBackground(xw, - CursorY(screen, screen->cur_row), - LineCursorX(screen, ld, screen->cur_col), - (unsigned) FontHeight(screen), - n * (unsigned) LineFontWidth(screen, ld)); + screen->cur_row, + screen->cur_col, + 1, + n, + (unsigned) LineFontWidth(screen, ld)); + } + if (n != 0) { + /* adjust screen->buf */ + ScrnInsertChar(xw, n); } - /* adjust screen->buf */ - ScrnInsertChar(xw, n); } /* @@ -1121,6 +1400,8 @@ DeleteChar(XtermWidget xw, unsigned n) LineData *ld; unsigned limit; int row = INX2ROW(screen, screen->cur_row); + int left = ScrnLeftMargin(xw); + int right = ScrnRightMargin(xw); if (screen->cursor_state) HideCursor(); @@ -1128,21 +1409,21 @@ DeleteChar(XtermWidget xw, unsigned n) TRACE(("DeleteChar count=%d\n", n)); if (ScrnHaveSelection(screen) - && ScrnIsLineInSelection(screen, row)) { + && ScrnIsRowInSelection(screen, row)) { ScrnDisownSelection(xw); } screen->do_wrap = False; - assert(screen->cur_col <= screen->max_col); - limit = (unsigned) (MaxCols(screen) - screen->cur_col); + limit = (unsigned) (right + 1 - screen->cur_col); if (n > limit) n = limit; - assert(n != 0); - if (AddToVisible(xw) - && (ld = getLineData(screen, screen->cur_row)) != 0) { - int col = MaxCols(screen) - (int) n; + if (screen->cur_col < left || screen->cur_col > right) { + n = 0; + } else if (AddToVisible(xw) + && (ld = getLineData(screen, screen->cur_row)) != 0) { + int col = right + 1 - (int) n; /* * If we delete part of a multi-column character, fill the rest @@ -1166,10 +1447,11 @@ DeleteChar(XtermWidget xw, unsigned n) -((int) n)); ClearCurBackground(xw, - CursorY(screen, screen->cur_row), - LineCursorX(screen, ld, col), - (unsigned) FontHeight(screen), - n * (unsigned) LineFontWidth(screen, ld)); + screen->cur_row, + col, + 1, + n, + (unsigned) LineFontWidth(screen, ld)); } if (n != 0) { /* adjust screen->buf */ @@ -1204,10 +1486,11 @@ ClearAbove(XtermWidget xw) height = screen->max_row + 1; if ((height -= top) > 0) { ClearCurBackground(xw, - top * FontHeight(screen) + screen->border, - OriginX(screen), - (unsigned) (height * FontHeight(screen)), - (unsigned) (Width(screen))); + top, + 0, + (unsigned) height, + (unsigned) MaxCols(screen), + (unsigned) FontWidth(screen)); } } ClearBufRows(xw, 0, screen->cur_row - 1); @@ -1241,11 +1524,11 @@ ClearBelow(XtermWidget xw) FlushScroll(xw); if (++top <= screen->max_row) { ClearCurBackground(xw, - top * FontHeight(screen) + screen->border, - OriginX(screen), - (unsigned) ((screen->max_row - top + 1) - * FontHeight(screen)), - (unsigned) (Width(screen))); + top, + 0, + (unsigned) (screen->max_row - top + 1), + (unsigned) MaxCols(screen), + (unsigned) FontWidth(screen)); } } ClearBufRows(xw, screen->cur_row + 1, screen->max_row); @@ -1269,7 +1552,7 @@ ClearInLine2(XtermWidget xw, int flags, int row, int col, unsigned len) screen->startH.col)); if (ScrnHaveSelection(screen) - && ScrnIsLineInSelection(screen, row)) { + && ScrnIsRowInSelection(screen, row)) { ScrnDisownSelection(xw); } @@ -1328,10 +1611,11 @@ ClearInLine2(XtermWidget xw, int flags, int row, int col, unsigned len) && (ld = getLineData(screen, row)) != 0) { ClearCurBackground(xw, - CursorY(screen, row), - LineCursorX(screen, ld, col), - (unsigned) FontHeight(screen), - len * (unsigned) LineFontWidth(screen, ld)); + row, + col, + 1, + len, + (unsigned) LineFontWidth(screen, ld)); } if (len != 0) { @@ -1466,11 +1750,11 @@ ClearScreen(XtermWidget xw) if (screen->scroll_amt) FlushScroll(xw); ClearCurBackground(xw, - top * FontHeight(screen) + screen->border, - OriginX(screen), - (unsigned) ((screen->max_row - top + 1) - * FontHeight(screen)), - (unsigned) Width(screen)); + top, + 0, + (unsigned) (screen->max_row - top + 1), + (unsigned) MaxCols(screen), + (unsigned) FontWidth(screen)); } ClearBufRows(xw, 0, screen->max_row); } @@ -1680,18 +1964,21 @@ static void vertical_copy_area(XtermWidget xw, int firstline, /* line on screen to start copying at */ int nlines, - int amount) /* number of lines to move up (neg=down) */ + int amount, /* number of lines to move up (neg=down) */ + int left, + int right) { TScreen *screen = TScreenOf(xw); if (nlines > 0) { - int src_x = OriginX(screen); + int src_x = CursorX(screen, left); int src_y = firstline * FontHeight(screen) + screen->border; copy_area(xw, src_x, src_y, - (unsigned) Width(screen), + (unsigned) ((right + 1 - left) * FontWidth(screen)), (unsigned) (nlines * FontHeight(screen)), src_x, src_y - amount * FontHeight(screen)); + if (screen->show_wrap_marks) { LineData *ld; int row; @@ -1715,7 +2002,7 @@ scrolling_copy_area(XtermWidget xw, { if (nlines > 0) { - vertical_copy_area(xw, firstline, nlines, amount); + vertical_copy_area(xw, firstline, nlines, amount, 0, TScreenOf(xw)->max_col); } } @@ -3676,18 +3963,27 @@ ClearCurBackground(XtermWidget xw, int top, int left, unsigned height, - unsigned width) + unsigned width, + unsigned fw) { TScreen *screen = TScreenOf(xw); - TRACE(("ClearCurBackground(%d,%d,%d,%d) %d\n", + TRACE(("ClearCurBackground %d,%d %dx%d with %d\n", top, left, height, width, xw->cur_background)); + assert((int) width > 0); + assert((left + (int) width) <= screen->max_col + 1); + assert((int) height <= screen->max_row + 1); + if (VWindow(screen)) { set_background(xw, xw->cur_background); XClearArea(screen->display, VWindow(screen), - left, top, width, height, False); + CursorX2(screen, left, fw), + CursorY(screen, top), + (width * fw), + (height * (unsigned) FontHeight(screen)), + False); set_background(xw, -1); } @@ -3750,6 +4046,13 @@ addXtermCombining(TScreen * screen, int row, int col, unsigned ch) } } } + +unsigned +getXtermCombining(TScreen * screen, int row, int col, int off) +{ + LineData *ld = getLineData(screen, row); + return ld->combData[off][col]; +} #endif #ifdef HAVE_CONFIG_H |