linedata.c revision c219fbeb
1c219fbebSmrg/* $XTermId: linedata.c,v 1.79 2011/01/21 00:07:35 tom Exp $ */ 2956cc18dSsnj 3956cc18dSsnj/************************************************************ 4956cc18dSsnj 5c219fbebSmrgCopyright 2009-2010,2011 by Thomas E. Dickey 6956cc18dSsnj 7956cc18dSsnj All Rights Reserved 8956cc18dSsnj 9956cc18dSsnjPermission is hereby granted, free of charge, to any person obtaining a 10956cc18dSsnjcopy of this software and associated documentation files (the 11956cc18dSsnj"Software"), to deal in the Software without restriction, including 12956cc18dSsnjwithout limitation the rights to use, copy, modify, merge, publish, 13956cc18dSsnjdistribute, sublicense, and/or sell copies of the Software, and to 14956cc18dSsnjpermit persons to whom the Software is furnished to do so, subject to 15956cc18dSsnjthe following conditions: 16956cc18dSsnj 17956cc18dSsnjThe above copyright notice and this permission notice shall be included 18956cc18dSsnjin all copies or substantial portions of the Software. 19956cc18dSsnj 20956cc18dSsnjTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21956cc18dSsnjOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22956cc18dSsnjMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23956cc18dSsnjIN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 24956cc18dSsnjCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25956cc18dSsnjTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26956cc18dSsnjSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27956cc18dSsnj 28956cc18dSsnjExcept as contained in this notice, the name(s) of the above copyright 29956cc18dSsnjholders shall not be used in advertising or otherwise to promote the 30956cc18dSsnjsale, use or other dealings in this Software without prior written 31956cc18dSsnjauthorization. 32956cc18dSsnj 33956cc18dSsnj********************************************************/ 34956cc18dSsnj 35956cc18dSsnj#include <xterm.h> 36956cc18dSsnj#include <data.h> /* FIXME - needed for 'term' */ 37956cc18dSsnj 38956cc18dSsnj#include <assert.h> 39956cc18dSsnj 40956cc18dSsnj/* 41956cc18dSsnj * Given a row-number, find the corresponding data for the line in the VT100 42956cc18dSsnj * widget. Row numbers can be positive or negative. 43956cc18dSsnj * 44956cc18dSsnj * If the data comes from the scrollback, defer that to getScrollback(). 45956cc18dSsnj */ 46956cc18dSsnjLineData * 47956cc18dSsnjgetLineData(TScreen * screen, int row) 48956cc18dSsnj{ 49956cc18dSsnj LineData *result = 0; 50956cc18dSsnj ScrnBuf buffer; 5120d2c4d2Smrg int max_row = screen->max_row; 52956cc18dSsnj 53956cc18dSsnj if (row >= 0) { 54956cc18dSsnj buffer = screen->visbuf; 55956cc18dSsnj } else { 56956cc18dSsnj#if OPT_FIFO_LINES 57956cc18dSsnj buffer = 0; 58956cc18dSsnj result = getScrollback(screen, row); 59956cc18dSsnj#else 60956cc18dSsnj buffer = screen->saveBuf_index; 61956cc18dSsnj row += screen->savelines; 6220d2c4d2Smrg max_row += screen->savelines; 63956cc18dSsnj#endif 64956cc18dSsnj } 6520d2c4d2Smrg if (row >= 0 && row <= max_row) { 66956cc18dSsnj result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row); 67956cc18dSsnj if (result != 0) { 68956cc18dSsnj#if 1 /* FIXME - these should be done in setupLineData, etc. */ 69956cc18dSsnj result->lineSize = (Dimension) MaxCols(screen); 70956cc18dSsnj#if OPT_WIDE_CHARS 71956cc18dSsnj if (screen->wide_chars) { 72956cc18dSsnj result->combSize = (Char) screen->max_combining; 73956cc18dSsnj } else { 74956cc18dSsnj result->combSize = 0; 75956cc18dSsnj } 76956cc18dSsnj#endif 77956cc18dSsnj#endif /* FIXME */ 78956cc18dSsnj } 79956cc18dSsnj } 80956cc18dSsnj 81956cc18dSsnj return result; 82956cc18dSsnj} 83956cc18dSsnj 84956cc18dSsnj/* 85956cc18dSsnj * Copy line's data, e.g., from one screen buffer to another, given the preset 86956cc18dSsnj * pointers for the destination. 87956cc18dSsnj * 88956cc18dSsnj * TODO: optionally prune unused combining character data from the result. 89956cc18dSsnj */ 90956cc18dSsnjvoid 91956cc18dSsnjcopyLineData(LineData * dst, LineData * src) 92956cc18dSsnj{ 93956cc18dSsnj dst->bufHead = src->bufHead; 94956cc18dSsnj 95956cc18dSsnj#if OPT_WIDE_CHARS 96956cc18dSsnj dst->combSize = src->combSize; 97956cc18dSsnj#endif 98956cc18dSsnj 99956cc18dSsnj /* 100956cc18dSsnj * Usually we're copying the same-sized line; a memcpy is faster than 101956cc18dSsnj * several loops. 102956cc18dSsnj */ 103956cc18dSsnj if (dst->lineSize == src->lineSize) { 104956cc18dSsnj size_t size = (sizeof(dst->attribs[0]) 105956cc18dSsnj#if OPT_ISO_COLORS 106956cc18dSsnj + sizeof(dst->color[0]) 107956cc18dSsnj#endif 108956cc18dSsnj + sizeof(dst->charData[0]) 109956cc18dSsnj#if OPT_WIDE_CHARS 110956cc18dSsnj + sizeof(dst->combData[0][0]) * dst->combSize 111956cc18dSsnj#endif 112956cc18dSsnj ); 113956cc18dSsnj 114956cc18dSsnj memcpy(dst->attribs, src->attribs, size * dst->lineSize); 115956cc18dSsnj } else { 116956cc18dSsnj Dimension col; 117956cc18dSsnj Dimension limit = ((dst->lineSize < src->lineSize) 118956cc18dSsnj ? dst->lineSize 119956cc18dSsnj : src->lineSize); 120956cc18dSsnj#if OPT_WIDE_CHARS 121956cc18dSsnj Char comb; 122956cc18dSsnj#endif 123956cc18dSsnj 124956cc18dSsnj for (col = 0; col < limit; ++col) { 125956cc18dSsnj dst->attribs[col] = src->attribs[col]; 126956cc18dSsnj#if OPT_ISO_COLORS 127956cc18dSsnj dst->color[col] = src->color[col]; 128956cc18dSsnj#endif 129956cc18dSsnj dst->charData[col] = src->charData[col]; 130956cc18dSsnj#if OPT_WIDE_CHARS 131956cc18dSsnj for (comb = 0; comb < dst->combSize; ++comb) { 132956cc18dSsnj dst->combData[comb][col] = src->combData[comb][col]; 133956cc18dSsnj } 134956cc18dSsnj#endif 135956cc18dSsnj } 136956cc18dSsnj for (col = limit; col < dst->lineSize; ++col) { 137956cc18dSsnj dst->attribs[col] = 0; 138956cc18dSsnj#if OPT_ISO_COLORS 139956cc18dSsnj dst->color[col] = 0; 140956cc18dSsnj#endif 141956cc18dSsnj dst->charData[col] = 0; 142956cc18dSsnj#if OPT_WIDE_CHARS 143956cc18dSsnj for (comb = 0; comb < dst->combSize; ++comb) { 144956cc18dSsnj dst->combData[comb][col] = 0; 145956cc18dSsnj } 146956cc18dSsnj#endif 147956cc18dSsnj } 148956cc18dSsnj } 149956cc18dSsnj} 150956cc18dSsnj 151956cc18dSsnj#if OPT_WIDE_CHARS 152956cc18dSsnj#define initLineExtra(screen) \ 153956cc18dSsnj screen->lineExtra = ((size_t) (screen->max_combining) * sizeof(IChar *)) 154956cc18dSsnj#else 155956cc18dSsnj#define initLineExtra(screen) \ 156956cc18dSsnj screen->lineExtra = 0 157956cc18dSsnj#endif 158956cc18dSsnj 159956cc18dSsnjvoid 160956cc18dSsnjinitLineData(XtermWidget xw) 161956cc18dSsnj{ 16220d2c4d2Smrg TScreen *screen = TScreenOf(xw); 163956cc18dSsnj 164956cc18dSsnj initLineExtra(screen); 165956cc18dSsnj 16620d2c4d2Smrg TRACE(("initLineData %lu\n", (unsigned long) screen->lineExtra)); 16720d2c4d2Smrg TRACE(("...sizeof(LineData) %lu\n", (unsigned long) sizeof(LineData))); 168956cc18dSsnj#if OPT_ISO_COLORS 16920d2c4d2Smrg TRACE(("...sizeof(CellColor) %lu\n", (unsigned long) sizeof(CellColor))); 170956cc18dSsnj#endif 17120d2c4d2Smrg TRACE(("...sizeof(RowData) %lu\n", (unsigned long) sizeof(RowData))); 17220d2c4d2Smrg TRACE(("...offset(lineSize) %lu\n", (unsigned long) offsetof(LineData, lineSize))); 17320d2c4d2Smrg TRACE(("...offset(bufHead) %lu\n", (unsigned long) offsetof(LineData, bufHead))); 174956cc18dSsnj#if OPT_WIDE_CHARS 17520d2c4d2Smrg TRACE(("...offset(combSize) %lu\n", (unsigned long) offsetof(LineData, combSize))); 176956cc18dSsnj#endif 17720d2c4d2Smrg TRACE(("...offset(attribs) %lu\n", (unsigned long) offsetof(LineData, attribs))); 178956cc18dSsnj#if OPT_ISO_COLORS 17920d2c4d2Smrg TRACE(("...offset(color) %lu\n", (unsigned long) offsetof(LineData, color))); 180956cc18dSsnj#endif 18120d2c4d2Smrg TRACE(("...offset(charData) %lu\n", (unsigned long) offsetof(LineData, charData))); 18220d2c4d2Smrg TRACE(("...offset(combData) %lu\n", (unsigned long) offsetof(LineData, combData))); 183956cc18dSsnj} 184956cc18dSsnj 185956cc18dSsnj/* 186956cc18dSsnj * CellData size depends on the "combiningChars" resource. 187956cc18dSsnj * FIXME - revise this to reduce arithmetic... 188956cc18dSsnj */ 189956cc18dSsnj#define CellDataSize(screen) (SizeOfCellData + screen->lineExtra) 190956cc18dSsnj 191956cc18dSsnj#define CellDataAddr(screen, data, cell) \ 192c219fbebSmrg (CellData *)(void *) ((char *)data + (cell * CellDataSize(screen))) 193956cc18dSsnj 194956cc18dSsnjCellData * 195956cc18dSsnjnewCellData(XtermWidget xw, Cardinal count) 196956cc18dSsnj{ 197956cc18dSsnj CellData *result; 19820d2c4d2Smrg TScreen *screen = TScreenOf(xw); 199956cc18dSsnj 200956cc18dSsnj initLineExtra(screen); 201956cc18dSsnj result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen)); 202956cc18dSsnj return result; 203956cc18dSsnj} 204956cc18dSsnj 205956cc18dSsnjvoid 206956cc18dSsnjsaveCellData(TScreen * screen, 207956cc18dSsnj CellData * data, 208956cc18dSsnj Cardinal cell, 209956cc18dSsnj LineData * ld, 210956cc18dSsnj int column) 211956cc18dSsnj{ 212956cc18dSsnj CellData *item = CellDataAddr(screen, data, cell); 213956cc18dSsnj 214956cc18dSsnj if (column < MaxCols(screen)) { 215956cc18dSsnj item->attribs = ld->attribs[column]; 216956cc18dSsnj#if OPT_ISO_COLORS 217956cc18dSsnj item->color = ld->color[column]; 218956cc18dSsnj#endif 219956cc18dSsnj item->charData = ld->charData[column]; 220956cc18dSsnj if_OPT_WIDE_CHARS(screen, { 221956cc18dSsnj size_t off; 222956cc18dSsnj item->combSize = ld->combSize; 223956cc18dSsnj for_each_combData(off, ld) { 224956cc18dSsnj item->combData[off] = ld->combData[off][column]; 225956cc18dSsnj } 226956cc18dSsnj }) 227956cc18dSsnj } 228956cc18dSsnj} 229956cc18dSsnj 230956cc18dSsnjvoid 231956cc18dSsnjrestoreCellData(TScreen * screen, 232956cc18dSsnj CellData * data, 233956cc18dSsnj Cardinal cell, 234956cc18dSsnj LineData * ld, 235956cc18dSsnj int column) 236956cc18dSsnj{ 237956cc18dSsnj CellData *item = CellDataAddr(screen, data, cell); 238956cc18dSsnj 239956cc18dSsnj if (column < MaxCols(screen)) { 240956cc18dSsnj ld->attribs[column] = item->attribs; 241956cc18dSsnj#if OPT_ISO_COLORS 242956cc18dSsnj ld->color[column] = item->color; 243956cc18dSsnj#endif 244956cc18dSsnj ld->charData[column] = item->charData; 245956cc18dSsnj if_OPT_WIDE_CHARS(screen, { 246956cc18dSsnj size_t off; 247956cc18dSsnj ld->combSize = item->combSize; 248956cc18dSsnj for_each_combData(off, ld) { 249956cc18dSsnj ld->combData[off][column] = item->combData[off]; 250956cc18dSsnj } 251956cc18dSsnj }) 252956cc18dSsnj } 253956cc18dSsnj} 254