diff options
Diffstat (limited to 'linedata.c')
-rw-r--r-- | linedata.c | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/linedata.c b/linedata.c new file mode 100644 index 0000000..fed072f --- /dev/null +++ b/linedata.c @@ -0,0 +1,251 @@ +/* $XTermId: linedata.c,v 1.80 2011/09/11 14:59:39 tom Exp $ */ + +/* + * Copyright 2009-2010,2011 by Thomas E. Dickey + * + * All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above copyright + * holders shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization. + */ + +#include <xterm.h> +#include <data.h> /* FIXME - needed for 'term' */ + +#include <assert.h> + +/* + * Given a row-number, find the corresponding data for the line in the VT100 + * widget. Row numbers can be positive or negative. + * + * If the data comes from the scrollback, defer that to getScrollback(). + */ +LineData * +getLineData(TScreen * screen, int row) +{ + LineData *result = 0; + ScrnBuf buffer; + int max_row = screen->max_row; + + if (row >= 0) { + buffer = screen->visbuf; + } else { +#if OPT_FIFO_LINES + buffer = 0; + result = getScrollback(screen, row); +#else + buffer = screen->saveBuf_index; + row += screen->savelines; + max_row += screen->savelines; +#endif + } + if (row >= 0 && row <= max_row) { + result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row); + if (result != 0) { +#if 1 /* FIXME - these should be done in setupLineData, etc. */ + result->lineSize = (Dimension) MaxCols(screen); +#if OPT_WIDE_CHARS + if (screen->wide_chars) { + result->combSize = (Char) screen->max_combining; + } else { + result->combSize = 0; + } +#endif +#endif /* FIXME */ + } + } + + return result; +} + +/* + * Copy line's data, e.g., from one screen buffer to another, given the preset + * pointers for the destination. + * + * TODO: optionally prune unused combining character data from the result. + */ +void +copyLineData(LineData * dst, LineData * src) +{ + dst->bufHead = src->bufHead; + +#if OPT_WIDE_CHARS + dst->combSize = src->combSize; +#endif + + /* + * Usually we're copying the same-sized line; a memcpy is faster than + * several loops. + */ + if (dst->lineSize == src->lineSize) { + size_t size = (sizeof(dst->attribs[0]) +#if OPT_ISO_COLORS + + sizeof(dst->color[0]) +#endif + + sizeof(dst->charData[0]) +#if OPT_WIDE_CHARS + + sizeof(dst->combData[0][0]) * dst->combSize +#endif + ); + + memcpy(dst->attribs, src->attribs, size * dst->lineSize); + } else { + Dimension col; + Dimension limit = ((dst->lineSize < src->lineSize) + ? dst->lineSize + : src->lineSize); +#if OPT_WIDE_CHARS + Char comb; +#endif + + for (col = 0; col < limit; ++col) { + dst->attribs[col] = src->attribs[col]; +#if OPT_ISO_COLORS + dst->color[col] = src->color[col]; +#endif + dst->charData[col] = src->charData[col]; +#if OPT_WIDE_CHARS + for (comb = 0; comb < dst->combSize; ++comb) { + dst->combData[comb][col] = src->combData[comb][col]; + } +#endif + } + for (col = limit; col < dst->lineSize; ++col) { + dst->attribs[col] = 0; +#if OPT_ISO_COLORS + dst->color[col] = 0; +#endif + dst->charData[col] = 0; +#if OPT_WIDE_CHARS + for (comb = 0; comb < dst->combSize; ++comb) { + dst->combData[comb][col] = 0; + } +#endif + } + } +} + +#if OPT_WIDE_CHARS +#define initLineExtra(screen) \ + screen->lineExtra = ((size_t) (screen->max_combining) * sizeof(IChar *)) +#else +#define initLineExtra(screen) \ + screen->lineExtra = 0 +#endif + +void +initLineData(XtermWidget xw) +{ + TScreen *screen = TScreenOf(xw); + + initLineExtra(screen); + + TRACE(("initLineData %lu\n", (unsigned long) screen->lineExtra)); + TRACE(("...sizeof(LineData) %lu\n", (unsigned long) sizeof(LineData))); +#if OPT_ISO_COLORS + TRACE(("...sizeof(CellColor) %lu\n", (unsigned long) sizeof(CellColor))); +#endif + TRACE(("...sizeof(RowData) %lu\n", (unsigned long) sizeof(RowData))); + TRACE(("...offset(lineSize) %lu\n", (unsigned long) offsetof(LineData, lineSize))); + TRACE(("...offset(bufHead) %lu\n", (unsigned long) offsetof(LineData, bufHead))); +#if OPT_WIDE_CHARS + TRACE(("...offset(combSize) %lu\n", (unsigned long) offsetof(LineData, combSize))); +#endif + TRACE(("...offset(attribs) %lu\n", (unsigned long) offsetof(LineData, attribs))); +#if OPT_ISO_COLORS + TRACE(("...offset(color) %lu\n", (unsigned long) offsetof(LineData, color))); +#endif + TRACE(("...offset(charData) %lu\n", (unsigned long) offsetof(LineData, charData))); + TRACE(("...offset(combData) %lu\n", (unsigned long) offsetof(LineData, combData))); +} + +/* + * CellData size depends on the "combiningChars" resource. + * FIXME - revise this to reduce arithmetic... + */ +#define CellDataSize(screen) (SizeOfCellData + screen->lineExtra) + +#define CellDataAddr(screen, data, cell) \ + (CellData *)(void *) ((char *)data + (cell * CellDataSize(screen))) + +CellData * +newCellData(XtermWidget xw, Cardinal count) +{ + CellData *result; + TScreen *screen = TScreenOf(xw); + + initLineExtra(screen); + result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen)); + return result; +} + +void +saveCellData(TScreen * screen, + CellData * data, + Cardinal cell, + LineData * ld, + int column) +{ + CellData *item = CellDataAddr(screen, data, cell); + + if (column < MaxCols(screen)) { + item->attribs = ld->attribs[column]; +#if OPT_ISO_COLORS + item->color = ld->color[column]; +#endif + item->charData = ld->charData[column]; + if_OPT_WIDE_CHARS(screen, { + size_t off; + item->combSize = ld->combSize; + for_each_combData(off, ld) { + item->combData[off] = ld->combData[off][column]; + } + }) + } +} + +void +restoreCellData(TScreen * screen, + CellData * data, + Cardinal cell, + LineData * ld, + int column) +{ + CellData *item = CellDataAddr(screen, data, cell); + + if (column < MaxCols(screen)) { + ld->attribs[column] = item->attribs; +#if OPT_ISO_COLORS + ld->color[column] = item->color; +#endif + ld->charData[column] = item->charData; + if_OPT_WIDE_CHARS(screen, { + size_t off; + ld->combSize = item->combSize; + for_each_combData(off, ld) { + ld->combData[off][column] = item->combData[off]; + } + }) + } +} |