ReactOS  0.4.14-dev-49-gfb4591c
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 166 of file lineinput.c.

169 {
170  UINT Pos = Console->LinePos;
172 
173  /*
174  * First, deal with control keys...
175  */
176 
177  switch (KeyEvent->wVirtualKeyCode)
178  {
179  case VK_ESCAPE:
180  {
181  /* Clear the entire line */
183  LineInputEdit(Console, Console->LineSize, 0, NULL);
184 
185  // TESTS!!
186  if (Popup)
187  {
189  Popup = NULL;
190  }
191  return;
192  }
193 
194  case VK_HOME:
195  {
196  /* Move to start of line. With CTRL, erase everything left of cursor. */
200  return;
201  }
202 
203  case VK_END:
204  {
205  /* Move to end of line. With CTRL, erase everything right of cursor. */
207  LineInputEdit(Console, Console->LineSize - Pos, 0, NULL);
208  else
209  LineInputSetPos(Console, Console->LineSize);
210  return;
211  }
212 
213  case VK_LEFT:
214  {
215  /* Move to the left. With CTRL, move to beginning of previous word. */
217  {
218  while (Pos > 0 && Console->LineBuffer[Pos - 1] == L' ') Pos--;
219  while (Pos > 0 && Console->LineBuffer[Pos - 1] != L' ') Pos--;
220  }
221  else
222  {
223  Pos -= (Pos > 0);
224  }
226  return;
227  }
228 
229  case VK_RIGHT:
230  case VK_F1:
231  {
232  /* Move to the right. With CTRL, move to beginning of next word. */
234  {
235  while (Pos < Console->LineSize && Console->LineBuffer[Pos] != L' ') Pos++;
236  while (Pos < Console->LineSize && Console->LineBuffer[Pos] == L' ') Pos++;
238  }
239  else
240  {
241  /* Recall one character (but don't overwrite current line) */
243  if (Pos < Console->LineSize)
245  else if (Pos * sizeof(WCHAR) < Entry.Length)
246  LineInputEdit(Console, 0, 1, &Entry.Buffer[Pos]);
247  }
248  return;
249  }
250 
251  case VK_INSERT:
252  {
253  /* Toggle between insert and overstrike */
254  Console->LineInsertToggle = !Console->LineInsertToggle;
255  TermSetCursorInfo(Console, Console->ActiveBuffer);
256  return;
257  }
258 
259  case VK_DELETE:
260  {
261  /* Remove one character to right of cursor */
262  if (Pos != Console->LineSize)
263  LineInputEdit(Console, 1, 0, NULL);
264  return;
265  }
266 
267  case VK_PRIOR:
268  {
269  /* Recall the first history entry */
270  LineInputRecallHistory(Console, ExeName, -((WORD)-1));
271  return;
272  }
273 
274  case VK_NEXT:
275  {
276  /* Recall the last history entry */
277  LineInputRecallHistory(Console, ExeName, +((WORD)-1));
278  return;
279  }
280 
281  case VK_UP:
282  case VK_F5:
283  {
284  /*
285  * Recall the previous history entry. On first time, actually recall
286  * the current (usually last) entry; on subsequent times go back.
287  */
288  LineInputRecallHistory(Console, ExeName, Console->LineUpPressed ? -1 : 0);
289  Console->LineUpPressed = TRUE;
290  return;
291  }
292 
293  case VK_DOWN:
294  {
295  /* Recall the next history entry */
296  LineInputRecallHistory(Console, ExeName, +1);
297  return;
298  }
299 
300  case VK_F3:
301  {
302  /* Recall the remainder of the current history entry */
304  if (Pos * sizeof(WCHAR) < Entry.Length)
305  {
306  UINT InsertSize = (Entry.Length / sizeof(WCHAR) - Pos);
307  UINT DeleteSize = min(Console->LineSize - Pos, InsertSize);
308  LineInputEdit(Console, DeleteSize, InsertSize, &Entry.Buffer[Pos]);
309  }
310  return;
311  }
312 
313  case VK_F6:
314  {
315  /* Insert a ^Z character */
316  KeyEvent->uChar.UnicodeChar = 26;
317  break;
318  }
319 
320  case VK_F7:
321  {
324  else
325  {
328  }
329  return;
330  }
331 
332  case VK_F8:
333  {
334  UNICODE_STRING EntryFound;
335 
336  Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
337  Entry.Buffer = Console->LineBuffer;
338 
339  if (HistoryFindEntryByPrefix(Console, ExeName, &Entry, &EntryFound))
340  {
341  LineInputEdit(Console, Console->LineSize - Pos,
342  EntryFound.Length / sizeof(WCHAR) - Pos,
343  &EntryFound.Buffer[Pos]);
344  /* Cursor stays where it was */
346  }
347 
348  return;
349  }
350 #if 0
351  {
352  PHISTORY_BUFFER Hist;
353  INT HistPos;
354 
355  /* Search for history entries starting with input */
356  Hist = HistoryCurrentBuffer(Console, ExeName);
357  if (!Hist || Hist->NumEntries == 0) return;
358 
359  /*
360  * Like Up/F5, on first time start from current (usually last) entry,
361  * but on subsequent times start at previous entry.
362  */
363  if (Console->LineUpPressed)
364  Hist->Position = (Hist->Position ? Hist->Position : Hist->NumEntries) - 1;
365  Console->LineUpPressed = TRUE;
366 
367  Entry.Length = Console->LinePos * sizeof(WCHAR); // == Pos * sizeof(WCHAR)
368  Entry.Buffer = Console->LineBuffer;
369 
370  /*
371  * Keep going backwards, even wrapping around to the end,
372  * until we get back to starting point.
373  */
374  HistPos = Hist->Position;
375  do
376  {
377  if (RtlPrefixUnicodeString(&Entry, &Hist->Entries[HistPos], FALSE))
378  {
379  Hist->Position = HistPos;
380  LineInputEdit(Console, Console->LineSize - Pos,
381  Hist->Entries[HistPos].Length / sizeof(WCHAR) - Pos,
382  &Hist->Entries[HistPos].Buffer[Pos]);
383  /* Cursor stays where it was */
385  return;
386  }
387  if (--HistPos < 0) HistPos += Hist->NumEntries;
388  } while (HistPos != Hist->Position);
389 
390  return;
391  }
392 #endif
393 
394  return;
395  }
396 
397 
398  /*
399  * OK, we deal with normal keys, we can continue...
400  */
401 
403  {
404  /*
405  * Backspace handling - if processed input enabled then we handle it
406  * here, otherwise we treat it like a normal character.
407  */
408  if (Pos > 0)
409  {
411  LineInputEdit(Console, 1, 0, NULL);
412  }
413  }
414  else if (KeyEvent->uChar.UnicodeChar == L'\r')
415  {
416  /*
417  * Only add a history entry if console echo is enabled. This ensures
418  * that anything sent to the console when echo is disabled (e.g.
419  * binary data, or secrets like passwords...) does not remain stored
420  * in memory.
421  */
423  {
424  Entry.Length = Entry.MaximumLength = Console->LineSize * sizeof(WCHAR);
425  Entry.Buffer = Console->LineBuffer;
426  HistoryAddEntry(Console, ExeName, &Entry);
427  }
428 
429  /* TODO: Expand aliases */
430  DPRINT1("TODO: Expand aliases\n");
431 
432  LineInputSetPos(Console, Console->LineSize);
433  Console->LineBuffer[Console->LineSize++] = L'\r';
435  {
436  if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
437  {
438  TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\r", 1, TRUE);
439  }
440  }
441 
442  /*
443  * Add \n if processed input. There should usually be room for it,
444  * but an exception to the rule exists: the buffer could have been
445  * pre-filled with LineMaxSize - 1 characters.
446  */
448  Console->LineSize < Console->LineMaxSize)
449  {
450  Console->LineBuffer[Console->LineSize++] = L'\n';
452  {
453  if (GetType(Console->ActiveBuffer) == TEXTMODE_BUFFER)
454  {
455  TermWriteStream(Console, (PTEXTMODE_SCREEN_BUFFER)(Console->ActiveBuffer), L"\n", 1, TRUE);
456  }
457  }
458  }
459  Console->LineComplete = TRUE;
460  Console->LinePos = 0;
461  }
462  else if (KeyEvent->uChar.UnicodeChar != L'\0')
463  {
464  if (KeyEvent->uChar.UnicodeChar < 0x20 &&
465  Console->LineWakeupMask & (1 << KeyEvent->uChar.UnicodeChar))
466  {
467  /* Control key client wants to handle itself (e.g. for tab completion) */
468  Console->LineBuffer[Console->LineSize++] = L' ';
469  Console->LineBuffer[Console->LinePos] = KeyEvent->uChar.UnicodeChar;
470  Console->LineComplete = TRUE;
471  Console->LinePos = 0;
472  }
473  else
474  {
475  /* Normal character */
476  BOOL Overstrike = !Console->LineInsertToggle && (Console->LinePos != Console->LineSize);
477  DPRINT("Overstrike = %s\n", Overstrike ? "true" : "false");
478  LineInputEdit(Console, (Overstrike ? 1 : 0), 1, &KeyEvent->uChar.UnicodeChar);
479  }
480  }
481 }
#define TRUE
Definition: types.h:120
WCHAR UnicodeChar
Definition: wincon.h:230
static PHISTORY_BUFFER HistoryCurrentBuffer(PCONSOLE Console)
Definition: lineinput.c:33
#define VK_F5
Definition: winuser.h:2234
#define VK_F6
Definition: winuser.h:2235
struct _Entry Entry
Definition: kefuncs.h:640
ULONG NumEntries
Definition: history.c:22
ush Pos
Definition: deflate.h:92
DWORD dwControlKeyState
Definition: wincon.h:233
#define VK_LEFT
Definition: winuser.h:2199
#define VK_DOWN
Definition: winuser.h:2202
#define VK_INSERT
Definition: winuser.h:2207
#define VK_PRIOR
Definition: winuser.h:2195
#define TEXTMODE_BUFFER
Definition: pccons.c:21
#define VK_ESCAPE
Definition: winuser.h:2189
int32_t INT
Definition: typedefs.h:56
#define VK_NEXT
Definition: winuser.h:2196
VOID HistoryDeleteCurrentBuffer(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName)
Definition: history.c:306
WORD wVirtualKeyCode
Definition: wincon.h:227
#define ENABLE_ECHO_INPUT
Definition: wincon.h:77
#define VK_HOME
Definition: winuser.h:2198
#define VK_UP
Definition: winuser.h:2200
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
#define GetConsoleInputBufferMode(Console)
Definition: conio.h:362
void DPRINT(...)
Definition: polytest.cpp:61
#define VK_DELETE
Definition: winuser.h:2208
#define LEFT_ALT_PRESSED
Definition: wincon.h:132
VOID HistoryGetCurrentEntry(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Entry)
Definition: history.c:197
PPOPUP_WINDOW Popup
Definition: lineinput.c:159
union _KEY_EVENT_RECORD::@3153 uChar
PUNICODE_STRING Entries
Definition: history.c:24
PPOPUP_WINDOW HistoryDisplayCurrentHistory(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName)
Definition: history.c:271
#define VK_F7
Definition: winuser.h:2236
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned short WORD
Definition: ntddk_ex.h:93
ULONG Position
Definition: history.c:20
#define VK_F3
Definition: winuser.h:2232
#define VK_F8
Definition: winuser.h:2237
#define LEFT_CTRL_PRESSED
Definition: wincon.h:134
INT GetType(BOOL bLocal, LPOSVERSIONINFOEX osvi, LPSERVER_INFO_102 pBuf102)
Definition: gettype.c:129
static const WCHAR L[]
Definition: oid.c:1250
VOID HistoryAddEntry(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Entry)
Definition: history.c:141
#define VK_RIGHT
Definition: winuser.h:2201
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:75
#define TermSetCursorInfo(Console, ScreenBuffer)
Definition: term.h:24
#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)
static VOID LineInputSetPos(PCONSRV_CONSOLE Console, UINT Pos)
Definition: lineinput.c:60
#define VK_F1
Definition: winuser.h:2230
CConsole Console
#define DPRINT1
Definition: precomp.h:8
BOOL HistoryFindEntryByPrefix(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Prefix, PUNICODE_STRING Entry)
Definition: history.c:229
#define TermWriteStream(Console, ScreenBuffer, Buffer, Length, Attrib)
Definition: term.h:17
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:133
static VOID LineInputEdit(PCONSRV_CONSOLE Console, UINT NumToDelete, UINT NumToInsert, PWCHAR Insertion)
Definition: lineinput.c:85
static VOID LineInputRecallHistory(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, INT Offset)
Definition: lineinput.c:125
#define VK_END
Definition: winuser.h:2197
base of all file and directory entries
Definition: entries.h:82
#define RIGHT_ALT_PRESSED
Definition: wincon.h:131

Referenced by ConDrvReadConsole(), and ConSrvTermReadStream().