linedata.c revision c219fbeb
1c219fbebSmrg/* $XTermId: linedata.c,v 1.79 2011/01/21 00:07:35 tom Exp $ */
2956cc18dSsnj
3956cc18dSsnj/************************************************************
4956cc18dSsnj
5c219fbebSmrgCopyright 2009-2010,2011 by Thomas E. Dickey
6956cc18dSsnj
7956cc18dSsnj                        All Rights Reserved
8956cc18dSsnj
9956cc18dSsnjPermission is hereby granted, free of charge, to any person obtaining a
10956cc18dSsnjcopy of this software and associated documentation files (the
11956cc18dSsnj"Software"), to deal in the Software without restriction, including
12956cc18dSsnjwithout limitation the rights to use, copy, modify, merge, publish,
13956cc18dSsnjdistribute, sublicense, and/or sell copies of the Software, and to
14956cc18dSsnjpermit persons to whom the Software is furnished to do so, subject to
15956cc18dSsnjthe following conditions:
16956cc18dSsnj
17956cc18dSsnjThe above copyright notice and this permission notice shall be included
18956cc18dSsnjin all copies or substantial portions of the Software.
19956cc18dSsnj
20956cc18dSsnjTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21956cc18dSsnjOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22956cc18dSsnjMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23956cc18dSsnjIN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
24956cc18dSsnjCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25956cc18dSsnjTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26956cc18dSsnjSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27956cc18dSsnj
28956cc18dSsnjExcept as contained in this notice, the name(s) of the above copyright
29956cc18dSsnjholders shall not be used in advertising or otherwise to promote the
30956cc18dSsnjsale, use or other dealings in this Software without prior written
31956cc18dSsnjauthorization.
32956cc18dSsnj
33956cc18dSsnj********************************************************/
34956cc18dSsnj
35956cc18dSsnj#include <xterm.h>
36956cc18dSsnj#include <data.h>		/* FIXME - needed for 'term' */
37956cc18dSsnj
38956cc18dSsnj#include <assert.h>
39956cc18dSsnj
40956cc18dSsnj/*
41956cc18dSsnj * Given a row-number, find the corresponding data for the line in the VT100
42956cc18dSsnj * widget.  Row numbers can be positive or negative.
43956cc18dSsnj *
44956cc18dSsnj * If the data comes from the scrollback, defer that to getScrollback().
45956cc18dSsnj */
46956cc18dSsnjLineData *
47956cc18dSsnjgetLineData(TScreen * screen, int row)
48956cc18dSsnj{
49956cc18dSsnj    LineData *result = 0;
50956cc18dSsnj    ScrnBuf buffer;
5120d2c4d2Smrg    int max_row = screen->max_row;
52956cc18dSsnj
53956cc18dSsnj    if (row >= 0) {
54956cc18dSsnj	buffer = screen->visbuf;
55956cc18dSsnj    } else {
56956cc18dSsnj#if OPT_FIFO_LINES
57956cc18dSsnj	buffer = 0;
58956cc18dSsnj	result = getScrollback(screen, row);
59956cc18dSsnj#else
60956cc18dSsnj	buffer = screen->saveBuf_index;
61956cc18dSsnj	row += screen->savelines;
6220d2c4d2Smrg	max_row += screen->savelines;
63956cc18dSsnj#endif
64956cc18dSsnj    }
6520d2c4d2Smrg    if (row >= 0 && row <= max_row) {
66956cc18dSsnj	result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row);
67956cc18dSsnj	if (result != 0) {
68956cc18dSsnj#if 1				/* FIXME - these should be done in setupLineData, etc. */
69956cc18dSsnj	    result->lineSize = (Dimension) MaxCols(screen);
70956cc18dSsnj#if OPT_WIDE_CHARS
71956cc18dSsnj	    if (screen->wide_chars) {
72956cc18dSsnj		result->combSize = (Char) screen->max_combining;
73956cc18dSsnj	    } else {
74956cc18dSsnj		result->combSize = 0;
75956cc18dSsnj	    }
76956cc18dSsnj#endif
77956cc18dSsnj#endif /* FIXME */
78956cc18dSsnj	}
79956cc18dSsnj    }
80956cc18dSsnj
81956cc18dSsnj    return result;
82956cc18dSsnj}
83956cc18dSsnj
84956cc18dSsnj/*
85956cc18dSsnj * Copy line's data, e.g., from one screen buffer to another, given the preset
86956cc18dSsnj * pointers for the destination.
87956cc18dSsnj *
88956cc18dSsnj * TODO: optionally prune unused combining character data from the result.
89956cc18dSsnj */
90956cc18dSsnjvoid
91956cc18dSsnjcopyLineData(LineData * dst, LineData * src)
92956cc18dSsnj{
93956cc18dSsnj    dst->bufHead = src->bufHead;
94956cc18dSsnj
95956cc18dSsnj#if OPT_WIDE_CHARS
96956cc18dSsnj    dst->combSize = src->combSize;
97956cc18dSsnj#endif
98956cc18dSsnj
99956cc18dSsnj    /*
100956cc18dSsnj     * Usually we're copying the same-sized line; a memcpy is faster than
101956cc18dSsnj     * several loops.
102956cc18dSsnj     */
103956cc18dSsnj    if (dst->lineSize == src->lineSize) {
104956cc18dSsnj	size_t size = (sizeof(dst->attribs[0])
105956cc18dSsnj#if OPT_ISO_COLORS
106956cc18dSsnj		       + sizeof(dst->color[0])
107956cc18dSsnj#endif
108956cc18dSsnj		       + sizeof(dst->charData[0])
109956cc18dSsnj#if OPT_WIDE_CHARS
110956cc18dSsnj		       + sizeof(dst->combData[0][0]) * dst->combSize
111956cc18dSsnj#endif
112956cc18dSsnj	);
113956cc18dSsnj
114956cc18dSsnj	memcpy(dst->attribs, src->attribs, size * dst->lineSize);
115956cc18dSsnj    } else {
116956cc18dSsnj	Dimension col;
117956cc18dSsnj	Dimension limit = ((dst->lineSize < src->lineSize)
118956cc18dSsnj			   ? dst->lineSize
119956cc18dSsnj			   : src->lineSize);
120956cc18dSsnj#if OPT_WIDE_CHARS
121956cc18dSsnj	Char comb;
122956cc18dSsnj#endif
123956cc18dSsnj
124956cc18dSsnj	for (col = 0; col < limit; ++col) {
125956cc18dSsnj	    dst->attribs[col] = src->attribs[col];
126956cc18dSsnj#if OPT_ISO_COLORS
127956cc18dSsnj	    dst->color[col] = src->color[col];
128956cc18dSsnj#endif
129956cc18dSsnj	    dst->charData[col] = src->charData[col];
130956cc18dSsnj#if OPT_WIDE_CHARS
131956cc18dSsnj	    for (comb = 0; comb < dst->combSize; ++comb) {
132956cc18dSsnj		dst->combData[comb][col] = src->combData[comb][col];
133956cc18dSsnj	    }
134956cc18dSsnj#endif
135956cc18dSsnj	}
136956cc18dSsnj	for (col = limit; col < dst->lineSize; ++col) {
137956cc18dSsnj	    dst->attribs[col] = 0;
138956cc18dSsnj#if OPT_ISO_COLORS
139956cc18dSsnj	    dst->color[col] = 0;
140956cc18dSsnj#endif
141956cc18dSsnj	    dst->charData[col] = 0;
142956cc18dSsnj#if OPT_WIDE_CHARS
143956cc18dSsnj	    for (comb = 0; comb < dst->combSize; ++comb) {
144956cc18dSsnj		dst->combData[comb][col] = 0;
145956cc18dSsnj	    }
146956cc18dSsnj#endif
147956cc18dSsnj	}
148956cc18dSsnj    }
149956cc18dSsnj}
150956cc18dSsnj
151956cc18dSsnj#if OPT_WIDE_CHARS
152956cc18dSsnj#define initLineExtra(screen) \
153956cc18dSsnj    screen->lineExtra = ((size_t) (screen->max_combining) * sizeof(IChar *))
154956cc18dSsnj#else
155956cc18dSsnj#define initLineExtra(screen) \
156956cc18dSsnj    screen->lineExtra = 0
157956cc18dSsnj#endif
158956cc18dSsnj
159956cc18dSsnjvoid
160956cc18dSsnjinitLineData(XtermWidget xw)
161956cc18dSsnj{
16220d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
163956cc18dSsnj
164956cc18dSsnj    initLineExtra(screen);
165956cc18dSsnj
16620d2c4d2Smrg    TRACE(("initLineData %lu\n", (unsigned long) screen->lineExtra));
16720d2c4d2Smrg    TRACE(("...sizeof(LineData)  %lu\n", (unsigned long) sizeof(LineData)));
168956cc18dSsnj#if OPT_ISO_COLORS
16920d2c4d2Smrg    TRACE(("...sizeof(CellColor) %lu\n", (unsigned long) sizeof(CellColor)));
170956cc18dSsnj#endif
17120d2c4d2Smrg    TRACE(("...sizeof(RowData)   %lu\n", (unsigned long) sizeof(RowData)));
17220d2c4d2Smrg    TRACE(("...offset(lineSize)  %lu\n", (unsigned long) offsetof(LineData, lineSize)));
17320d2c4d2Smrg    TRACE(("...offset(bufHead)   %lu\n", (unsigned long) offsetof(LineData, bufHead)));
174956cc18dSsnj#if OPT_WIDE_CHARS
17520d2c4d2Smrg    TRACE(("...offset(combSize)  %lu\n", (unsigned long) offsetof(LineData, combSize)));
176956cc18dSsnj#endif
17720d2c4d2Smrg    TRACE(("...offset(attribs)   %lu\n", (unsigned long) offsetof(LineData, attribs)));
178956cc18dSsnj#if OPT_ISO_COLORS
17920d2c4d2Smrg    TRACE(("...offset(color)     %lu\n", (unsigned long) offsetof(LineData, color)));
180956cc18dSsnj#endif
18120d2c4d2Smrg    TRACE(("...offset(charData)  %lu\n", (unsigned long) offsetof(LineData, charData)));
18220d2c4d2Smrg    TRACE(("...offset(combData)  %lu\n", (unsigned long) offsetof(LineData, combData)));
183956cc18dSsnj}
184956cc18dSsnj
185956cc18dSsnj/*
186956cc18dSsnj * CellData size depends on the "combiningChars" resource.
187956cc18dSsnj * FIXME - revise this to reduce arithmetic...
188956cc18dSsnj */
189956cc18dSsnj#define CellDataSize(screen) (SizeOfCellData + screen->lineExtra)
190956cc18dSsnj
191956cc18dSsnj#define CellDataAddr(screen, data, cell) \
192c219fbebSmrg	(CellData *)(void *) ((char *)data + (cell * CellDataSize(screen)))
193956cc18dSsnj
194956cc18dSsnjCellData *
195956cc18dSsnjnewCellData(XtermWidget xw, Cardinal count)
196956cc18dSsnj{
197956cc18dSsnj    CellData *result;
19820d2c4d2Smrg    TScreen *screen = TScreenOf(xw);
199956cc18dSsnj
200956cc18dSsnj    initLineExtra(screen);
201956cc18dSsnj    result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen));
202956cc18dSsnj    return result;
203956cc18dSsnj}
204956cc18dSsnj
205956cc18dSsnjvoid
206956cc18dSsnjsaveCellData(TScreen * screen,
207956cc18dSsnj	     CellData * data,
208956cc18dSsnj	     Cardinal cell,
209956cc18dSsnj	     LineData * ld,
210956cc18dSsnj	     int column)
211956cc18dSsnj{
212956cc18dSsnj    CellData *item = CellDataAddr(screen, data, cell);
213956cc18dSsnj
214956cc18dSsnj    if (column < MaxCols(screen)) {
215956cc18dSsnj	item->attribs = ld->attribs[column];
216956cc18dSsnj#if OPT_ISO_COLORS
217956cc18dSsnj	item->color = ld->color[column];
218956cc18dSsnj#endif
219956cc18dSsnj	item->charData = ld->charData[column];
220956cc18dSsnj	if_OPT_WIDE_CHARS(screen, {
221956cc18dSsnj	    size_t off;
222956cc18dSsnj	    item->combSize = ld->combSize;
223956cc18dSsnj	    for_each_combData(off, ld) {
224956cc18dSsnj		item->combData[off] = ld->combData[off][column];
225956cc18dSsnj	    }
226956cc18dSsnj	})
227956cc18dSsnj    }
228956cc18dSsnj}
229956cc18dSsnj
230956cc18dSsnjvoid
231956cc18dSsnjrestoreCellData(TScreen * screen,
232956cc18dSsnj		CellData * data,
233956cc18dSsnj		Cardinal cell,
234956cc18dSsnj		LineData * ld,
235956cc18dSsnj		int column)
236956cc18dSsnj{
237956cc18dSsnj    CellData *item = CellDataAddr(screen, data, cell);
238956cc18dSsnj
239956cc18dSsnj    if (column < MaxCols(screen)) {
240956cc18dSsnj	ld->attribs[column] = item->attribs;
241956cc18dSsnj#if OPT_ISO_COLORS
242956cc18dSsnj	ld->color[column] = item->color;
243956cc18dSsnj#endif
244956cc18dSsnj	ld->charData[column] = item->charData;
245956cc18dSsnj	if_OPT_WIDE_CHARS(screen, {
246956cc18dSsnj	    size_t off;
247956cc18dSsnj	    ld->combSize = item->combSize;
248956cc18dSsnj	    for_each_combData(off, ld) {
249956cc18dSsnj		ld->combData[off][column] = item->combData[off];
250956cc18dSsnj	    }
251956cc18dSsnj	})
252956cc18dSsnj    }
253956cc18dSsnj}
254