Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Kitware
GitHub Repository: Kitware/CMake
Path: blob/master/Utilities/cmpdcurses/wincon/pdcdisp.c
3153 views
1
/* PDCurses */
2
3
#include "pdcwin.h"
4
5
#include <stdlib.h>
6
#include <string.h>
7
8
#ifdef PDC_WIDE
9
# include "../common/acsuni.h"
10
#else
11
# include "../common/acs437.h"
12
#endif
13
14
DWORD pdc_last_blink;
15
static bool blinked_off = FALSE;
16
static bool in_italic = FALSE;
17
18
/* position hardware cursor at (y, x) */
19
20
void PDC_gotoyx(int row, int col)
21
{
22
COORD coord;
23
24
PDC_LOG(("PDC_gotoyx() - called: row %d col %d from row %d col %d\n",
25
row, col, SP->cursrow, SP->curscol));
26
27
coord.X = col;
28
coord.Y = row;
29
30
SetConsoleCursorPosition(pdc_con_out, coord);
31
}
32
33
void _set_ansi_color(short f, short b, attr_t attr)
34
{
35
char esc[64], *p;
36
short tmp, underline;
37
bool italic;
38
39
if (f < 16 && !pdc_color[f].mapped)
40
f = pdc_curstoansi[f];
41
42
if (b < 16 && !pdc_color[b].mapped)
43
b = pdc_curstoansi[b];
44
45
if (attr & A_REVERSE)
46
{
47
tmp = f;
48
f = b;
49
b = tmp;
50
}
51
attr &= SP->termattrs;
52
italic = !!(attr & A_ITALIC);
53
underline = !!(attr & A_UNDERLINE);
54
55
p = esc + sprintf(esc, "\x1b[");
56
57
if (f != pdc_oldf)
58
{
59
if (f < 8 && !pdc_color[f].mapped)
60
p += sprintf(p, "%d", f + 30);
61
else if (f < 16 && !pdc_color[f].mapped)
62
p += sprintf(p, "%d", f + 82);
63
else if (f < 256 && !pdc_color[f].mapped)
64
p += sprintf(p, "38;5;%d", f);
65
else
66
{
67
short red = DIVROUND(pdc_color[f].r * 255, 1000);
68
short green = DIVROUND(pdc_color[f].g * 255, 1000);
69
short blue = DIVROUND(pdc_color[f].b * 255, 1000);
70
71
p += sprintf(p, "38;2;%d;%d;%d", red, green, blue);
72
}
73
74
pdc_oldf = f;
75
}
76
77
if (b != pdc_oldb)
78
{
79
if (strlen(esc) > 2)
80
p += sprintf(p, ";");
81
82
if (b < 8 && !pdc_color[b].mapped)
83
p += sprintf(p, "%d", b + 40);
84
else if (b < 16 && !pdc_color[b].mapped)
85
p += sprintf(p, "%d", b + 92);
86
else if (b < 256 && !pdc_color[b].mapped)
87
p += sprintf(p, "48;5;%d", b);
88
else
89
{
90
short red = DIVROUND(pdc_color[b].r * 255, 1000);
91
short green = DIVROUND(pdc_color[b].g * 255, 1000);
92
short blue = DIVROUND(pdc_color[b].b * 255, 1000);
93
94
p += sprintf(p, "48;2;%d;%d;%d", red, green, blue);
95
}
96
97
pdc_oldb = b;
98
}
99
100
if (italic != in_italic)
101
{
102
if (strlen(esc) > 2)
103
p += sprintf(p, ";");
104
105
if (italic)
106
p += sprintf(p, "3");
107
else
108
p += sprintf(p, "23");
109
110
in_italic = italic;
111
}
112
113
if (underline != pdc_oldu)
114
{
115
if (strlen(esc) > 2)
116
p += sprintf(p, ";");
117
118
if (underline)
119
p += sprintf(p, "4");
120
else
121
p += sprintf(p, "24");
122
123
pdc_oldu = underline;
124
}
125
126
if (strlen(esc) > 2)
127
{
128
sprintf(p, "m");
129
if (!pdc_conemu)
130
SetConsoleMode(pdc_con_out, 0x0015);
131
132
WriteConsoleA(pdc_con_out, esc, strlen(esc), NULL, NULL);
133
134
if (!pdc_conemu)
135
SetConsoleMode(pdc_con_out, 0x0010);
136
}
137
}
138
139
void _new_packet(attr_t attr, int lineno, int x, int len, const chtype *srcp)
140
{
141
int j;
142
short fore, back;
143
bool blink, ansi;
144
145
if (pdc_ansi && (lineno == (SP->lines - 1)) && ((x + len) == SP->cols))
146
{
147
len--;
148
if (len)
149
_new_packet(attr, lineno, x, len, srcp);
150
pdc_ansi = FALSE;
151
_new_packet(attr, lineno, x + len, 1, srcp + len);
152
pdc_ansi = TRUE;
153
return;
154
}
155
156
pair_content(PAIR_NUMBER(attr), &fore, &back);
157
ansi = pdc_ansi || (fore >= 16 || back >= 16);
158
blink = (SP->termattrs & A_BLINK) && (attr & A_BLINK);
159
160
if (blink)
161
{
162
attr &= ~A_BLINK;
163
if (blinked_off)
164
attr &= ~(A_UNDERLINE | A_RIGHT | A_LEFT);
165
}
166
167
if (attr & A_BOLD)
168
fore |= 8;
169
if (attr & A_BLINK)
170
back |= 8;
171
172
if (ansi)
173
{
174
#ifdef PDC_WIDE
175
WCHAR buffer[512];
176
#else
177
char buffer[512];
178
#endif
179
for (j = 0; j < len; j++)
180
{
181
chtype ch = srcp[j];
182
183
if (ch & A_ALTCHARSET && !(ch & 0xff80))
184
{
185
ch = acs_map[ch & 0x7f];
186
187
if (pdc_wt && (ch & A_CHARTEXT) < ' ')
188
goto NONANSI;
189
}
190
191
if (blink && blinked_off)
192
ch = ' ';
193
194
buffer[j] = ch & A_CHARTEXT;
195
}
196
197
PDC_gotoyx(lineno, x);
198
_set_ansi_color(fore, back, attr);
199
#ifdef PDC_WIDE
200
WriteConsoleW(pdc_con_out, buffer, len, NULL, NULL);
201
#else
202
WriteConsoleA(pdc_con_out, buffer, len, NULL, NULL);
203
#endif
204
}
205
else
206
NONANSI:
207
{
208
CHAR_INFO buffer[512];
209
COORD bufSize, bufPos;
210
SMALL_RECT sr;
211
WORD mapped_attr;
212
213
fore = pdc_curstoreal[fore];
214
back = pdc_curstoreal[back];
215
216
if (attr & A_REVERSE)
217
mapped_attr = back | (fore << 4);
218
else
219
mapped_attr = fore | (back << 4);
220
221
if (attr & A_UNDERLINE)
222
mapped_attr |= 0x8000; /* COMMON_LVB_UNDERSCORE */
223
if (attr & A_LEFT)
224
mapped_attr |= 0x0800; /* COMMON_LVB_GRID_LVERTICAL */
225
if (attr & A_RIGHT)
226
mapped_attr |= 0x1000; /* COMMON_LVB_GRID_RVERTICAL */
227
228
for (j = 0; j < len; j++)
229
{
230
chtype ch = srcp[j];
231
232
if (ch & A_ALTCHARSET && !(ch & 0xff80))
233
ch = acs_map[ch & 0x7f];
234
235
if (blink && blinked_off)
236
ch = ' ';
237
238
buffer[j].Attributes = mapped_attr;
239
buffer[j].Char.UnicodeChar = ch & A_CHARTEXT;
240
}
241
242
bufPos.X = bufPos.Y = 0;
243
bufSize.X = len;
244
bufSize.Y = 1;
245
246
sr.Top = sr.Bottom = lineno;
247
sr.Left = x;
248
sr.Right = x + len - 1;
249
250
WriteConsoleOutput(pdc_con_out, buffer, bufSize, bufPos, &sr);
251
}
252
}
253
254
/* update the given physical line to look like the corresponding line in
255
curscr */
256
257
void PDC_transform_line(int lineno, int x, int len, const chtype *srcp)
258
{
259
attr_t old_attr, attr;
260
int i, j;
261
262
PDC_LOG(("PDC_transform_line() - called: lineno=%d\n", lineno));
263
264
old_attr = *srcp & (A_ATTRIBUTES ^ A_ALTCHARSET);
265
266
for (i = 1, j = 1; j < len; i++, j++)
267
{
268
attr = srcp[i] & (A_ATTRIBUTES ^ A_ALTCHARSET);
269
270
if (attr != old_attr)
271
{
272
_new_packet(old_attr, lineno, x, i, srcp);
273
old_attr = attr;
274
srcp += i;
275
x += i;
276
i = 0;
277
}
278
}
279
280
_new_packet(old_attr, lineno, x, i, srcp);
281
}
282
283
void PDC_blink_text(void)
284
{
285
CONSOLE_CURSOR_INFO cci;
286
int i, j, k;
287
bool oldvis;
288
289
GetConsoleCursorInfo(pdc_con_out, &cci);
290
oldvis = cci.bVisible;
291
if (oldvis)
292
{
293
cci.bVisible = FALSE;
294
SetConsoleCursorInfo(pdc_con_out, &cci);
295
}
296
297
if (!(SP->termattrs & A_BLINK))
298
blinked_off = FALSE;
299
else
300
blinked_off = !blinked_off;
301
302
for (i = 0; i < SP->lines; i++)
303
{
304
const chtype *srcp = curscr->_y[i];
305
306
for (j = 0; j < SP->cols; j++)
307
if (srcp[j] & A_BLINK)
308
{
309
k = j;
310
while (k < SP->cols && (srcp[k] & A_BLINK))
311
k++;
312
PDC_transform_line(i, j, k - j, srcp + j);
313
j = k;
314
}
315
}
316
317
PDC_gotoyx(SP->cursrow, SP->curscol);
318
if (oldvis)
319
{
320
cci.bVisible = TRUE;
321
SetConsoleCursorInfo(pdc_con_out, &cci);
322
}
323
324
pdc_last_blink = GetTickCount();
325
}
326
327
void PDC_doupdate(void)
328
{
329
}
330
331