linedata.c revision 956cc18d
1/* $XTermId: linedata.c,v 1.71 2009/08/09 00:34:16 tom Exp $ */ 2 3/************************************************************ 4 5Copyright 2009 by Thomas E. Dickey 6 7 All Rights Reserved 8 9Permission is hereby granted, free of charge, to any person obtaining a 10copy of this software and associated documentation files (the 11"Software"), to deal in the Software without restriction, including 12without limitation the rights to use, copy, modify, merge, publish, 13distribute, sublicense, and/or sell copies of the Software, and to 14permit persons to whom the Software is furnished to do so, subject to 15the following conditions: 16 17The above copyright notice and this permission notice shall be included 18in all copies or substantial portions of the Software. 19 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY 24CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 28Except as contained in this notice, the name(s) of the above copyright 29holders shall not be used in advertising or otherwise to promote the 30sale, use or other dealings in this Software without prior written 31authorization. 32 33********************************************************/ 34 35#include <xterm.h> 36#include <data.h> /* FIXME - needed for 'term' */ 37 38#include <assert.h> 39 40/* 41 * Given a row-number, find the corresponding data for the line in the VT100 42 * widget. Row numbers can be positive or negative. 43 * 44 * If the data comes from the scrollback, defer that to getScrollback(). 45 */ 46LineData * 47getLineData(TScreen * screen, int row) 48{ 49 LineData *result = 0; 50 ScrnBuf buffer; 51 52 if (row >= 0) { 53 buffer = screen->visbuf; 54 } else { 55#if OPT_FIFO_LINES 56 buffer = 0; 57 result = getScrollback(screen, row); 58#else 59 buffer = screen->saveBuf_index; 60 row += screen->savelines; 61#endif 62 } 63 if (row >= 0) { 64 result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row); 65 if (result != 0) { 66#if 1 /* FIXME - these should be done in setupLineData, etc. */ 67 result->lineSize = (Dimension) MaxCols(screen); 68#if OPT_WIDE_CHARS 69 if (screen->wide_chars) { 70 result->combSize = (Char) screen->max_combining; 71 } else { 72 result->combSize = 0; 73 } 74#endif 75#endif /* FIXME */ 76 } 77 } 78 79 return result; 80} 81 82/* 83 * Copy line's data, e.g., from one screen buffer to another, given the preset 84 * pointers for the destination. 85 * 86 * TODO: optionally prune unused combining character data from the result. 87 */ 88void 89copyLineData(LineData * dst, LineData * src) 90{ 91 dst->bufHead = src->bufHead; 92 93#if OPT_WIDE_CHARS 94 dst->combSize = src->combSize; 95#endif 96 97 /* 98 * Usually we're copying the same-sized line; a memcpy is faster than 99 * several loops. 100 */ 101 if (dst->lineSize == src->lineSize) { 102 size_t size = (sizeof(dst->attribs[0]) 103#if OPT_ISO_COLORS 104 + sizeof(dst->color[0]) 105#endif 106 + sizeof(dst->charData[0]) 107#if OPT_WIDE_CHARS 108 + sizeof(dst->combData[0][0]) * dst->combSize 109#endif 110 ); 111 112 memcpy(dst->attribs, src->attribs, size * dst->lineSize); 113 } else { 114 Dimension col; 115 Dimension limit = ((dst->lineSize < src->lineSize) 116 ? dst->lineSize 117 : src->lineSize); 118#if OPT_WIDE_CHARS 119 Char comb; 120#endif 121 122 for (col = 0; col < limit; ++col) { 123 dst->attribs[col] = src->attribs[col]; 124#if OPT_ISO_COLORS 125 dst->color[col] = src->color[col]; 126#endif 127 dst->charData[col] = src->charData[col]; 128#if OPT_WIDE_CHARS 129 for (comb = 0; comb < dst->combSize; ++comb) { 130 dst->combData[comb][col] = src->combData[comb][col]; 131 } 132#endif 133 } 134 for (col = limit; col < dst->lineSize; ++col) { 135 dst->attribs[col] = 0; 136#if OPT_ISO_COLORS 137 dst->color[col] = 0; 138#endif 139 dst->charData[col] = 0; 140#if OPT_WIDE_CHARS 141 for (comb = 0; comb < dst->combSize; ++comb) { 142 dst->combData[comb][col] = 0; 143 } 144#endif 145 } 146 } 147} 148 149#if OPT_WIDE_CHARS 150#define initLineExtra(screen) \ 151 screen->lineExtra = ((size_t) (screen->max_combining) * sizeof(IChar *)) 152#else 153#define initLineExtra(screen) \ 154 screen->lineExtra = 0 155#endif 156 157void 158initLineData(XtermWidget xw) 159{ 160 TScreen *screen = &(xw->screen); 161 162 initLineExtra(screen); 163 164 TRACE(("initLineData %d\n", screen->lineExtra)); 165 TRACE(("...sizeof(LineData) %d\n", sizeof(LineData))); 166#if OPT_ISO_COLORS 167 TRACE(("...sizeof(CellColor) %d\n", sizeof(CellColor))); 168#endif 169 TRACE(("...sizeof(RowData) %d\n", sizeof(RowData))); 170 TRACE(("...offset(lineSize) %d\n", offsetof(LineData, lineSize))); 171 TRACE(("...offset(bufHead) %d\n", offsetof(LineData, bufHead))); 172#if OPT_WIDE_CHARS 173 TRACE(("...offset(combSize) %d\n", offsetof(LineData, combSize))); 174#endif 175 TRACE(("...offset(attribs) %d\n", offsetof(LineData, attribs))); 176#if OPT_ISO_COLORS 177 TRACE(("...offset(color) %d\n", offsetof(LineData, color))); 178#endif 179 TRACE(("...offset(charData) %d\n", offsetof(LineData, charData))); 180 TRACE(("...offset(combData) %d\n", offsetof(LineData, combData))); 181} 182 183/* 184 * CellData size depends on the "combiningChars" resource. 185 * FIXME - revise this to reduce arithmetic... 186 */ 187#define CellDataSize(screen) (SizeOfCellData + screen->lineExtra) 188 189#define CellDataAddr(screen, data, cell) \ 190 (CellData *)((char *)data + (cell * CellDataSize(screen))) 191 192CellData * 193newCellData(XtermWidget xw, Cardinal count) 194{ 195 CellData *result; 196 TScreen *screen = &(xw->screen); 197 198 initLineExtra(screen); 199 result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen)); 200 return result; 201} 202 203void 204saveCellData(TScreen * screen, 205 CellData * data, 206 Cardinal cell, 207 LineData * ld, 208 int column) 209{ 210 CellData *item = CellDataAddr(screen, data, cell); 211 212 if (column < MaxCols(screen)) { 213 item->attribs = ld->attribs[column]; 214#if OPT_ISO_COLORS 215 item->color = ld->color[column]; 216#endif 217 item->charData = ld->charData[column]; 218 if_OPT_WIDE_CHARS(screen, { 219 size_t off; 220 item->combSize = ld->combSize; 221 for_each_combData(off, ld) { 222 item->combData[off] = ld->combData[off][column]; 223 } 224 }) 225 } 226} 227 228void 229restoreCellData(TScreen * screen, 230 CellData * data, 231 Cardinal cell, 232 LineData * ld, 233 int column) 234{ 235 CellData *item = CellDataAddr(screen, data, cell); 236 237 if (column < MaxCols(screen)) { 238 ld->attribs[column] = item->attribs; 239#if OPT_ISO_COLORS 240 ld->color[column] = item->color; 241#endif 242 ld->charData[column] = item->charData; 243 if_OPT_WIDE_CHARS(screen, { 244 size_t off; 245 ld->combSize = item->combSize; 246 for_each_combData(off, ld) { 247 ld->combData[off][column] = item->combData[off]; 248 } 249 }) 250 } 251} 252