linedata.c revision 956cc18d
1956cc18dSsnj/* $XTermId: linedata.c,v 1.71 2009/08/09 00:34:16 tom Exp $ */
2956cc18dSsnj
3956cc18dSsnj/************************************************************
4956cc18dSsnj
5956cc18dSsnjCopyright 2009 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;
51956cc18dSsnj
52956cc18dSsnj    if (row >= 0) {
53956cc18dSsnj	buffer = screen->visbuf;
54956cc18dSsnj    } else {
55956cc18dSsnj#if OPT_FIFO_LINES
56956cc18dSsnj	buffer = 0;
57956cc18dSsnj	result = getScrollback(screen, row);
58956cc18dSsnj#else
59956cc18dSsnj	buffer = screen->saveBuf_index;
60956cc18dSsnj	row += screen->savelines;
61956cc18dSsnj#endif
62956cc18dSsnj    }
63956cc18dSsnj    if (row >= 0) {
64956cc18dSsnj	result = (LineData *) scrnHeadAddr(screen, buffer, (unsigned) row);
65956cc18dSsnj	if (result != 0) {
66956cc18dSsnj#if 1				/* FIXME - these should be done in setupLineData, etc. */
67956cc18dSsnj	    result->lineSize = (Dimension) MaxCols(screen);
68956cc18dSsnj#if OPT_WIDE_CHARS
69956cc18dSsnj	    if (screen->wide_chars) {
70956cc18dSsnj		result->combSize = (Char) screen->max_combining;
71956cc18dSsnj	    } else {
72956cc18dSsnj		result->combSize = 0;
73956cc18dSsnj	    }
74956cc18dSsnj#endif
75956cc18dSsnj#endif /* FIXME */
76956cc18dSsnj	}
77956cc18dSsnj    }
78956cc18dSsnj
79956cc18dSsnj    return result;
80956cc18dSsnj}
81956cc18dSsnj
82956cc18dSsnj/*
83956cc18dSsnj * Copy line's data, e.g., from one screen buffer to another, given the preset
84956cc18dSsnj * pointers for the destination.
85956cc18dSsnj *
86956cc18dSsnj * TODO: optionally prune unused combining character data from the result.
87956cc18dSsnj */
88956cc18dSsnjvoid
89956cc18dSsnjcopyLineData(LineData * dst, LineData * src)
90956cc18dSsnj{
91956cc18dSsnj    dst->bufHead = src->bufHead;
92956cc18dSsnj
93956cc18dSsnj#if OPT_WIDE_CHARS
94956cc18dSsnj    dst->combSize = src->combSize;
95956cc18dSsnj#endif
96956cc18dSsnj
97956cc18dSsnj    /*
98956cc18dSsnj     * Usually we're copying the same-sized line; a memcpy is faster than
99956cc18dSsnj     * several loops.
100956cc18dSsnj     */
101956cc18dSsnj    if (dst->lineSize == src->lineSize) {
102956cc18dSsnj	size_t size = (sizeof(dst->attribs[0])
103956cc18dSsnj#if OPT_ISO_COLORS
104956cc18dSsnj		       + sizeof(dst->color[0])
105956cc18dSsnj#endif
106956cc18dSsnj		       + sizeof(dst->charData[0])
107956cc18dSsnj#if OPT_WIDE_CHARS
108956cc18dSsnj		       + sizeof(dst->combData[0][0]) * dst->combSize
109956cc18dSsnj#endif
110956cc18dSsnj	);
111956cc18dSsnj
112956cc18dSsnj	memcpy(dst->attribs, src->attribs, size * dst->lineSize);
113956cc18dSsnj    } else {
114956cc18dSsnj	Dimension col;
115956cc18dSsnj	Dimension limit = ((dst->lineSize < src->lineSize)
116956cc18dSsnj			   ? dst->lineSize
117956cc18dSsnj			   : src->lineSize);
118956cc18dSsnj#if OPT_WIDE_CHARS
119956cc18dSsnj	Char comb;
120956cc18dSsnj#endif
121956cc18dSsnj
122956cc18dSsnj	for (col = 0; col < limit; ++col) {
123956cc18dSsnj	    dst->attribs[col] = src->attribs[col];
124956cc18dSsnj#if OPT_ISO_COLORS
125956cc18dSsnj	    dst->color[col] = src->color[col];
126956cc18dSsnj#endif
127956cc18dSsnj	    dst->charData[col] = src->charData[col];
128956cc18dSsnj#if OPT_WIDE_CHARS
129956cc18dSsnj	    for (comb = 0; comb < dst->combSize; ++comb) {
130956cc18dSsnj		dst->combData[comb][col] = src->combData[comb][col];
131956cc18dSsnj	    }
132956cc18dSsnj#endif
133956cc18dSsnj	}
134956cc18dSsnj	for (col = limit; col < dst->lineSize; ++col) {
135956cc18dSsnj	    dst->attribs[col] = 0;
136956cc18dSsnj#if OPT_ISO_COLORS
137956cc18dSsnj	    dst->color[col] = 0;
138956cc18dSsnj#endif
139956cc18dSsnj	    dst->charData[col] = 0;
140956cc18dSsnj#if OPT_WIDE_CHARS
141956cc18dSsnj	    for (comb = 0; comb < dst->combSize; ++comb) {
142956cc18dSsnj		dst->combData[comb][col] = 0;
143956cc18dSsnj	    }
144956cc18dSsnj#endif
145956cc18dSsnj	}
146956cc18dSsnj    }
147956cc18dSsnj}
148956cc18dSsnj
149956cc18dSsnj#if OPT_WIDE_CHARS
150956cc18dSsnj#define initLineExtra(screen) \
151956cc18dSsnj    screen->lineExtra = ((size_t) (screen->max_combining) * sizeof(IChar *))
152956cc18dSsnj#else
153956cc18dSsnj#define initLineExtra(screen) \
154956cc18dSsnj    screen->lineExtra = 0
155956cc18dSsnj#endif
156956cc18dSsnj
157956cc18dSsnjvoid
158956cc18dSsnjinitLineData(XtermWidget xw)
159956cc18dSsnj{
160956cc18dSsnj    TScreen *screen = &(xw->screen);
161956cc18dSsnj
162956cc18dSsnj    initLineExtra(screen);
163956cc18dSsnj
164956cc18dSsnj    TRACE(("initLineData %d\n", screen->lineExtra));
165956cc18dSsnj    TRACE(("...sizeof(LineData)  %d\n", sizeof(LineData)));
166956cc18dSsnj#if OPT_ISO_COLORS
167956cc18dSsnj    TRACE(("...sizeof(CellColor) %d\n", sizeof(CellColor)));
168956cc18dSsnj#endif
169956cc18dSsnj    TRACE(("...sizeof(RowData)   %d\n", sizeof(RowData)));
170956cc18dSsnj    TRACE(("...offset(lineSize)  %d\n", offsetof(LineData, lineSize)));
171956cc18dSsnj    TRACE(("...offset(bufHead)   %d\n", offsetof(LineData, bufHead)));
172956cc18dSsnj#if OPT_WIDE_CHARS
173956cc18dSsnj    TRACE(("...offset(combSize)  %d\n", offsetof(LineData, combSize)));
174956cc18dSsnj#endif
175956cc18dSsnj    TRACE(("...offset(attribs)   %d\n", offsetof(LineData, attribs)));
176956cc18dSsnj#if OPT_ISO_COLORS
177956cc18dSsnj    TRACE(("...offset(color)     %d\n", offsetof(LineData, color)));
178956cc18dSsnj#endif
179956cc18dSsnj    TRACE(("...offset(charData)  %d\n", offsetof(LineData, charData)));
180956cc18dSsnj    TRACE(("...offset(combData)  %d\n", offsetof(LineData, combData)));
181956cc18dSsnj}
182956cc18dSsnj
183956cc18dSsnj/*
184956cc18dSsnj * CellData size depends on the "combiningChars" resource.
185956cc18dSsnj * FIXME - revise this to reduce arithmetic...
186956cc18dSsnj */
187956cc18dSsnj#define CellDataSize(screen) (SizeOfCellData + screen->lineExtra)
188956cc18dSsnj
189956cc18dSsnj#define CellDataAddr(screen, data, cell) \
190956cc18dSsnj	(CellData *)((char *)data + (cell * CellDataSize(screen)))
191956cc18dSsnj
192956cc18dSsnjCellData *
193956cc18dSsnjnewCellData(XtermWidget xw, Cardinal count)
194956cc18dSsnj{
195956cc18dSsnj    CellData *result;
196956cc18dSsnj    TScreen *screen = &(xw->screen);
197956cc18dSsnj
198956cc18dSsnj    initLineExtra(screen);
199956cc18dSsnj    result = (CellData *) calloc((size_t) count, (size_t) CellDataSize(screen));
200956cc18dSsnj    return result;
201956cc18dSsnj}
202956cc18dSsnj
203956cc18dSsnjvoid
204956cc18dSsnjsaveCellData(TScreen * screen,
205956cc18dSsnj	     CellData * data,
206956cc18dSsnj	     Cardinal cell,
207956cc18dSsnj	     LineData * ld,
208956cc18dSsnj	     int column)
209956cc18dSsnj{
210956cc18dSsnj    CellData *item = CellDataAddr(screen, data, cell);
211956cc18dSsnj
212956cc18dSsnj    if (column < MaxCols(screen)) {
213956cc18dSsnj	item->attribs = ld->attribs[column];
214956cc18dSsnj#if OPT_ISO_COLORS
215956cc18dSsnj	item->color = ld->color[column];
216956cc18dSsnj#endif
217956cc18dSsnj	item->charData = ld->charData[column];
218956cc18dSsnj	if_OPT_WIDE_CHARS(screen, {
219956cc18dSsnj	    size_t off;
220956cc18dSsnj	    item->combSize = ld->combSize;
221956cc18dSsnj	    for_each_combData(off, ld) {
222956cc18dSsnj		item->combData[off] = ld->combData[off][column];
223956cc18dSsnj	    }
224956cc18dSsnj	})
225956cc18dSsnj    }
226956cc18dSsnj}
227956cc18dSsnj
228956cc18dSsnjvoid
229956cc18dSsnjrestoreCellData(TScreen * screen,
230956cc18dSsnj		CellData * data,
231956cc18dSsnj		Cardinal cell,
232956cc18dSsnj		LineData * ld,
233956cc18dSsnj		int column)
234956cc18dSsnj{
235956cc18dSsnj    CellData *item = CellDataAddr(screen, data, cell);
236956cc18dSsnj
237956cc18dSsnj    if (column < MaxCols(screen)) {
238956cc18dSsnj	ld->attribs[column] = item->attribs;
239956cc18dSsnj#if OPT_ISO_COLORS
240956cc18dSsnj	ld->color[column] = item->color;
241956cc18dSsnj#endif
242956cc18dSsnj	ld->charData[column] = item->charData;
243956cc18dSsnj	if_OPT_WIDE_CHARS(screen, {
244956cc18dSsnj	    size_t off;
245956cc18dSsnj	    ld->combSize = item->combSize;
246956cc18dSsnj	    for_each_combData(off, ld) {
247956cc18dSsnj		ld->combData[off][column] = item->combData[off];
248956cc18dSsnj	    }
249956cc18dSsnj	})
250956cc18dSsnj    }
251956cc18dSsnj}
252