linedata.c revision c219fbeb
1/* $XTermId: linedata.c,v 1.79 2011/01/21 00:07:35 tom Exp $ */ 2 3/************************************************************ 4 5Copyright 2009-2010,2011 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 int max_row = screen->max_row; 52 53 if (row >= 0) { 54 buffer = screen->visbuf; 55 } else { 56#if OPT_FIFO_LINES 57 buffer = 0; 58 result = getScrollback(screen, row); 59#else 60 buffer = screen->saveBuf_index; 61 row += screen->savelines; 62 max_row += screen->savelines; 63#endif 64 } 65 if (row >= 0 && row <= max_row) { 66 result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row); 67 if (result != 0) { 68#if 1 /* FIXME - these should be done in setupLineData, etc. */ 69 result->lineSize = (Dimension) MaxCols(screen); 70#if OPT_WIDE_CHARS 71 if (screen->wide_chars) { 72 result->combSize = (Char) screen->max_combining; 73 } else { 74 result->combSize = 0; 75 } 76#endif 77#endif /* FIXME */ 78 } 79 } 80 81 return result; 82} 83 84/* 85 * Copy line's data, e.g., from one screen buffer to another, given the preset 86 * pointers for the destination. 87 * 88 * TODO: optionally prune unused combining character data from the result. 89 */ 90void 91copyLineData(LineData * dst, LineData * src) 92{ 93 dst->bufHead = src->bufHead; 94 95#if OPT_WIDE_CHARS 96 dst->combSize = src->combSize; 97#endif 98 99 /* 100 * Usually we're copying the same-sized line; a memcpy is faster than 101 * several loops. 102 */ 103 if (dst->lineSize == src->lineSize) { 104 size_t size = (sizeof(dst->attribs[0]) 105#if OPT_ISO_COLORS 106 + sizeof(dst->color[0]) 107#endif 108 + sizeof(dst->charData[0]) 109#if OPT_WIDE_CHARS 110 + sizeof(dst->combData[0][0]) * dst->combSize 111#endif 112 ); 113 114 memcpy(dst->attribs, src->attribs, size * dst->lineSize); 115 } else { 116 Dimension col; 117 Dimension limit = ((dst->lineSize < src->lineSize) 118 ? dst->lineSize 119 : src->lineSize); 120#if OPT_WIDE_CHARS 121 Char comb; 122#endif 123 124 for (col = 0; col < limit; ++col) { 125 dst->attribs[col] = src->attribs[col]; 126#if OPT_ISO_COLORS 127 dst->color[col] = src->color[col]; 128#endif 129 dst->charData[col] = src->charData[col]; 130#if OPT_WIDE_CHARS 131 for (comb = 0; comb < dst->combSize; ++comb) { 132 dst->combData[comb][col] = src->combData[comb][col]; 133 } 134#endif 135 } 136 for (col = limit; col < dst->lineSize; ++col) { 137 dst->attribs[col] = 0; 138#if OPT_ISO_COLORS 139 dst->color[col] = 0; 140#endif 141 dst->charData[col] = 0; 142#if OPT_WIDE_CHARS 143 for (comb = 0; comb < dst->combSize; ++comb) { 144 dst->combData[comb][col] = 0; 145 } 146#endif 147 } 148 } 149} 150 151#if OPT_WIDE_CHARS 152#define initLineExtra(screen) \ 153 screen->lineExtra = ((size_t) (screen->max_combining) * sizeof(IChar *)) 154#else 155#define initLineExtra(screen) \ 156 screen->lineExtra = 0 157#endif 158 159void 160initLineData(XtermWidget xw) 161{ 162 TScreen *screen = TScreenOf(xw); 163 164 initLineExtra(screen); 165 166 TRACE(("initLineData %lu\n", (unsigned long) screen->lineExtra)); 167 TRACE(("...sizeof(LineData) %lu\n", (unsigned long) sizeof(LineData))); 168#if OPT_ISO_COLORS 169 TRACE(("...sizeof(CellColor) %lu\n", (unsigned long) sizeof(CellColor))); 170#endif 171 TRACE(("...sizeof(RowData) %lu\n", (unsigned long) sizeof(RowData))); 172 TRACE(("...offset(lineSize) %lu\n", (unsigned long) offsetof(LineData, lineSize))); 173 TRACE(("...offset(bufHead) %lu\n", (unsigned long) offsetof(LineData, bufHead))); 174#if OPT_WIDE_CHARS 175 TRACE(("...offset(combSize) %lu\n", (unsigned long) offsetof(LineData, combSize))); 176#endif 177 TRACE(("...offset(attribs) %lu\n", (unsigned long) offsetof(LineData, attribs))); 178#if OPT_ISO_COLORS 179 TRACE(("...offset(color) %lu\n", (unsigned long) offsetof(LineData, color))); 180#endif 181 TRACE(("...offset(charData) %lu\n", (unsigned long) offsetof(LineData, charData))); 182 TRACE(("...offset(combData) %lu\n", (unsigned long) offsetof(LineData, combData))); 183} 184 185/* 186 * CellData size depends on the "combiningChars" resource. 187 * FIXME - revise this to reduce arithmetic... 188 */ 189#define CellDataSize(screen) (SizeOfCellData + screen->lineExtra) 190 191#define CellDataAddr(screen, data, cell) \ 192 (CellData *)(void *) ((char *)data + (cell * CellDataSize(screen))) 193 194CellData * 195newCellData(XtermWidget xw, Cardinal count) 196{ 197 CellData *result; 198 TScreen *screen = TScreenOf(xw); 199 200 initLineExtra(screen); 201 result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen)); 202 return result; 203} 204 205void 206saveCellData(TScreen * screen, 207 CellData * data, 208 Cardinal cell, 209 LineData * ld, 210 int column) 211{ 212 CellData *item = CellDataAddr(screen, data, cell); 213 214 if (column < MaxCols(screen)) { 215 item->attribs = ld->attribs[column]; 216#if OPT_ISO_COLORS 217 item->color = ld->color[column]; 218#endif 219 item->charData = ld->charData[column]; 220 if_OPT_WIDE_CHARS(screen, { 221 size_t off; 222 item->combSize = ld->combSize; 223 for_each_combData(off, ld) { 224 item->combData[off] = ld->combData[off][column]; 225 } 226 }) 227 } 228} 229 230void 231restoreCellData(TScreen * screen, 232 CellData * data, 233 Cardinal cell, 234 LineData * ld, 235 int column) 236{ 237 CellData *item = CellDataAddr(screen, data, cell); 238 239 if (column < MaxCols(screen)) { 240 ld->attribs[column] = item->attribs; 241#if OPT_ISO_COLORS 242 ld->color[column] = item->color; 243#endif 244 ld->charData[column] = item->charData; 245 if_OPT_WIDE_CHARS(screen, { 246 size_t off; 247 ld->combSize = item->combSize; 248 for_each_combData(off, ld) { 249 ld->combData[off][column] = item->combData[off]; 250 } 251 }) 252 } 253} 254