linedata.c revision 956cc18d
1956cc18dSsnj/* $XTermId: linedata.c,v 1.71 2009/08/09 00:34:16 tom Exp $ */ 2956cc18dSsnj 3956cc18dSsnj/************************************************************ 4956cc18dSsnj 5956cc18dSsnjCopyright 2009 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; 51956cc18dSsnj 52956cc18dSsnj if (row >= 0) { 53956cc18dSsnj buffer = screen->visbuf; 54956cc18dSsnj } else { 55956cc18dSsnj#if OPT_FIFO_LINES 56956cc18dSsnj buffer = 0; 57956cc18dSsnj result = getScrollback(screen, row); 58956cc18dSsnj#else 59956cc18dSsnj buffer = screen->saveBuf_index; 60956cc18dSsnj row += screen->savelines; 61956cc18dSsnj#endif 62956cc18dSsnj } 63956cc18dSsnj if (row >= 0) { 64956cc18dSsnj result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row); 65956cc18dSsnj if (result != 0) { 66956cc18dSsnj#if 1 /* FIXME - these should be done in setupLineData, etc. */ 67956cc18dSsnj result->lineSize = (Dimension) MaxCols(screen); 68956cc18dSsnj#if OPT_WIDE_CHARS 69956cc18dSsnj if (screen->wide_chars) { 70956cc18dSsnj result->combSize = (Char) screen->max_combining; 71956cc18dSsnj } else { 72956cc18dSsnj result->combSize = 0; 73956cc18dSsnj } 74956cc18dSsnj#endif 75956cc18dSsnj#endif /* FIXME */ 76956cc18dSsnj } 77956cc18dSsnj } 78956cc18dSsnj 79956cc18dSsnj return result; 80956cc18dSsnj} 81956cc18dSsnj 82956cc18dSsnj/* 83956cc18dSsnj * Copy line's data, e.g., from one screen buffer to another, given the preset 84956cc18dSsnj * pointers for the destination. 85956cc18dSsnj * 86956cc18dSsnj * TODO: optionally prune unused combining character data from the result. 87956cc18dSsnj */ 88956cc18dSsnjvoid 89956cc18dSsnjcopyLineData(LineData * dst, LineData * src) 90956cc18dSsnj{ 91956cc18dSsnj dst->bufHead = src->bufHead; 92956cc18dSsnj 93956cc18dSsnj#if OPT_WIDE_CHARS 94956cc18dSsnj dst->combSize = src->combSize; 95956cc18dSsnj#endif 96956cc18dSsnj 97956cc18dSsnj /* 98956cc18dSsnj * Usually we're copying the same-sized line; a memcpy is faster than 99956cc18dSsnj * several loops. 100956cc18dSsnj */ 101956cc18dSsnj if (dst->lineSize == src->lineSize) { 102956cc18dSsnj size_t size = (sizeof(dst->attribs[0]) 103956cc18dSsnj#if OPT_ISO_COLORS 104956cc18dSsnj + sizeof(dst->color[0]) 105956cc18dSsnj#endif 106956cc18dSsnj + sizeof(dst->charData[0]) 107956cc18dSsnj#if OPT_WIDE_CHARS 108956cc18dSsnj + sizeof(dst->combData[0][0]) * dst->combSize 109956cc18dSsnj#endif 110956cc18dSsnj ); 111956cc18dSsnj 112956cc18dSsnj memcpy(dst->attribs, src->attribs, size * dst->lineSize); 113956cc18dSsnj } else { 114956cc18dSsnj Dimension col; 115956cc18dSsnj Dimension limit = ((dst->lineSize < src->lineSize) 116956cc18dSsnj ? dst->lineSize 117956cc18dSsnj : src->lineSize); 118956cc18dSsnj#if OPT_WIDE_CHARS 119956cc18dSsnj Char comb; 120956cc18dSsnj#endif 121956cc18dSsnj 122956cc18dSsnj for (col = 0; col < limit; ++col) { 123956cc18dSsnj dst->attribs[col] = src->attribs[col]; 124956cc18dSsnj#if OPT_ISO_COLORS 125956cc18dSsnj dst->color[col] = src->color[col]; 126956cc18dSsnj#endif 127956cc18dSsnj dst->charData[col] = src->charData[col]; 128956cc18dSsnj#if OPT_WIDE_CHARS 129956cc18dSsnj for (comb = 0; comb < dst->combSize; ++comb) { 130956cc18dSsnj dst->combData[comb][col] = src->combData[comb][col]; 131956cc18dSsnj } 132956cc18dSsnj#endif 133956cc18dSsnj } 134956cc18dSsnj for (col = limit; col < dst->lineSize; ++col) { 135956cc18dSsnj dst->attribs[col] = 0; 136956cc18dSsnj#if OPT_ISO_COLORS 137956cc18dSsnj dst->color[col] = 0; 138956cc18dSsnj#endif 139956cc18dSsnj dst->charData[col] = 0; 140956cc18dSsnj#if OPT_WIDE_CHARS 141956cc18dSsnj for (comb = 0; comb < dst->combSize; ++comb) { 142956cc18dSsnj dst->combData[comb][col] = 0; 143956cc18dSsnj } 144956cc18dSsnj#endif 145956cc18dSsnj } 146956cc18dSsnj } 147956cc18dSsnj} 148956cc18dSsnj 149956cc18dSsnj#if OPT_WIDE_CHARS 150956cc18dSsnj#define initLineExtra(screen) \ 151956cc18dSsnj screen->lineExtra = ((size_t) (screen->max_combining) * sizeof(IChar *)) 152956cc18dSsnj#else 153956cc18dSsnj#define initLineExtra(screen) \ 154956cc18dSsnj screen->lineExtra = 0 155956cc18dSsnj#endif 156956cc18dSsnj 157956cc18dSsnjvoid 158956cc18dSsnjinitLineData(XtermWidget xw) 159956cc18dSsnj{ 160956cc18dSsnj TScreen *screen = &(xw->screen); 161956cc18dSsnj 162956cc18dSsnj initLineExtra(screen); 163956cc18dSsnj 164956cc18dSsnj TRACE(("initLineData %d\n", screen->lineExtra)); 165956cc18dSsnj TRACE(("...sizeof(LineData) %d\n", sizeof(LineData))); 166956cc18dSsnj#if OPT_ISO_COLORS 167956cc18dSsnj TRACE(("...sizeof(CellColor) %d\n", sizeof(CellColor))); 168956cc18dSsnj#endif 169956cc18dSsnj TRACE(("...sizeof(RowData) %d\n", sizeof(RowData))); 170956cc18dSsnj TRACE(("...offset(lineSize) %d\n", offsetof(LineData, lineSize))); 171956cc18dSsnj TRACE(("...offset(bufHead) %d\n", offsetof(LineData, bufHead))); 172956cc18dSsnj#if OPT_WIDE_CHARS 173956cc18dSsnj TRACE(("...offset(combSize) %d\n", offsetof(LineData, combSize))); 174956cc18dSsnj#endif 175956cc18dSsnj TRACE(("...offset(attribs) %d\n", offsetof(LineData, attribs))); 176956cc18dSsnj#if OPT_ISO_COLORS 177956cc18dSsnj TRACE(("...offset(color) %d\n", offsetof(LineData, color))); 178956cc18dSsnj#endif 179956cc18dSsnj TRACE(("...offset(charData) %d\n", offsetof(LineData, charData))); 180956cc18dSsnj TRACE(("...offset(combData) %d\n", offsetof(LineData, combData))); 181956cc18dSsnj} 182956cc18dSsnj 183956cc18dSsnj/* 184956cc18dSsnj * CellData size depends on the "combiningChars" resource. 185956cc18dSsnj * FIXME - revise this to reduce arithmetic... 186956cc18dSsnj */ 187956cc18dSsnj#define CellDataSize(screen) (SizeOfCellData + screen->lineExtra) 188956cc18dSsnj 189956cc18dSsnj#define CellDataAddr(screen, data, cell) \ 190956cc18dSsnj (CellData *)((char *)data + (cell * CellDataSize(screen))) 191956cc18dSsnj 192956cc18dSsnjCellData * 193956cc18dSsnjnewCellData(XtermWidget xw, Cardinal count) 194956cc18dSsnj{ 195956cc18dSsnj CellData *result; 196956cc18dSsnj TScreen *screen = &(xw->screen); 197956cc18dSsnj 198956cc18dSsnj initLineExtra(screen); 199956cc18dSsnj result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen)); 200956cc18dSsnj return result; 201956cc18dSsnj} 202956cc18dSsnj 203956cc18dSsnjvoid 204956cc18dSsnjsaveCellData(TScreen * screen, 205956cc18dSsnj CellData * data, 206956cc18dSsnj Cardinal cell, 207956cc18dSsnj LineData * ld, 208956cc18dSsnj int column) 209956cc18dSsnj{ 210956cc18dSsnj CellData *item = CellDataAddr(screen, data, cell); 211956cc18dSsnj 212956cc18dSsnj if (column < MaxCols(screen)) { 213956cc18dSsnj item->attribs = ld->attribs[column]; 214956cc18dSsnj#if OPT_ISO_COLORS 215956cc18dSsnj item->color = ld->color[column]; 216956cc18dSsnj#endif 217956cc18dSsnj item->charData = ld->charData[column]; 218956cc18dSsnj if_OPT_WIDE_CHARS(screen, { 219956cc18dSsnj size_t off; 220956cc18dSsnj item->combSize = ld->combSize; 221956cc18dSsnj for_each_combData(off, ld) { 222956cc18dSsnj item->combData[off] = ld->combData[off][column]; 223956cc18dSsnj } 224956cc18dSsnj }) 225956cc18dSsnj } 226956cc18dSsnj} 227956cc18dSsnj 228956cc18dSsnjvoid 229956cc18dSsnjrestoreCellData(TScreen * screen, 230956cc18dSsnj CellData * data, 231956cc18dSsnj Cardinal cell, 232956cc18dSsnj LineData * ld, 233956cc18dSsnj int column) 234956cc18dSsnj{ 235956cc18dSsnj CellData *item = CellDataAddr(screen, data, cell); 236956cc18dSsnj 237956cc18dSsnj if (column < MaxCols(screen)) { 238956cc18dSsnj ld->attribs[column] = item->attribs; 239956cc18dSsnj#if OPT_ISO_COLORS 240956cc18dSsnj ld->color[column] = item->color; 241956cc18dSsnj#endif 242956cc18dSsnj ld->charData[column] = item->charData; 243956cc18dSsnj if_OPT_WIDE_CHARS(screen, { 244956cc18dSsnj size_t off; 245956cc18dSsnj ld->combSize = item->combSize; 246956cc18dSsnj for_each_combData(off, ld) { 247956cc18dSsnj ld->combData[off][column] = item->combData[off]; 248956cc18dSsnj } 249956cc18dSsnj }) 250956cc18dSsnj } 251956cc18dSsnj} 252