summaryrefslogtreecommitdiff
path: root/linedata.c
diff options
context:
space:
mode:
Diffstat (limited to 'linedata.c')
-rw-r--r--linedata.c251
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];
+ }
+ })
+ }
+}