|
6782c57…
|
stephan
|
1 |
|
|
6782c57…
|
stephan
|
2 |
/* this code is not standalone |
|
6782c57…
|
stephan
|
3 |
* it is included into linenoise.c |
|
6782c57…
|
stephan
|
4 |
* for windows. |
|
6782c57…
|
stephan
|
5 |
* It is deliberately kept separate so that |
|
6782c57…
|
stephan
|
6 |
* applications that have no need for windows |
|
6782c57…
|
stephan
|
7 |
* support can omit this |
|
6782c57…
|
stephan
|
8 |
*/ |
|
6782c57…
|
stephan
|
9 |
static DWORD orig_consolemode = 0; |
|
6782c57…
|
stephan
|
10 |
|
|
6782c57…
|
stephan
|
11 |
static int flushOutput(struct current *current); |
|
6782c57…
|
stephan
|
12 |
static void outputNewline(struct current *current); |
|
6782c57…
|
stephan
|
13 |
|
|
6782c57…
|
stephan
|
14 |
static void refreshStart(struct current *current) |
|
6782c57…
|
stephan
|
15 |
{ |
|
6782c57…
|
stephan
|
16 |
(void)current; |
|
6782c57…
|
stephan
|
17 |
} |
|
6782c57…
|
stephan
|
18 |
|
|
6782c57…
|
stephan
|
19 |
static void refreshEnd(struct current *current) |
|
6782c57…
|
stephan
|
20 |
{ |
|
6782c57…
|
stephan
|
21 |
(void)current; |
|
6782c57…
|
stephan
|
22 |
} |
|
6782c57…
|
stephan
|
23 |
|
|
6782c57…
|
stephan
|
24 |
static void refreshStartChars(struct current *current) |
|
6782c57…
|
stephan
|
25 |
{ |
|
6782c57…
|
stephan
|
26 |
assert(current->output == NULL); |
|
6782c57…
|
stephan
|
27 |
/* We accumulate all output here */ |
|
6782c57…
|
stephan
|
28 |
current->output = sb_alloc(); |
|
6782c57…
|
stephan
|
29 |
#ifdef USE_UTF8 |
|
6782c57…
|
stephan
|
30 |
current->ubuflen = 0; |
|
6782c57…
|
stephan
|
31 |
#endif |
|
6782c57…
|
stephan
|
32 |
} |
|
6782c57…
|
stephan
|
33 |
|
|
6782c57…
|
stephan
|
34 |
static void refreshNewline(struct current *current) |
|
6782c57…
|
stephan
|
35 |
{ |
|
6782c57…
|
stephan
|
36 |
DRL("<nl>"); |
|
6782c57…
|
stephan
|
37 |
outputNewline(current); |
|
6782c57…
|
stephan
|
38 |
} |
|
6782c57…
|
stephan
|
39 |
|
|
6782c57…
|
stephan
|
40 |
static void refreshEndChars(struct current *current) |
|
6782c57…
|
stephan
|
41 |
{ |
|
6782c57…
|
stephan
|
42 |
assert(current->output); |
|
6782c57…
|
stephan
|
43 |
flushOutput(current); |
|
6782c57…
|
stephan
|
44 |
sb_free(current->output); |
|
6782c57…
|
stephan
|
45 |
current->output = NULL; |
|
6782c57…
|
stephan
|
46 |
} |
|
6782c57…
|
stephan
|
47 |
|
|
6782c57…
|
stephan
|
48 |
static int enableRawMode(struct current *current) { |
|
6782c57…
|
stephan
|
49 |
DWORD n; |
|
6782c57…
|
stephan
|
50 |
INPUT_RECORD irec; |
|
6782c57…
|
stephan
|
51 |
|
|
6782c57…
|
stephan
|
52 |
current->outh = GetStdHandle(STD_OUTPUT_HANDLE); |
|
6782c57…
|
stephan
|
53 |
current->inh = GetStdHandle(STD_INPUT_HANDLE); |
|
6782c57…
|
stephan
|
54 |
|
|
6782c57…
|
stephan
|
55 |
if (!PeekConsoleInput(current->inh, &irec, 1, &n)) { |
|
6782c57…
|
stephan
|
56 |
return -1; |
|
6782c57…
|
stephan
|
57 |
} |
|
6782c57…
|
stephan
|
58 |
if (getWindowSize(current) != 0) { |
|
6782c57…
|
stephan
|
59 |
return -1; |
|
6782c57…
|
stephan
|
60 |
} |
|
6782c57…
|
stephan
|
61 |
if (GetConsoleMode(current->inh, &orig_consolemode)) { |
|
6782c57…
|
stephan
|
62 |
SetConsoleMode(current->inh, ENABLE_PROCESSED_INPUT); |
|
6782c57…
|
stephan
|
63 |
} |
|
6782c57…
|
stephan
|
64 |
#ifdef USE_UTF8 |
|
6782c57…
|
stephan
|
65 |
/* XXX is this the right thing to do? */ |
|
6782c57…
|
stephan
|
66 |
SetConsoleCP(65001); |
|
6782c57…
|
stephan
|
67 |
#endif |
|
6782c57…
|
stephan
|
68 |
return 0; |
|
6782c57…
|
stephan
|
69 |
} |
|
6782c57…
|
stephan
|
70 |
|
|
6782c57…
|
stephan
|
71 |
static void disableRawMode(struct current *current) |
|
6782c57…
|
stephan
|
72 |
{ |
|
6782c57…
|
stephan
|
73 |
SetConsoleMode(current->inh, orig_consolemode); |
|
6782c57…
|
stephan
|
74 |
} |
|
6782c57…
|
stephan
|
75 |
|
|
6782c57…
|
stephan
|
76 |
void linenoiseClearScreen(void) |
|
6782c57…
|
stephan
|
77 |
{ |
|
6782c57…
|
stephan
|
78 |
/* XXX: This is ugly. Should just have the caller pass a handle */ |
|
6782c57…
|
stephan
|
79 |
struct current current; |
|
6782c57…
|
stephan
|
80 |
|
|
6782c57…
|
stephan
|
81 |
current.outh = GetStdHandle(STD_OUTPUT_HANDLE); |
|
6782c57…
|
stephan
|
82 |
|
|
6782c57…
|
stephan
|
83 |
if (getWindowSize(¤t) == 0) { |
|
6782c57…
|
stephan
|
84 |
COORD topleft = { 0, 0 }; |
|
6782c57…
|
stephan
|
85 |
DWORD n; |
|
6782c57…
|
stephan
|
86 |
|
|
6782c57…
|
stephan
|
87 |
FillConsoleOutputCharacter(current.outh, ' ', |
|
6782c57…
|
stephan
|
88 |
current.cols * current.rows, topleft, &n); |
|
6782c57…
|
stephan
|
89 |
FillConsoleOutputAttribute(current.outh, |
|
6782c57…
|
stephan
|
90 |
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, |
|
6782c57…
|
stephan
|
91 |
current.cols * current.rows, topleft, &n); |
|
6782c57…
|
stephan
|
92 |
SetConsoleCursorPosition(current.outh, topleft); |
|
6782c57…
|
stephan
|
93 |
} |
|
6782c57…
|
stephan
|
94 |
} |
|
6782c57…
|
stephan
|
95 |
|
|
6782c57…
|
stephan
|
96 |
static void cursorToLeft(struct current *current) |
|
6782c57…
|
stephan
|
97 |
{ |
|
6782c57…
|
stephan
|
98 |
COORD pos; |
|
6782c57…
|
stephan
|
99 |
DWORD n; |
|
6782c57…
|
stephan
|
100 |
|
|
6782c57…
|
stephan
|
101 |
pos.X = 0; |
|
6782c57…
|
stephan
|
102 |
pos.Y = (SHORT)current->y; |
|
6782c57…
|
stephan
|
103 |
|
|
6782c57…
|
stephan
|
104 |
FillConsoleOutputAttribute(current->outh, |
|
6782c57…
|
stephan
|
105 |
FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN, current->cols, pos, &n); |
|
6782c57…
|
stephan
|
106 |
current->x = 0; |
|
6782c57…
|
stephan
|
107 |
} |
|
6782c57…
|
stephan
|
108 |
|
|
6782c57…
|
stephan
|
109 |
#ifdef USE_UTF8 |
|
6782c57…
|
stephan
|
110 |
static void flush_ubuf(struct current *current) |
|
6782c57…
|
stephan
|
111 |
{ |
|
6782c57…
|
stephan
|
112 |
COORD pos; |
|
6782c57…
|
stephan
|
113 |
DWORD nwritten; |
|
6782c57…
|
stephan
|
114 |
pos.Y = (SHORT)current->y; |
|
6782c57…
|
stephan
|
115 |
pos.X = (SHORT)current->x; |
|
6782c57…
|
stephan
|
116 |
SetConsoleCursorPosition(current->outh, pos); |
|
6782c57…
|
stephan
|
117 |
WriteConsoleW(current->outh, current->ubuf, current->ubuflen, &nwritten, 0); |
|
6782c57…
|
stephan
|
118 |
current->x += current->ubufcols; |
|
6782c57…
|
stephan
|
119 |
current->ubuflen = 0; |
|
6782c57…
|
stephan
|
120 |
current->ubufcols = 0; |
|
6782c57…
|
stephan
|
121 |
} |
|
6782c57…
|
stephan
|
122 |
|
|
6782c57…
|
stephan
|
123 |
static void add_ubuf(struct current *current, int ch) |
|
6782c57…
|
stephan
|
124 |
{ |
|
6782c57…
|
stephan
|
125 |
/* This code originally by: Author: Mark E. Davis, 1994. */ |
|
6782c57…
|
stephan
|
126 |
static const int halfShift = 10; /* used for shifting by 10 bits */ |
|
6782c57…
|
stephan
|
127 |
|
|
6782c57…
|
stephan
|
128 |
static const DWORD halfBase = 0x0010000UL; |
|
6782c57…
|
stephan
|
129 |
static const DWORD halfMask = 0x3FFUL; |
|
6782c57…
|
stephan
|
130 |
|
|
6782c57…
|
stephan
|
131 |
#define UNI_SUR_HIGH_START 0xD800 |
|
6782c57…
|
stephan
|
132 |
#define UNI_SUR_HIGH_END 0xDBFF |
|
6782c57…
|
stephan
|
133 |
#define UNI_SUR_LOW_START 0xDC00 |
|
6782c57…
|
stephan
|
134 |
#define UNI_SUR_LOW_END 0xDFFF |
|
6782c57…
|
stephan
|
135 |
|
|
6782c57…
|
stephan
|
136 |
#define UNI_MAX_BMP 0x0000FFFF |
|
6782c57…
|
stephan
|
137 |
|
|
6782c57…
|
stephan
|
138 |
if (ch > UNI_MAX_BMP) { |
|
6782c57…
|
stephan
|
139 |
/* convert from unicode to utf16 surrogate pairs |
|
6782c57…
|
stephan
|
140 |
* There is always space for one extra word in ubuf |
|
6782c57…
|
stephan
|
141 |
*/ |
|
6782c57…
|
stephan
|
142 |
ch -= halfBase; |
|
6782c57…
|
stephan
|
143 |
current->ubuf[current->ubuflen++] = (WORD)((ch >> halfShift) + UNI_SUR_HIGH_START); |
|
6782c57…
|
stephan
|
144 |
current->ubuf[current->ubuflen++] = (WORD)((ch & halfMask) + UNI_SUR_LOW_START); |
|
6782c57…
|
stephan
|
145 |
} |
|
6782c57…
|
stephan
|
146 |
else { |
|
6782c57…
|
stephan
|
147 |
current->ubuf[current->ubuflen++] = ch; |
|
6782c57…
|
stephan
|
148 |
} |
|
6782c57…
|
stephan
|
149 |
current->ubufcols += utf8_width(ch); |
|
6782c57…
|
stephan
|
150 |
if (current->ubuflen >= UBUF_MAX_CHARS) { |
|
6782c57…
|
stephan
|
151 |
flush_ubuf(current); |
|
6782c57…
|
stephan
|
152 |
} |
|
6782c57…
|
stephan
|
153 |
} |
|
6782c57…
|
stephan
|
154 |
#endif |
|
6782c57…
|
stephan
|
155 |
|
|
6782c57…
|
stephan
|
156 |
static int flushOutput(struct current *current) |
|
6782c57…
|
stephan
|
157 |
{ |
|
6782c57…
|
stephan
|
158 |
const char *pt = sb_str(current->output); |
|
6782c57…
|
stephan
|
159 |
int len = sb_len(current->output); |
|
6782c57…
|
stephan
|
160 |
|
|
6782c57…
|
stephan
|
161 |
#ifdef USE_UTF8 |
|
6782c57…
|
stephan
|
162 |
/* convert utf8 in current->output into utf16 in current->ubuf |
|
6782c57…
|
stephan
|
163 |
*/ |
|
6782c57…
|
stephan
|
164 |
while (len) { |
|
6782c57…
|
stephan
|
165 |
int ch; |
|
6782c57…
|
stephan
|
166 |
int n = utf8_tounicode(pt, &ch); |
|
6782c57…
|
stephan
|
167 |
|
|
6782c57…
|
stephan
|
168 |
pt += n; |
|
6782c57…
|
stephan
|
169 |
len -= n; |
|
6782c57…
|
stephan
|
170 |
|
|
6782c57…
|
stephan
|
171 |
add_ubuf(current, ch); |
|
6782c57…
|
stephan
|
172 |
} |
|
6782c57…
|
stephan
|
173 |
flush_ubuf(current); |
|
6782c57…
|
stephan
|
174 |
#else |
|
6782c57…
|
stephan
|
175 |
DWORD nwritten; |
|
6782c57…
|
stephan
|
176 |
COORD pos; |
|
6782c57…
|
stephan
|
177 |
|
|
6782c57…
|
stephan
|
178 |
pos.Y = (SHORT)current->y; |
|
6782c57…
|
stephan
|
179 |
pos.X = (SHORT)current->x; |
|
6782c57…
|
stephan
|
180 |
|
|
6782c57…
|
stephan
|
181 |
SetConsoleCursorPosition(current->outh, pos); |
|
6782c57…
|
stephan
|
182 |
WriteConsoleA(current->outh, pt, len, &nwritten, 0); |
|
6782c57…
|
stephan
|
183 |
|
|
6782c57…
|
stephan
|
184 |
current->x += len; |
|
6782c57…
|
stephan
|
185 |
#endif |
|
6782c57…
|
stephan
|
186 |
|
|
6782c57…
|
stephan
|
187 |
sb_clear(current->output); |
|
6782c57…
|
stephan
|
188 |
|
|
6782c57…
|
stephan
|
189 |
return 0; |
|
6782c57…
|
stephan
|
190 |
} |
|
6782c57…
|
stephan
|
191 |
|
|
6782c57…
|
stephan
|
192 |
static int outputChars(struct current *current, const char *buf, int len) |
|
6782c57…
|
stephan
|
193 |
{ |
|
6782c57…
|
stephan
|
194 |
if (len < 0) { |
|
6782c57…
|
stephan
|
195 |
len = strlen(buf); |
|
6782c57…
|
stephan
|
196 |
} |
|
6782c57…
|
stephan
|
197 |
assert(current->output); |
|
6782c57…
|
stephan
|
198 |
|
|
6782c57…
|
stephan
|
199 |
sb_append_len(current->output, buf, len); |
|
6782c57…
|
stephan
|
200 |
|
|
6782c57…
|
stephan
|
201 |
return 0; |
|
6782c57…
|
stephan
|
202 |
} |
|
6782c57…
|
stephan
|
203 |
|
|
6782c57…
|
stephan
|
204 |
static void outputNewline(struct current *current) |
|
6782c57…
|
stephan
|
205 |
{ |
|
6782c57…
|
stephan
|
206 |
/* On the last row output a newline to force a scroll */ |
|
6782c57…
|
stephan
|
207 |
if (current->y + 1 == current->rows) { |
|
6782c57…
|
stephan
|
208 |
outputChars(current, "\n", 1); |
|
6782c57…
|
stephan
|
209 |
} |
|
6782c57…
|
stephan
|
210 |
flushOutput(current); |
|
6782c57…
|
stephan
|
211 |
current->x = 0; |
|
6782c57…
|
stephan
|
212 |
current->y++; |
|
6782c57…
|
stephan
|
213 |
} |
|
6782c57…
|
stephan
|
214 |
|
|
6782c57…
|
stephan
|
215 |
static void setOutputHighlight(struct current *current, const int *props, int nprops) |
|
6782c57…
|
stephan
|
216 |
{ |
|
6782c57…
|
stephan
|
217 |
int colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; |
|
6782c57…
|
stephan
|
218 |
int bold = 0; |
|
6782c57…
|
stephan
|
219 |
int reverse = 0; |
|
6782c57…
|
stephan
|
220 |
int i; |
|
6782c57…
|
stephan
|
221 |
|
|
6782c57…
|
stephan
|
222 |
for (i = 0; i < nprops; i++) { |
|
6782c57…
|
stephan
|
223 |
switch (props[i]) { |
|
6782c57…
|
stephan
|
224 |
case 0: |
|
6782c57…
|
stephan
|
225 |
colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; |
|
6782c57…
|
stephan
|
226 |
bold = 0; |
|
6782c57…
|
stephan
|
227 |
reverse = 0; |
|
6782c57…
|
stephan
|
228 |
break; |
|
6782c57…
|
stephan
|
229 |
case 1: |
|
6782c57…
|
stephan
|
230 |
bold = FOREGROUND_INTENSITY; |
|
6782c57…
|
stephan
|
231 |
break; |
|
6782c57…
|
stephan
|
232 |
case 7: |
|
6782c57…
|
stephan
|
233 |
reverse = 1; |
|
6782c57…
|
stephan
|
234 |
break; |
|
6782c57…
|
stephan
|
235 |
case 30: |
|
6782c57…
|
stephan
|
236 |
colour = 0; |
|
6782c57…
|
stephan
|
237 |
break; |
|
6782c57…
|
stephan
|
238 |
case 31: |
|
6782c57…
|
stephan
|
239 |
colour = FOREGROUND_RED; |
|
6782c57…
|
stephan
|
240 |
break; |
|
6782c57…
|
stephan
|
241 |
case 32: |
|
6782c57…
|
stephan
|
242 |
colour = FOREGROUND_GREEN; |
|
6782c57…
|
stephan
|
243 |
break; |
|
6782c57…
|
stephan
|
244 |
case 33: |
|
6782c57…
|
stephan
|
245 |
colour = FOREGROUND_RED | FOREGROUND_GREEN; |
|
6782c57…
|
stephan
|
246 |
break; |
|
6782c57…
|
stephan
|
247 |
case 34: |
|
6782c57…
|
stephan
|
248 |
colour = FOREGROUND_BLUE; |
|
6782c57…
|
stephan
|
249 |
break; |
|
6782c57…
|
stephan
|
250 |
case 35: |
|
6782c57…
|
stephan
|
251 |
colour = FOREGROUND_RED | FOREGROUND_BLUE; |
|
6782c57…
|
stephan
|
252 |
break; |
|
6782c57…
|
stephan
|
253 |
case 36: |
|
6782c57…
|
stephan
|
254 |
colour = FOREGROUND_BLUE | FOREGROUND_GREEN; |
|
6782c57…
|
stephan
|
255 |
break; |
|
6782c57…
|
stephan
|
256 |
case 37: |
|
6782c57…
|
stephan
|
257 |
colour = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN; |
|
6782c57…
|
stephan
|
258 |
break; |
|
6782c57…
|
stephan
|
259 |
} |
|
6782c57…
|
stephan
|
260 |
} |
|
6782c57…
|
stephan
|
261 |
|
|
6782c57…
|
stephan
|
262 |
flushOutput(current); |
|
6782c57…
|
stephan
|
263 |
|
|
6782c57…
|
stephan
|
264 |
if (reverse) { |
|
6782c57…
|
stephan
|
265 |
SetConsoleTextAttribute(current->outh, BACKGROUND_INTENSITY); |
|
6782c57…
|
stephan
|
266 |
} |
|
6782c57…
|
stephan
|
267 |
else { |
|
6782c57…
|
stephan
|
268 |
SetConsoleTextAttribute(current->outh, colour | bold); |
|
6782c57…
|
stephan
|
269 |
} |
|
6782c57…
|
stephan
|
270 |
} |
|
6782c57…
|
stephan
|
271 |
|
|
6782c57…
|
stephan
|
272 |
static void eraseEol(struct current *current) |
|
6782c57…
|
stephan
|
273 |
{ |
|
6782c57…
|
stephan
|
274 |
COORD pos; |
|
6782c57…
|
stephan
|
275 |
DWORD n; |
|
6782c57…
|
stephan
|
276 |
|
|
6782c57…
|
stephan
|
277 |
pos.X = (SHORT) current->x; |
|
6782c57…
|
stephan
|
278 |
pos.Y = (SHORT) current->y; |
|
6782c57…
|
stephan
|
279 |
|
|
6782c57…
|
stephan
|
280 |
FillConsoleOutputCharacter(current->outh, ' ', current->cols - current->x, pos, &n); |
|
6782c57…
|
stephan
|
281 |
} |
|
6782c57…
|
stephan
|
282 |
|
|
6782c57…
|
stephan
|
283 |
static void setCursorXY(struct current *current) |
|
6782c57…
|
stephan
|
284 |
{ |
|
6782c57…
|
stephan
|
285 |
COORD pos; |
|
6782c57…
|
stephan
|
286 |
|
|
6782c57…
|
stephan
|
287 |
pos.X = (SHORT) current->x; |
|
6782c57…
|
stephan
|
288 |
pos.Y = (SHORT) current->y; |
|
6782c57…
|
stephan
|
289 |
|
|
6782c57…
|
stephan
|
290 |
SetConsoleCursorPosition(current->outh, pos); |
|
6782c57…
|
stephan
|
291 |
} |
|
6782c57…
|
stephan
|
292 |
|
|
6782c57…
|
stephan
|
293 |
|
|
6782c57…
|
stephan
|
294 |
static void setCursorPos(struct current *current, int x) |
|
6782c57…
|
stephan
|
295 |
{ |
|
6782c57…
|
stephan
|
296 |
current->x = x; |
|
6782c57…
|
stephan
|
297 |
setCursorXY(current); |
|
6782c57…
|
stephan
|
298 |
} |
|
6782c57…
|
stephan
|
299 |
|
|
6782c57…
|
stephan
|
300 |
static void cursorUp(struct current *current, int n) |
|
6782c57…
|
stephan
|
301 |
{ |
|
6782c57…
|
stephan
|
302 |
current->y -= n; |
|
6782c57…
|
stephan
|
303 |
setCursorXY(current); |
|
6782c57…
|
stephan
|
304 |
} |
|
6782c57…
|
stephan
|
305 |
|
|
6782c57…
|
stephan
|
306 |
static void cursorDown(struct current *current, int n) |
|
6782c57…
|
stephan
|
307 |
{ |
|
6782c57…
|
stephan
|
308 |
current->y += n; |
|
6782c57…
|
stephan
|
309 |
setCursorXY(current); |
|
6782c57…
|
stephan
|
310 |
} |
|
6782c57…
|
stephan
|
311 |
|
|
6782c57…
|
stephan
|
312 |
static int fd_read(struct current *current) |
|
6782c57…
|
stephan
|
313 |
{ |
|
6782c57…
|
stephan
|
314 |
while (1) { |
|
6782c57…
|
stephan
|
315 |
INPUT_RECORD irec; |
|
6782c57…
|
stephan
|
316 |
DWORD n; |
|
6782c57…
|
stephan
|
317 |
if (WaitForSingleObject(current->inh, INFINITE) != WAIT_OBJECT_0) { |
|
6782c57…
|
stephan
|
318 |
break; |
|
6782c57…
|
stephan
|
319 |
} |
|
6782c57…
|
stephan
|
320 |
if (!ReadConsoleInputW(current->inh, &irec, 1, &n)) { |
|
6782c57…
|
stephan
|
321 |
break; |
|
6782c57…
|
stephan
|
322 |
} |
|
6782c57…
|
stephan
|
323 |
if (irec.EventType == KEY_EVENT) { |
|
6782c57…
|
stephan
|
324 |
KEY_EVENT_RECORD *k = &irec.Event.KeyEvent; |
|
6782c57…
|
stephan
|
325 |
if (k->bKeyDown || k->wVirtualKeyCode == VK_MENU) { |
|
6782c57…
|
stephan
|
326 |
if (k->dwControlKeyState & ENHANCED_KEY) { |
|
6782c57…
|
stephan
|
327 |
switch (k->wVirtualKeyCode) { |
|
6782c57…
|
stephan
|
328 |
case VK_LEFT: |
|
6782c57…
|
stephan
|
329 |
return SPECIAL_LEFT; |
|
6782c57…
|
stephan
|
330 |
case VK_RIGHT: |
|
6782c57…
|
stephan
|
331 |
return SPECIAL_RIGHT; |
|
6782c57…
|
stephan
|
332 |
case VK_UP: |
|
6782c57…
|
stephan
|
333 |
return SPECIAL_UP; |
|
6782c57…
|
stephan
|
334 |
case VK_DOWN: |
|
6782c57…
|
stephan
|
335 |
return SPECIAL_DOWN; |
|
6782c57…
|
stephan
|
336 |
case VK_INSERT: |
|
6782c57…
|
stephan
|
337 |
return SPECIAL_INSERT; |
|
6782c57…
|
stephan
|
338 |
case VK_DELETE: |
|
6782c57…
|
stephan
|
339 |
return SPECIAL_DELETE; |
|
6782c57…
|
stephan
|
340 |
case VK_HOME: |
|
6782c57…
|
stephan
|
341 |
return SPECIAL_HOME; |
|
6782c57…
|
stephan
|
342 |
case VK_END: |
|
6782c57…
|
stephan
|
343 |
return SPECIAL_END; |
|
6782c57…
|
stephan
|
344 |
case VK_PRIOR: |
|
6782c57…
|
stephan
|
345 |
return SPECIAL_PAGE_UP; |
|
6782c57…
|
stephan
|
346 |
case VK_NEXT: |
|
6782c57…
|
stephan
|
347 |
return SPECIAL_PAGE_DOWN; |
|
6782c57…
|
stephan
|
348 |
case VK_RETURN: |
|
6782c57…
|
stephan
|
349 |
return k->uChar.UnicodeChar; |
|
6782c57…
|
stephan
|
350 |
} |
|
6782c57…
|
stephan
|
351 |
} |
|
6782c57…
|
stephan
|
352 |
/* Note that control characters are already translated in AsciiChar */ |
|
6782c57…
|
stephan
|
353 |
else if (k->wVirtualKeyCode == VK_CONTROL) |
|
6782c57…
|
stephan
|
354 |
continue; |
|
6782c57…
|
stephan
|
355 |
else { |
|
6782c57…
|
stephan
|
356 |
return k->uChar.UnicodeChar; |
|
6782c57…
|
stephan
|
357 |
} |
|
6782c57…
|
stephan
|
358 |
} |
|
6782c57…
|
stephan
|
359 |
} |
|
6782c57…
|
stephan
|
360 |
} |
|
6782c57…
|
stephan
|
361 |
return -1; |
|
6782c57…
|
stephan
|
362 |
} |
|
6782c57…
|
stephan
|
363 |
|
|
6782c57…
|
stephan
|
364 |
static int getWindowSize(struct current *current) |
|
6782c57…
|
stephan
|
365 |
{ |
|
6782c57…
|
stephan
|
366 |
CONSOLE_SCREEN_BUFFER_INFO info; |
|
6782c57…
|
stephan
|
367 |
if (!GetConsoleScreenBufferInfo(current->outh, &info)) { |
|
6782c57…
|
stephan
|
368 |
return -1; |
|
6782c57…
|
stephan
|
369 |
} |
|
6782c57…
|
stephan
|
370 |
current->cols = info.dwSize.X; |
|
6782c57…
|
stephan
|
371 |
current->rows = info.dwSize.Y; |
|
6782c57…
|
stephan
|
372 |
if (current->cols <= 0 || current->rows <= 0) { |
|
6782c57…
|
stephan
|
373 |
current->cols = 80; |
|
6782c57…
|
stephan
|
374 |
return -1; |
|
6782c57…
|
stephan
|
375 |
} |
|
6782c57…
|
stephan
|
376 |
current->y = info.dwCursorPosition.Y; |
|
6782c57…
|
stephan
|
377 |
current->x = info.dwCursorPosition.X; |
|
6782c57…
|
stephan
|
378 |
return 0; |
|
6782c57…
|
stephan
|
379 |
} |