ReactOS 0.4.16-dev-329-g9223134
lineinput.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

VOID LineInputKeyDown (PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, KEY_EVENT_RECORD *KeyEvent)
 

Function Documentation

◆ LineInputKeyDown()

VOID LineInputKeyDown ( PCONSRV_CONSOLE  Console,
PUNICODE_STRING  ExeName,
KEY_EVENT_RECORD KeyEvent 
)

Definition at line 147 of file lineinput.c.

150{
151 UINT Pos = Console->LinePos;
153
154 /*
155 * First, deal with control keys...
156 */
157
158 switch (KeyEvent->wVirtualKeyCode)
159 {
160 case VK_ESCAPE:
161 {
162 /* Clear the entire line */
164 LineInputEdit(Console, Console->LineSize, 0, NULL);
165
166 // TESTS!!
167 if (Popup)
168 {
170 Popup = NULL;
171 }
172 return;
173 }
174
175 case VK_HOME:
176 {
177 /* Move to start of line. With CTRL, erase everything left of cursor. */
181 return;
182 }
183
184 case VK_END:
185 {
186 /* Move to end of line. With CTRL, erase everything right of cursor. */
188 LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
189 else
190 LineInputSetPos(Console, Console->LineSize);
191 return;
192 }
193
194 case VK_LEFT:
195 {
196 /* Move to the left. With CTRL, move to beginning of previous word. */
198 {
199 while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
200 while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
201 }
202 else
203 {
204 Pos -= (Pos > 0);
205 }
207 return;
208 }
209
210 case VK_RIGHT:
211 case VK_F1:
212 {
213 /* Move to the right. With CTRL, move to beginning of next word. */
215 {
216 while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
217 while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
219 }
220 else
221 {
222 /* Recall one character (but don't overwrite current line) */
224 if (Pos < Console->LineSize)
226 else if (Pos * sizeof(WCHAR) < Entry.Length)
227 LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
228 }
229 return;
230 }
231
232 case VK_INSERT:
233 {
234 /* Toggle between insert and overstrike */
235 Console->LineInsertToggle = !Console->LineInsertToggle;
236 TermSetCursorInfo(Console, Console->ActiveBuffer);
237 return;
238 }
239
240 case VK_DELETE:
241 {
242 /* Remove one character to right of cursor */
243 if (Pos != Console->LineSize)
244 LineInputEdit(Console, 1, 0, NULL);
245 return;
246 }
247
248 case VK_PRIOR:
249 {
250 /* Recall the first history entry */
251 LineInputRecallHistory(Console, ExeName, -((WORD)-1));
252 return;
253 }
254
255 case VK_NEXT:
256 {
257 /* Recall the last history entry */
258 LineInputRecallHistory(Console, ExeName, +((WORD)-1));
259 return;
260 }
261
262 case VK_UP:
263 case VK_F5:
264 {
265 /*
266 * Recall the previous history entry. On first time, actually recall
267 * the current (usually last) entry; on subsequent times go back.
268 */
269 LineInputRecallHistory(Console, ExeName, Console->LineUpPressed ? -1 : 0);
270 Console->LineUpPressed = TRUE;
271 return;
272 }
273
274 case VK_DOWN:
275 {
276 /* Recall the next history entry */
277 LineInputRecallHistory(Console, ExeName, +1);
278 return;
279 }
280
281 case VK_F3:
282 {
283 /* Recall the remainder of the current history entry */
285 if (Pos * sizeof(WCHAR) < Entry.Length)
286 {
287 UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
288 UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
289 LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
290 }
291 return;
292 }
293
294 case VK_F6:
295 {
296 /* Insert a ^Z character */
297 KeyEvent->uChar.UnicodeChar = 26;
298 break;
299 }
300
301 case VK_F7:
302 {
304 {
306 }
307 else
308 {
311 }
312 return;
313 }
314
315 case VK_F8:
316 {
317 UNICODE_STRING EntryFound;
318
319 Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
320 Entry.Buffer = Console->LineBuffer;
321
322 if (HistoryFindEntryByPrefix(Console, ExeName, &Entry, &EntryFound))
323 {
324 LineInputEdit(Console, Console->LineSize - Pos,
325 EntryFound.Length / sizeof(WCHAR) - Pos,
326 &EntryFound.Buffer[Pos]);
327 /* Cursor stays where it was */
329 }
330
331 return;
332 }
333#if 0
334 {
335 PHISTORY_BUFFER Hist;
336 INT HistPos;
337
338 /* Search for history entries starting with input */
339 Hist = HistoryCurrentBuffer(Console, ExeName);
340 if (!Hist || Hist->NumEntries == 0) return;
341
342 /*
343 * Like Up/F5, on first time start from current (usually last) entry,
344 * but on subsequent times start at previous entry.
345 */
346 if (Console->LineUpPressed)
347 Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
348 Console->LineUpPressed = TRUE;
349
350 Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
351 Entry.Buffer = Console->LineBuffer;
352
353 /*
354 * Keep going backwards, even wrapping around to the end,
355 * until we get back to starting point.
356 */
357 HistPos = Hist->Position;
358 do
359 {
360 if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
361 {
362 Hist->Position = HistPos;
363 LineInputEdit(Console, Console->LineSize - Pos,
364 Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
365 &Hist->Entries[HistPos].Buffer[Pos]);
366 /* Cursor stays where it was */
368 return;
369 }
370 if (--HistPos < 0) HistPos += Hist->NumEntries;
371 } while (HistPos != Hist->Position);
372
373 return;
374 }
375#endif
376
377 return;
378 }
379
380
381 /*
382 * OK, we deal with normal keys, we can continue...
383 */
384
386 {
387 /*
388 * Backspace handling - if processed input enabled then we handle it
389 * here, otherwise we treat it like a normal character.
390 */
391 if (Pos > 0)
392 {
394 LineInputEdit(Console, 1, 0, NULL);
395 }
396 }
397 else if (KeyEvent->uChar.UnicodeChar == L'\r')
398 {
399 /*
400 * Only add a history entry if console echo is enabled. This ensures
401 * that anything sent to the console when echo is disabled (e.g.
402 * binary data, or secrets like passwords...) does not remain stored
403 * in memory.
404 */
406 {
407 Entry.Length = Entry.MaximumLength = Console->LineSize * sizeof(WCHAR);
408 Entry.Buffer = Console->LineBuffer;
409 HistoryAddEntry(Console, ExeName, &Entry);
410 }
411
412 /* TODO: Expand aliases */
413 DPRINT1("TODO: Expand aliases\n");
414
415 LineInputSetPos(Console, Console->LineSize);
416 Console->LineBuffer[Console->LineSize++] = L'\r';
417 if ((GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER) &&
419 {
420 TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
421 }
422
423 /*
424 * Add \n if processed input. There should usually be room for it,
425 * but an exception to the rule exists: the buffer could have been
426 * pre-filled with LineMaxSize - 1 characters.
427 */
429 Console->LineSize < Console->LineMaxSize)
430 {
431 Console->LineBuffer[Console->LineSize++] = L'\n';
432 if ((GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER) &&
434 {
435 TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
436 }
437 }
438 Console->LineComplete = TRUE;
439 Console->LinePos = 0;
440 }
441 else if (KeyEvent->uChar.UnicodeChar != L'\0')
442 {
443 if (KeyEvent->uChar.UnicodeChar < 0x20 &&
444 Console->LineWakeupMask & (1 << KeyEvent->uChar.UnicodeChar))
445 {
446 /* Control key client wants to handle itself (e.g. for tab completion) */
447 Console->LineBuffer[Console->LineSize++] = L' ';
448 Console->LineBuffer[Console->LinePos] = KeyEvent->uChar.UnicodeChar;
449 Console->LineComplete = TRUE;
450 Console->LinePos = 0;
451 }
452 else
453 {
454 /* Normal character */
455 BOOL Overstrike = !Console->LineInsertToggle && (Console->LinePos != Console->LineSize);
456 DPRINT("Overstrike = %s\n", Overstrike ? "true" : "false");
457 LineInputEdit(Console, (Overstrike ? 1 : 0), 1, &KeyEvent->uChar.UnicodeChar);
458 }
459 }
460}
CConsole Console
#define DPRINT1
Definition: precomp.h:8
ush Pos
Definition: deflate.h:92
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned short WORD
Definition: ntddk_ex.h:93
PPOPUP_WINDOW Popup
Definition: lineinput.c:140
static VOID LineInputRecallHistory(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, INT Offset)
Definition: lineinput.c:106
static VOID LineInputSetPos(PCONSRV_CONSOLE Console, UINT Pos)
Definition: lineinput.c:38
PPOPUP_WINDOW HistoryDisplayCurrentHistory(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName)
Definition: history.c:315
static VOID LineInputEdit(PCONSRV_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, PWCHAR Insertion)
Definition: lineinput.c:63
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define L(x)
Definition: ntvdm.h:50
#define TEXTMODE_BUFFER
Definition: pccons.c:21
VOID DestroyPopupWindow(IN PPOPUP_WINDOW Popup)
Definition: popup.c:244
#define DPRINT
Definition: sndvol32.h:73
base of all file and directory entries
Definition: entries.h:83
PUNICODE_STRING Entries
Definition: history.c:24
ULONG NumEntries
Definition: history.c:22
ULONG Position
Definition: history.c:20
DWORD dwControlKeyState
Definition: wincon.h:248
WORD wVirtualKeyCode
Definition: wincon.h:242
union _KEY_EVENT_RECORD::@3286 uChar
WCHAR UnicodeChar
Definition: wincon.h:245
#define TermWriteStream(Console, ScreenBuffer, Buffer, Length, Attrib)
Definition: term.h:17
#define TermSetCursorInfo(Console, ScreenBuffer)
Definition: term.h:24
int32_t INT
Definition: typedefs.h:58
VOID HistoryGetCurrentEntry(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Entry)
Definition: history.c:241
static PHISTORY_BUFFER HistoryCurrentBuffer(IN PCONSRV_CONSOLE Console, IN PUNICODE_STRING ExeName)
Definition: history.c:47
VOID HistoryDeleteCurrentBuffer(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName)
Definition: history.c:350
BOOL HistoryFindEntryByPrefix(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Prefix, PUNICODE_STRING Entry)
Definition: history.c:273
VOID HistoryAddEntry(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Entry)
Definition: history.c:185
#define GetConsoleInputBufferMode(Console)
Definition: conio.h:320
#define GetType(This)
Definition: conio.h:54
#define LEFT_CTRL_PRESSED
Definition: wincon.h:140
#define ENABLE_ECHO_INPUT
Definition: wincon.h:80
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:139
#define RIGHT_ALT_PRESSED
Definition: wincon.h:137
#define LEFT_ALT_PRESSED
Definition: wincon.h:138
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:78
#define VK_UP
Definition: winuser.h:2228
#define VK_F1
Definition: winuser.h:2258
#define VK_F6
Definition: winuser.h:2263
#define VK_NEXT
Definition: winuser.h:2224
#define VK_F5
Definition: winuser.h:2262
#define VK_F8
Definition: winuser.h:2265
#define VK_END
Definition: winuser.h:2225
#define VK_HOME
Definition: winuser.h:2226
#define VK_F3
Definition: winuser.h:2260
#define VK_LEFT
Definition: winuser.h:2227
#define VK_RIGHT
Definition: winuser.h:2229
#define VK_DOWN
Definition: winuser.h:2230
#define VK_PRIOR
Definition: winuser.h:2223
#define VK_DELETE
Definition: winuser.h:2236
#define VK_ESCAPE
Definition: winuser.h:2217
#define VK_F7
Definition: winuser.h:2264
#define VK_INSERT
Definition: winuser.h:2235
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ConSrvTermReadStream().