linedata.c revision 3367019c
13367019cSmrg/* $XTermId: linedata.c,v 1.82 2013/02/08 00:11:16 tom Exp $ */ 2956cc18dSsnj 33367019cSmrg/* 43367019cSmrg * Copyright 2009-2012,2013 by Thomas E. Dickey 53367019cSmrg * 63367019cSmrg * All Rights Reserved 73367019cSmrg * 83367019cSmrg * Permission is hereby granted, free of charge, to any person obtaining a 93367019cSmrg * copy of this software and associated documentation files (the 103367019cSmrg * "Software"), to deal in the Software without restriction, including 113367019cSmrg * without limitation the rights to use, copy, modify, merge, publish, 123367019cSmrg * distribute, sublicense, and/or sell copies of the Software, and to 133367019cSmrg * permit persons to whom the Software is furnished to do so, subject to 143367019cSmrg * the following conditions: 153367019cSmrg * 163367019cSmrg * The above copyright notice and this permission notice shall be included 173367019cSmrg * in all copies or substantial portions of the Software. 183367019cSmrg * 193367019cSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 203367019cSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 213367019cSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 223367019cSmrg * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 233367019cSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 243367019cSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 253367019cSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 263367019cSmrg * 273367019cSmrg * Except as contained in this notice, the name(s) of the above copyright 283367019cSmrg * holders shall not be used in advertising or otherwise to promote the 293367019cSmrg * sale, use or other dealings in this Software without prior written 303367019cSmrg * authorization. 313367019cSmrg */ 32956cc18dSsnj 33956cc18dSsnj#include <xterm.h> 34956cc18dSsnj 35956cc18dSsnj#include <assert.h> 36956cc18dSsnj 37956cc18dSsnj/* 38956cc18dSsnj * Given a row-number, find the corresponding data for the line in the VT100 39956cc18dSsnj * widget. Row numbers can be positive or negative. 40956cc18dSsnj * 41956cc18dSsnj * If the data comes from the scrollback, defer that to getScrollback(). 42956cc18dSsnj */ 43956cc18dSsnjLineData * 44956cc18dSsnjgetLineData(TScreen * screen, int row) 45956cc18dSsnj{ 46956cc18dSsnj LineData *result = 0; 47956cc18dSsnj ScrnBuf buffer; 4820d2c4d2Smrg int max_row = screen->max_row; 49956cc18dSsnj 50956cc18dSsnj if (row >= 0) { 51956cc18dSsnj buffer = screen->visbuf; 52956cc18dSsnj } else { 53956cc18dSsnj#if OPT_FIFO_LINES 54956cc18dSsnj buffer = 0; 55956cc18dSsnj result = getScrollback(screen, row); 56956cc18dSsnj#else 57956cc18dSsnj buffer = screen->saveBuf_index; 58956cc18dSsnj row += screen->savelines; 5920d2c4d2Smrg max_row += screen->savelines; 60956cc18dSsnj#endif 61956cc18dSsnj } 6220d2c4d2Smrg if (row >= 0 && row <= max_row) { 63956cc18dSsnj result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row); 64956cc18dSsnj if (result != 0) { 65956cc18dSsnj#if 1 /* FIXME - these should be done in setupLineData, etc. */ 66956cc18dSsnj result->lineSize = (Dimension) MaxCols(screen); 67956cc18dSsnj#if OPT_WIDE_CHARS 68956cc18dSsnj if (screen->wide_chars) { 69956cc18dSsnj result->combSize = (Char) screen->max_combining; 70956cc18dSsnj } else { 71956cc18dSsnj result->combSize = 0; 72956cc18dSsnj } 73956cc18dSsnj#endif 74956cc18dSsnj#endif /* FIXME */ 75956cc18dSsnj } 76956cc18dSsnj } 77956cc18dSsnj 78956cc18dSsnj return result; 79956cc18dSsnj} 80956cc18dSsnj 81956cc18dSsnj/* 82956cc18dSsnj * Copy line's data, e.g., from one screen buffer to another, given the preset 83956cc18dSsnj * pointers for the destination. 84956cc18dSsnj * 85956cc18dSsnj * TODO: optionally prune unused combining character data from the result. 86956cc18dSsnj */ 87956cc18dSsnjvoid 88956cc18dSsnjcopyLineData(LineData * dst, LineData * src) 89956cc18dSsnj{ 90956cc18dSsnj dst->bufHead = src->bufHead; 91956cc18dSsnj 92956cc18dSsnj#if OPT_WIDE_CHARS 93956cc18dSsnj dst->combSize = src->combSize; 94956cc18dSsnj#endif 95956cc18dSsnj 96956cc18dSsnj /* 97956cc18dSsnj * Usually we're copying the same-sized line; a memcpy is faster than 98956cc18dSsnj * several loops. 99956cc18dSsnj */ 100956cc18dSsnj if (dst->lineSize == src->lineSize) { 101956cc18dSsnj size_t size = (sizeof(dst->attribs[0]) 102956cc18dSsnj#if OPT_ISO_COLORS 103956cc18dSsnj + sizeof(dst->color[0]) 104956cc18dSsnj#endif 105956cc18dSsnj + sizeof(dst->charData[0]) 106956cc18dSsnj#if OPT_WIDE_CHARS 107956cc18dSsnj + sizeof(dst->combData[0][0]) * dst->combSize 108956cc18dSsnj#endif 109956cc18dSsnj ); 110956cc18dSsnj 111956cc18dSsnj memcpy(dst->attribs, src->attribs, size * dst->lineSize); 112956cc18dSsnj } else { 113956cc18dSsnj Dimension col; 114956cc18dSsnj Dimension limit = ((dst->lineSize < src->lineSize) 115956cc18dSsnj ? dst->lineSize 116956cc18dSsnj : src->lineSize); 117956cc18dSsnj#if OPT_WIDE_CHARS 118956cc18dSsnj Char comb; 119956cc18dSsnj#endif 120956cc18dSsnj 121956cc18dSsnj for (col = 0; col < limit; ++col) { 122956cc18dSsnj dst->attribs[col] = src->attribs[col]; 123956cc18dSsnj#if OPT_ISO_COLORS 124956cc18dSsnj dst->color[col] = src->color[col]; 125956cc18dSsnj#endif 126956cc18dSsnj dst->charData[col] = src->charData[col]; 127956cc18dSsnj#if OPT_WIDE_CHARS 128956cc18dSsnj for (comb = 0; comb < dst->combSize; ++comb) { 129956cc18dSsnj dst->combData[comb][col] = src->combData[comb][col]; 130956cc18dSsnj } 131956cc18dSsnj#endif 132956cc18dSsnj } 133956cc18dSsnj for (col = limit; col < dst->lineSize; ++col) { 134956cc18dSsnj dst->attribs[col] = 0; 135956cc18dSsnj#if OPT_ISO_COLORS 136956cc18dSsnj dst->color[col] = 0; 137956cc18dSsnj#endif 138956cc18dSsnj dst->charData[col] = 0; 139956cc18dSsnj#if OPT_WIDE_CHARS 140956cc18dSsnj for (comb = 0; comb < dst->combSize; ++comb) { 141956cc18dSsnj dst->combData[comb][col] = 0; 142956cc18dSsnj } 143956cc18dSsnj#endif 144956cc18dSsnj } 145956cc18dSsnj } 146956cc18dSsnj} 147956cc18dSsnj 148956cc18dSsnj#if OPT_WIDE_CHARS 149956cc18dSsnj#define initLineExtra(screen) \ 150956cc18dSsnj screen->lineExtra = ((size_t) (screen->max_combining) * sizeof(IChar *)) 151956cc18dSsnj#else 152956cc18dSsnj#define initLineExtra(screen) \ 153956cc18dSsnj screen->lineExtra = 0 154956cc18dSsnj#endif 155956cc18dSsnj 156956cc18dSsnjvoid 157956cc18dSsnjinitLineData(XtermWidget xw) 158956cc18dSsnj{ 15920d2c4d2Smrg TScreen *screen = TScreenOf(xw); 160956cc18dSsnj 161956cc18dSsnj initLineExtra(screen); 162956cc18dSsnj 16320d2c4d2Smrg TRACE(("initLineData %lu\n", (unsigned long) screen->lineExtra)); 16420d2c4d2Smrg TRACE(("...sizeof(LineData) %lu\n", (unsigned long) sizeof(LineData))); 165956cc18dSsnj#if OPT_ISO_COLORS 16620d2c4d2Smrg TRACE(("...sizeof(CellColor) %lu\n", (unsigned long) sizeof(CellColor))); 167956cc18dSsnj#endif 16820d2c4d2Smrg TRACE(("...sizeof(RowData) %lu\n", (unsigned long) sizeof(RowData))); 16920d2c4d2Smrg TRACE(("...offset(lineSize) %lu\n", (unsigned long) offsetof(LineData, lineSize))); 17020d2c4d2Smrg TRACE(("...offset(bufHead) %lu\n", (unsigned long) offsetof(LineData, bufHead))); 171956cc18dSsnj#if OPT_WIDE_CHARS 17220d2c4d2Smrg TRACE(("...offset(combSize) %lu\n", (unsigned long) offsetof(LineData, combSize))); 173956cc18dSsnj#endif 17420d2c4d2Smrg TRACE(("...offset(attribs) %lu\n", (unsigned long) offsetof(LineData, attribs))); 175956cc18dSsnj#if OPT_ISO_COLORS 17620d2c4d2Smrg TRACE(("...offset(color) %lu\n", (unsigned long) offsetof(LineData, color))); 177956cc18dSsnj#endif 17820d2c4d2Smrg TRACE(("...offset(charData) %lu\n", (unsigned long) offsetof(LineData, charData))); 17920d2c4d2Smrg TRACE(("...offset(combData) %lu\n", (unsigned long) offsetof(LineData, combData))); 180956cc18dSsnj} 181956cc18dSsnj 182956cc18dSsnj/* 183956cc18dSsnj * CellData size depends on the "combiningChars" resource. 184956cc18dSsnj * FIXME - revise this to reduce arithmetic... 185956cc18dSsnj */ 186956cc18dSsnj#define CellDataSize(screen) (SizeOfCellData + screen->lineExtra) 187956cc18dSsnj 188956cc18dSsnj#define CellDataAddr(screen, data, cell) \ 189c219fbebSmrg (CellData *)(void *) ((char *)data + (cell * CellDataSize(screen))) 190956cc18dSsnj 191956cc18dSsnjCellData * 192956cc18dSsnjnewCellData(XtermWidget xw, Cardinal count) 193956cc18dSsnj{ 194956cc18dSsnj CellData *result; 19520d2c4d2Smrg TScreen *screen = TScreenOf(xw); 196956cc18dSsnj 197956cc18dSsnj initLineExtra(screen); 198956cc18dSsnj result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen)); 199956cc18dSsnj return result; 200956cc18dSsnj} 201956cc18dSsnj 202956cc18dSsnjvoid 203956cc18dSsnjsaveCellData(TScreen * screen, 204956cc18dSsnj CellData * data, 205956cc18dSsnj Cardinal cell, 206956cc18dSsnj LineData * ld, 207956cc18dSsnj int column) 208956cc18dSsnj{ 209956cc18dSsnj CellData *item = CellDataAddr(screen, data, cell); 210956cc18dSsnj 211956cc18dSsnj if (column < MaxCols(screen)) { 212956cc18dSsnj item->attribs = ld->attribs[column]; 213956cc18dSsnj#if OPT_ISO_COLORS 214956cc18dSsnj item->color = ld->color[column]; 215956cc18dSsnj#endif 216956cc18dSsnj item->charData = ld->charData[column]; 217956cc18dSsnj if_OPT_WIDE_CHARS(screen, { 218956cc18dSsnj size_t off; 219956cc18dSsnj item->combSize = ld->combSize; 220956cc18dSsnj for_each_combData(off, ld) { 221956cc18dSsnj item->combData[off] = ld->combData[off][column]; 222956cc18dSsnj } 223956cc18dSsnj }) 224956cc18dSsnj } 225956cc18dSsnj} 226956cc18dSsnj 227956cc18dSsnjvoid 228956cc18dSsnjrestoreCellData(TScreen * screen, 229956cc18dSsnj CellData * data, 230956cc18dSsnj Cardinal cell, 231956cc18dSsnj LineData * ld, 232956cc18dSsnj int column) 233956cc18dSsnj{ 234956cc18dSsnj CellData *item = CellDataAddr(screen, data, cell); 235956cc18dSsnj 236956cc18dSsnj if (column < MaxCols(screen)) { 237956cc18dSsnj ld->attribs[column] = item->attribs; 238956cc18dSsnj#if OPT_ISO_COLORS 239956cc18dSsnj ld->color[column] = item->color; 240956cc18dSsnj#endif 241956cc18dSsnj ld->charData[column] = item->charData; 242956cc18dSsnj if_OPT_WIDE_CHARS(screen, { 243956cc18dSsnj size_t off; 244956cc18dSsnj ld->combSize = item->combSize; 245956cc18dSsnj for_each_combData(off, ld) { 246956cc18dSsnj ld->combData[off][column] = item->combData[off]; 247956cc18dSsnj } 248956cc18dSsnj }) 249956cc18dSsnj } 250956cc18dSsnj} 251