cursor.c revision 4419d26b
14419d26bSmrg/* $XTermId: cursor.c,v 1.82 2022/02/13 18:20:53 tom Exp $ */ 2d522f475Smrg 3d522f475Smrg/* 44419d26bSmrg * Copyright 2002-2021,2022 by Thomas E. Dickey 54419d26bSmrg * 6d522f475Smrg * All Rights Reserved 74419d26bSmrg * 8d522f475Smrg * Permission is hereby granted, free of charge, to any person obtaining a 9d522f475Smrg * copy of this software and associated documentation files (the 10d522f475Smrg * "Software"), to deal in the Software without restriction, including 11d522f475Smrg * without limitation the rights to use, copy, modify, merge, publish, 12d522f475Smrg * distribute, sublicense, and/or sell copies of the Software, and to 13d522f475Smrg * permit persons to whom the Software is furnished to do so, subject to 14d522f475Smrg * the following conditions: 154419d26bSmrg * 16d522f475Smrg * The above copyright notice and this permission notice shall be included 17d522f475Smrg * in all copies or substantial portions of the Software. 184419d26bSmrg * 19d522f475Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20d522f475Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21d522f475Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22d522f475Smrg * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 23d522f475Smrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24d522f475Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25d522f475Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 264419d26bSmrg * 27d522f475Smrg * Except as contained in this notice, the name(s) of the above copyright 28d522f475Smrg * holders shall not be used in advertising or otherwise to promote the 29d522f475Smrg * sale, use or other dealings in this Software without prior written 30d522f475Smrg * authorization. 314419d26bSmrg * 32d522f475Smrg * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 33d522f475Smrg * 34d522f475Smrg * All Rights Reserved 35d522f475Smrg * 36d522f475Smrg * Permission to use, copy, modify, and distribute this software and its 37d522f475Smrg * documentation for any purpose and without fee is hereby granted, 38d522f475Smrg * provided that the above copyright notice appear in all copies and that 39d522f475Smrg * both that copyright notice and this permission notice appear in 40d522f475Smrg * supporting documentation, and that the name of Digital Equipment 41d522f475Smrg * Corporation not be used in advertising or publicity pertaining to 42d522f475Smrg * distribution of the software without specific, written prior permission. 43d522f475Smrg * 44d522f475Smrg * 45d522f475Smrg * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 46d522f475Smrg * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 47d522f475Smrg * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 48d522f475Smrg * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 49d522f475Smrg * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 50d522f475Smrg * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 51d522f475Smrg * SOFTWARE. 52d522f475Smrg */ 53d522f475Smrg 54d522f475Smrg/* cursor.c */ 55d522f475Smrg 56d522f475Smrg#include <xterm.h> 57d522f475Smrg#include <data.h> 58d522f475Smrg#include <menu.h> 59d522f475Smrg 60d522f475Smrg#include <assert.h> 61d522f475Smrg 62d522f475Smrg/* 63d522f475Smrg * Moves the cursor to the specified position, checking for bounds. 64d522f475Smrg * (this includes scrolling regions) 65d522f475Smrg * The origin is considered to be 0, 0 for this procedure. 66d522f475Smrg */ 67d522f475Smrgvoid 682e4f8982SmrgCursorSet(TScreen *screen, int row, int col, unsigned flags) 69d522f475Smrg{ 70d522f475Smrg int use_row = row; 710bd37d32Smrg int use_col = col; 720bd37d32Smrg int max_col = screen->max_col; 730bd37d32Smrg int max_row = screen->max_row; 740bd37d32Smrg 750bd37d32Smrg if (flags & ORIGIN) { 760bd37d32Smrg use_col += screen->lft_marg; 770bd37d32Smrg max_col = screen->rgt_marg; 780bd37d32Smrg } 790bd37d32Smrg use_col = (use_col < 0 ? 0 : use_col); 800bd37d32Smrg set_cur_col(screen, (use_col <= max_col ? use_col : max_col)); 81d522f475Smrg 82d522f475Smrg if (flags & ORIGIN) { 83d522f475Smrg use_row += screen->top_marg; 84d522f475Smrg max_row = screen->bot_marg; 85d522f475Smrg } 86d522f475Smrg use_row = (use_row < 0 ? 0 : use_row); 87d522f475Smrg set_cur_row(screen, (use_row <= max_row ? use_row : max_row)); 88d522f475Smrg 890bd37d32Smrg ResetWrap(screen); 900bd37d32Smrg 910bd37d32Smrg TRACE(("CursorSet(%d,%d) margins V[%d..%d] H[%d..%d] -> %d,%d %s\n", 92d522f475Smrg row, col, 93d522f475Smrg screen->top_marg, 94d522f475Smrg screen->bot_marg, 950bd37d32Smrg screen->lft_marg, 960bd37d32Smrg screen->rgt_marg, 97d522f475Smrg screen->cur_row, 98d522f475Smrg screen->cur_col, 992e4f8982Smrg ((flags & ORIGIN) ? "origin" : "normal"))); 100d522f475Smrg} 101d522f475Smrg 102d522f475Smrg/* 103d522f475Smrg * moves the cursor left n, no wrap around 104d522f475Smrg */ 105d522f475Smrgvoid 106d522f475SmrgCursorBack(XtermWidget xw, int n) 107d522f475Smrg{ 1080bd37d32Smrg#define WRAP_MASK (REVERSEWRAP | WRAPAROUND) 10920d2c4d2Smrg TScreen *screen = TScreenOf(xw); 1102e4f8982Smrg int rev; 1110bd37d32Smrg int left = ScrnLeftMargin(xw); 1120bd37d32Smrg int before = screen->cur_col; 113d522f475Smrg 1142e4f8982Smrg if ((rev = ((xw->flags & WRAP_MASK) == WRAP_MASK)) != 0 1150bd37d32Smrg && screen->do_wrap) { 116d522f475Smrg n--; 1170bd37d32Smrg } 1180bd37d32Smrg 1190bd37d32Smrg /* if the cursor is already before the left-margin, we have to let it go */ 1200bd37d32Smrg if (before < left) 1210bd37d32Smrg left = 0; 1220bd37d32Smrg 1230bd37d32Smrg if ((screen->cur_col -= n) < left) { 124d522f475Smrg if (rev) { 1252e4f8982Smrg int in_row = ScrnRightMargin(xw) - left + 1; 1262e4f8982Smrg int offset = (in_row * screen->cur_row) + screen->cur_col - left; 127f2e35a3aSmrg if ((before == left) && 128f2e35a3aSmrg ScrnIsColInMargins(screen, before) && 129f2e35a3aSmrg ScrnIsRowInMargins(screen, screen->cur_row) && 130f2e35a3aSmrg screen->cur_row == screen->top_marg) { 131f2e35a3aSmrg offset = (screen->bot_marg + 1) * in_row - 1; 132f2e35a3aSmrg } else if (offset < 0) { 1332e4f8982Smrg int length = in_row * MaxRows(screen); 1340bd37d32Smrg offset += ((-offset) / length + 1) * length; 135d522f475Smrg } 1360bd37d32Smrg set_cur_row(screen, (offset / in_row)); 1370bd37d32Smrg set_cur_col(screen, (offset % in_row) + left); 138f2e35a3aSmrg do_xevents(xw); 139d522f475Smrg } else { 1400bd37d32Smrg set_cur_col(screen, left); 141d522f475Smrg } 142d522f475Smrg } 1430bd37d32Smrg ResetWrap(screen); 144d522f475Smrg} 145d522f475Smrg 146d522f475Smrg/* 147d522f475Smrg * moves the cursor forward n, no wraparound 148d522f475Smrg */ 149d522f475Smrgvoid 1500bd37d32SmrgCursorForward(XtermWidget xw, int n) 151d522f475Smrg{ 1520bd37d32Smrg TScreen *screen = TScreenOf(xw); 153956cc18dSsnj#if OPT_DEC_CHRSET 154956cc18dSsnj LineData *ld = getLineData(screen, screen->cur_row); 155956cc18dSsnj#endif 156d522f475Smrg int next = screen->cur_col + n; 1570bd37d32Smrg int max; 1580bd37d32Smrg 1590bd37d32Smrg if (IsLeftRightMode(xw)) { 1600bd37d32Smrg max = screen->rgt_marg; 1610bd37d32Smrg if (screen->cur_col > max) 1620bd37d32Smrg max = screen->max_col; 1630bd37d32Smrg } else { 1640bd37d32Smrg max = LineMaxCol(screen, ld); 1650bd37d32Smrg } 166d522f475Smrg 167d522f475Smrg if (next > max) 168d522f475Smrg next = max; 169d522f475Smrg 170d522f475Smrg set_cur_col(screen, next); 1710bd37d32Smrg ResetWrap(screen); 172d522f475Smrg} 173d522f475Smrg 174d522f475Smrg/* 175d522f475Smrg * moves the cursor down n, no scrolling. 176d522f475Smrg * Won't pass bottom margin or bottom of screen. 177d522f475Smrg */ 178d522f475Smrgvoid 1792e4f8982SmrgCursorDown(TScreen *screen, int n) 180d522f475Smrg{ 181d522f475Smrg int max; 182d522f475Smrg int next = screen->cur_row + n; 183d522f475Smrg 184d522f475Smrg max = (screen->cur_row > screen->bot_marg ? 185d522f475Smrg screen->max_row : screen->bot_marg); 186d522f475Smrg if (next > max) 187d522f475Smrg next = max; 188d522f475Smrg if (next > screen->max_row) 189d522f475Smrg next = screen->max_row; 190d522f475Smrg 191d522f475Smrg set_cur_row(screen, next); 1920bd37d32Smrg ResetWrap(screen); 193d522f475Smrg} 194d522f475Smrg 195d522f475Smrg/* 196d522f475Smrg * moves the cursor up n, no linestarving. 197d522f475Smrg * Won't pass top margin or top of screen. 198d522f475Smrg */ 199d522f475Smrgvoid 2002e4f8982SmrgCursorUp(TScreen *screen, int n) 201d522f475Smrg{ 202d522f475Smrg int min; 203d522f475Smrg int next = screen->cur_row - n; 204d522f475Smrg 205d522f475Smrg min = ((screen->cur_row < screen->top_marg) 206d522f475Smrg ? 0 207d522f475Smrg : screen->top_marg); 208d522f475Smrg if (next < min) 209d522f475Smrg next = min; 210d522f475Smrg if (next < 0) 211d522f475Smrg next = 0; 212d522f475Smrg 213d522f475Smrg set_cur_row(screen, next); 2140bd37d32Smrg ResetWrap(screen); 215d522f475Smrg} 216d522f475Smrg 217d522f475Smrg/* 218d522f475Smrg * Moves cursor down amount lines, scrolls if necessary. 219d522f475Smrg * Won't leave scrolling region. No carriage return. 220d522f475Smrg */ 221d522f475Smrgvoid 222d522f475SmrgxtermIndex(XtermWidget xw, int amount) 223d522f475Smrg{ 22420d2c4d2Smrg TScreen *screen = TScreenOf(xw); 225d522f475Smrg 226d522f475Smrg /* 227d522f475Smrg * indexing when below scrolling region is cursor down. 228d522f475Smrg * if cursor high enough, no scrolling necessary. 229d522f475Smrg */ 230d522f475Smrg if (screen->cur_row > screen->bot_marg 2310bd37d32Smrg || screen->cur_row + amount <= screen->bot_marg 2320bd37d32Smrg || (IsLeftRightMode(xw) 2330bd37d32Smrg && !ScrnIsColInMargins(screen, screen->cur_col))) { 234d522f475Smrg CursorDown(screen, amount); 2350bd37d32Smrg } else { 2362e4f8982Smrg int j; 2370bd37d32Smrg CursorDown(screen, j = screen->bot_marg - screen->cur_row); 2380bd37d32Smrg xtermScroll(xw, amount - j); 239d522f475Smrg } 240d522f475Smrg} 241d522f475Smrg 242d522f475Smrg/* 243d522f475Smrg * Moves cursor up amount lines, reverse scrolls if necessary. 244d522f475Smrg * Won't leave scrolling region. No carriage return. 245d522f475Smrg */ 246d522f475Smrgvoid 247d522f475SmrgRevIndex(XtermWidget xw, int amount) 248d522f475Smrg{ 24920d2c4d2Smrg TScreen *screen = TScreenOf(xw); 250d522f475Smrg 251d522f475Smrg /* 252d522f475Smrg * reverse indexing when above scrolling region is cursor up. 253d522f475Smrg * if cursor low enough, no reverse indexing needed 254d522f475Smrg */ 255d522f475Smrg if (screen->cur_row < screen->top_marg 2560bd37d32Smrg || screen->cur_row - amount >= screen->top_marg 2570bd37d32Smrg || (IsLeftRightMode(xw) 2580bd37d32Smrg && !ScrnIsColInMargins(screen, screen->cur_col))) { 259d522f475Smrg CursorUp(screen, amount); 2600bd37d32Smrg } else { 2610bd37d32Smrg RevScroll(xw, amount - (screen->cur_row - screen->top_marg)); 2620bd37d32Smrg CursorUp(screen, screen->cur_row - screen->top_marg); 263d522f475Smrg } 264d522f475Smrg} 265d522f475Smrg 266d522f475Smrg/* 267d522f475Smrg * Moves Cursor To First Column In Line 268d522f475Smrg * (Note: xterm doesn't implement SLH, SLL which would affect use of this) 269d522f475Smrg */ 270d522f475Smrgvoid 2710bd37d32SmrgCarriageReturn(XtermWidget xw) 272d522f475Smrg{ 2730bd37d32Smrg TScreen *screen = TScreenOf(xw); 2740bd37d32Smrg int left = ScrnLeftMargin(xw); 2750bd37d32Smrg int col; 2760bd37d32Smrg 2770bd37d32Smrg if (xw->flags & ORIGIN) { 2780bd37d32Smrg col = left; 279e0a2b6dfSmrg } else if (screen->cur_col >= left) { 2800bd37d32Smrg col = left; 2810bd37d32Smrg } else { 2820bd37d32Smrg /* 2830bd37d32Smrg * If origin-mode is not active, it is possible to use cursor 2840bd37d32Smrg * addressing outside the margins. In that case we will go to the 2850bd37d32Smrg * first column rather than following the margin. 2860bd37d32Smrg */ 2870bd37d32Smrg col = 0; 2880bd37d32Smrg } 2890bd37d32Smrg 2900bd37d32Smrg set_cur_col(screen, col); 2910bd37d32Smrg ResetWrap(screen); 292f2e35a3aSmrg do_xevents(xw); 293d522f475Smrg} 294d522f475Smrg 295d522f475Smrg/* 296d522f475Smrg * When resizing the window, if we're showing the alternate screen, we still 297d522f475Smrg * have to adjust the saved cursor from the normal screen to account for 298d522f475Smrg * shifting of the saved-line region in/out of the viewable window. 299d522f475Smrg */ 300d522f475Smrgvoid 301d522f475SmrgAdjustSavedCursor(XtermWidget xw, int adjust) 302d522f475Smrg{ 30320d2c4d2Smrg TScreen *screen = TScreenOf(xw); 304d522f475Smrg 305956cc18dSsnj if (screen->whichBuf) { 306956cc18dSsnj SavedCursor *sc = &screen->sc[0]; 307d522f475Smrg 308d522f475Smrg if (adjust > 0) { 309d522f475Smrg TRACE(("AdjustSavedCursor %d -> %d\n", sc->row, sc->row - adjust)); 310d522f475Smrg sc->row += adjust; 311d522f475Smrg } 312d522f475Smrg } 313d522f475Smrg} 314d522f475Smrg 315d522f475Smrg/* 316d522f475Smrg * Save Cursor and Attributes 317d522f475Smrg */ 318d522f475Smrgvoid 3194419d26bSmrgCursorSave2(XtermWidget xw, SavedCursor * sc) 320d522f475Smrg{ 32120d2c4d2Smrg TScreen *screen = TScreenOf(xw); 322d522f475Smrg 323d522f475Smrg sc->saved = True; 324d522f475Smrg sc->row = screen->cur_row; 325d522f475Smrg sc->col = screen->cur_col; 326d522f475Smrg sc->flags = xw->flags; 327d522f475Smrg sc->curgl = screen->curgl; 328d522f475Smrg sc->curgr = screen->curgr; 329913cc679Smrg sc->wrap_flag = screen->do_wrap; 330d522f475Smrg#if OPT_ISO_COLORS 331d522f475Smrg sc->cur_foreground = xw->cur_foreground; 332d522f475Smrg sc->cur_background = xw->cur_background; 333d522f475Smrg sc->sgr_foreground = xw->sgr_foreground; 334f2e35a3aSmrg sc->sgr_38_xcolors = xw->sgr_38_xcolors; 335d522f475Smrg#endif 336f2e35a3aSmrg saveCharsets(screen, sc->gsets); 337d522f475Smrg} 338d522f475Smrg 3394419d26bSmrgvoid 3404419d26bSmrgCursorSave(XtermWidget xw) 3414419d26bSmrg{ 3424419d26bSmrg TScreen *screen = TScreenOf(xw); 3434419d26bSmrg CursorSave2(xw, &screen->sc[screen->whichBuf]); 3444419d26bSmrg} 3454419d26bSmrg 346d522f475Smrg/* 347d522f475Smrg * We save/restore all visible attributes, plus wrapping, origin mode, and the 348d522f475Smrg * selective erase attribute. 3494419d26bSmrg * 3504419d26bSmrg * This is documented, but some of the documentation is incorrect. 3514419d26bSmrg * 3524419d26bSmrg * Page 270 of the VT420 manual (2nd edition) says that DECSC saves these 3534419d26bSmrg * items: 3544419d26bSmrg * 3554419d26bSmrg * Cursor position 3564419d26bSmrg * * Character attributes set by the SGR command 3574419d26bSmrg * * Character sets (G0, G1, G2, or G3) currently in GL and GR 3584419d26bSmrg * * Wrap flag (autowrap or no autowrap) 3594419d26bSmrg * * State of origin mode (DECOM) 3604419d26bSmrg * * Selective erase attribute 3614419d26bSmrg * * Any single shift 2 (SS2) or single shift 3 (SS3) functions sent 3624419d26bSmrg * 3634419d26bSmrg * The VT520 manual has the same information (page 5-120). 3644419d26bSmrg * 3654419d26bSmrg * However, DEC 070 (29-June-1990), pages 5-186 to 5-191, describes 3664419d26bSmrg * save/restore operations, but makes no mention of "wrap". 3674419d26bSmrg * 3684419d26bSmrg * Mattias Engdegård, who has investigated wrapping behavior of different 3694419d26bSmrg * terminals, 3704419d26bSmrg * 3714419d26bSmrg * https://github.com/mattiase/wraptest 3724419d26bSmrg * 3734419d26bSmrg * states 3744419d26bSmrg * The LCF is saved/restored by the Save/Restore Cursor (DECSC/DECRC) 3754419d26bSmrg * control sequences. The DECAWM flag is not included in the state 3764419d26bSmrg * managed by these operations. 3774419d26bSmrg * 3784419d26bSmrg * DEC 070 does mention the ANSI color text extension saying that it, too, is 3794419d26bSmrg * saved/restored. 380d522f475Smrg */ 381913cc679Smrg#define DECSC_FLAGS (ATTRIBUTES|ORIGIN|PROTECTED) 382d522f475Smrg 383d522f475Smrg/* 384d522f475Smrg * Restore Cursor and Attributes 385d522f475Smrg */ 386d522f475Smrgvoid 3874419d26bSmrgCursorRestore2(XtermWidget xw, SavedCursor * sc) 388d522f475Smrg{ 38920d2c4d2Smrg TScreen *screen = TScreenOf(xw); 390d522f475Smrg 391d522f475Smrg /* Restore the character sets, unless we never did a save-cursor op. 392d522f475Smrg * In that case, we'll reset the character sets. 393d522f475Smrg */ 394d522f475Smrg if (sc->saved) { 395f2e35a3aSmrg restoreCharsets(screen, sc->gsets); 396d522f475Smrg screen->curgl = sc->curgl; 397d522f475Smrg screen->curgr = sc->curgr; 398d522f475Smrg } else { 399d522f475Smrg resetCharsets(screen); 400d522f475Smrg } 401d522f475Smrg 40220d2c4d2Smrg UIntClr(xw->flags, DECSC_FLAGS); 40320d2c4d2Smrg UIntSet(xw->flags, sc->flags & DECSC_FLAGS); 404f2e35a3aSmrg if ((xw->flags & ORIGIN)) { 405f2e35a3aSmrg CursorSet(screen, 406f2e35a3aSmrg sc->row - screen->top_marg, 407f2e35a3aSmrg ((xw->flags & LEFT_RIGHT) 408f2e35a3aSmrg ? sc->col - screen->lft_marg 409f2e35a3aSmrg : sc->col), 410f2e35a3aSmrg xw->flags); 411f2e35a3aSmrg } else { 412f2e35a3aSmrg CursorSet(screen, sc->row, sc->col, xw->flags); 413f2e35a3aSmrg } 414913cc679Smrg screen->do_wrap = sc->wrap_flag; /* after CursorSet/ResetWrap */ 415d522f475Smrg 416d522f475Smrg#if OPT_ISO_COLORS 417d522f475Smrg xw->sgr_foreground = sc->sgr_foreground; 418f2e35a3aSmrg xw->sgr_38_xcolors = sc->sgr_38_xcolors; 4192e4f8982Smrg SGR_Foreground(xw, (xw->flags & FG_COLOR) ? sc->cur_foreground : -1); 4202e4f8982Smrg SGR_Background(xw, (xw->flags & BG_COLOR) ? sc->cur_background : -1); 421d522f475Smrg#endif 422d522f475Smrg} 423d522f475Smrg 4244419d26bSmrgvoid 4254419d26bSmrgCursorRestore(XtermWidget xw) 4264419d26bSmrg{ 4274419d26bSmrg TScreen *screen = TScreenOf(xw); 4284419d26bSmrg CursorRestore2(xw, &screen->sc[screen->whichBuf]); 4294419d26bSmrg} 4304419d26bSmrg 431d522f475Smrg/* 432d522f475Smrg * Move the cursor to the first column of the n-th next line. 433d522f475Smrg */ 434d522f475Smrgvoid 4350bd37d32SmrgCursorNextLine(XtermWidget xw, int count) 436d522f475Smrg{ 4370bd37d32Smrg TScreen *screen = TScreenOf(xw); 4380bd37d32Smrg 439d522f475Smrg CursorDown(screen, count < 1 ? 1 : count); 4400bd37d32Smrg CarriageReturn(xw); 441f2e35a3aSmrg do_xevents(xw); 442d522f475Smrg} 443d522f475Smrg 444d522f475Smrg/* 445d522f475Smrg * Move the cursor to the first column of the n-th previous line. 446d522f475Smrg */ 447d522f475Smrgvoid 4480bd37d32SmrgCursorPrevLine(XtermWidget xw, int count) 449d522f475Smrg{ 4500bd37d32Smrg TScreen *screen = TScreenOf(xw); 4510bd37d32Smrg 452d522f475Smrg CursorUp(screen, count < 1 ? 1 : count); 4530bd37d32Smrg CarriageReturn(xw); 454f2e35a3aSmrg do_xevents(xw); 455d522f475Smrg} 456d522f475Smrg 4570bd37d32Smrg/* 4580bd37d32Smrg * Return col/row values which can be passed to CursorSet() preserving the 4590bd37d32Smrg * current col/row, e.g., accounting for DECOM. 4600bd37d32Smrg */ 4610bd37d32Smrgint 4620bd37d32SmrgCursorCol(XtermWidget xw) 4630bd37d32Smrg{ 4640bd37d32Smrg TScreen *screen = TScreenOf(xw); 4650bd37d32Smrg int result = screen->cur_col; 4660bd37d32Smrg if (xw->flags & ORIGIN) { 4670bd37d32Smrg result -= ScrnLeftMargin(xw); 4680bd37d32Smrg if (result < 0) 4690bd37d32Smrg result = 0; 4700bd37d32Smrg } 4710bd37d32Smrg return result; 4720bd37d32Smrg} 4730bd37d32Smrg 4740bd37d32Smrgint 4750bd37d32SmrgCursorRow(XtermWidget xw) 4760bd37d32Smrg{ 4770bd37d32Smrg TScreen *screen = TScreenOf(xw); 4780bd37d32Smrg int result = screen->cur_row; 4790bd37d32Smrg if (xw->flags & ORIGIN) { 4800bd37d32Smrg result -= screen->top_marg; 4810bd37d32Smrg if (result < 0) 4820bd37d32Smrg result = 0; 4830bd37d32Smrg } 4840bd37d32Smrg return result; 4850bd37d32Smrg} 4860bd37d32Smrg 487d522f475Smrg#if OPT_TRACE 488d522f475Smrgint 4892e4f8982Smrgset_cur_row(TScreen *screen, int value) 490d522f475Smrg{ 4914419d26bSmrg TRACE(("set_cur_row %d vs %d\n", value, screen ? LastRowNumber(screen) : -1)); 492956cc18dSsnj 493d522f475Smrg assert(screen != 0); 494d522f475Smrg assert(value >= 0); 4954419d26bSmrg assert(value <= LastRowNumber(screen)); 4964419d26bSmrg if_STATUS_LINE(screen, { 4974419d26bSmrg value = LastRowNumber(screen); 4984419d26bSmrg }); 499d522f475Smrg screen->cur_row = value; 500d522f475Smrg return value; 501d522f475Smrg} 502d522f475Smrg 503d522f475Smrgint 5042e4f8982Smrgset_cur_col(TScreen *screen, int value) 505d522f475Smrg{ 506956cc18dSsnj TRACE(("set_cur_col %d vs %d\n", value, screen ? screen->max_col : -1)); 507956cc18dSsnj 508d522f475Smrg assert(screen != 0); 509d522f475Smrg assert(value >= 0); 510d522f475Smrg assert(value <= screen->max_col); 511d522f475Smrg screen->cur_col = value; 512d522f475Smrg return value; 513d522f475Smrg} 514d522f475Smrg#endif /* OPT_TRACE */ 5154419d26bSmrg/* 5164419d26bSmrg * vile:cmode fk=utf-8 5174419d26bSmrg */ 518