scrollback.c revision 50027b5b
1/* $XTermId: scrollback.c,v 1.23 2022/03/09 00:38:51 tom Exp $ */ 2 3/* 4 * Copyright 2009-2020,2022 by Thomas E. Dickey 5 * 6 * All Rights Reserved 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sublicense, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22 * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 23 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 * Except as contained in this notice, the name(s) of the above copyright 28 * holders shall not be used in advertising or otherwise to promote the 29 * sale, use or other dealings in this Software without prior written 30 * authorization. 31 */ 32 33#include <xterm.h> 34 35#define REAL_ROW(screen, row) ((row) + (screen)->saved_fifo) 36#define ROW2FIFO(screen, row) \ 37 (unsigned) (REAL_ROW(screen, row) % (screen)->savelines) 38 39/* 40 * Given a row-number, find the corresponding data for the line in the VT100 41 * widget's saved-line FIFO. The row-number (from getLineData) is negative. 42 * So we just count backwards from the last saved line. 43 */ 44LineData * 45getScrollback(TScreen *screen, int row) 46{ 47 LineData *result = 0; 48 49 if (screen->saved_fifo > 0 && REAL_ROW(screen, row) >= 0) { 50 unsigned which = ROW2FIFO(screen, row); 51 ScrnBuf where = scrnHeadAddr(screen, screen->saveBuf_index, which); 52 result = (LineData *) where; 53 } 54 55 TRACE(("getScrollback %d -> %d -> %p\n", 56 row, ROW2FIFO(screen, row), 57 (void *) result)); 58 return result; 59} 60 61/* 62 * Allocate a new row in the scrollback FIFO, returning a pointer to it. 63 */ 64LineData * 65addScrollback(TScreen *screen) 66{ 67 ScrnBuf where = 0; 68 unsigned ncols = (unsigned) MaxCols(screen); 69 70 if (screen->saveBuf_index != 0 && screen->savelines != 0) { 71 unsigned which; 72 Char *block; 73 74 TRACE(("addScrollback %lu\n", screen->saved_fifo)); 75 76 /* first, see which index we'll use */ 77 which = (unsigned) (screen->saved_fifo % screen->savelines); 78 where = scrnHeadAddr(screen, screen->saveBuf_index, which); 79 80 /* discard any obsolete index data */ 81 if (screen->saved_fifo > screen->savelines) { 82 LineData *prior = (LineData *) where; 83 /* 84 * setupLineData uses the attribs as the first address used from the 85 * data block. 86 */ 87 if (prior->attribs != 0) { 88 TRACE(("...freeing prior FIFO data in slot %d: %p->%p\n", 89 which, (void *) prior, (void *) prior->attribs)); 90 FreeAndNull(prior->attribs); 91 } 92 if (screen->saved_fifo > 2 * screen->savelines) { 93 screen->saved_fifo -= screen->savelines; 94 } 95 } 96 97 /* allocate the new data */ 98 block = allocScrnData(screen, 1, ncols, False); 99 100 /* record the new data in the index */ 101 setupLineData(screen, where, (Char *) block, 1, ncols, False); 102 103 TRACE(("...storing new FIFO data in slot %d: %p->%p\n", 104 which, (void *) where, block)); 105 106 screen->saved_fifo++; 107 } 108 return (LineData *) where; 109} 110 111void 112deleteScrollback(TScreen *screen) 113{ 114 unsigned which = ROW2FIFO(screen, -1); 115 ScrnBuf where = scrnHeadAddr(screen, screen->saveBuf_index, which); 116 LineData *prior = (LineData *) where; 117 /* 118 * setupLineData uses the attribs as the first address used from the 119 * data block. 120 */ 121 if (prior->attribs != 0) { 122 TRACE(("...freeing prior FIFO data in slot %d: %p->%p\n", 123 which, (void *) prior, (void *) prior->attribs)); 124 FreeAndNull(prior->attribs); 125 } 126 screen->saved_fifo--; 127} 128