ReactOS  0.4.14-dev-1034-g1e60116
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 169 of file lineinput.c.

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

Referenced by ConDrvReadConsole(), and ConSrvTermReadStream().