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