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