ReactOS  0.4.15-dev-1171-gab82533
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 }
WCHAR UnicodeChar
Definition: wincon.h:245
#define VK_F5
Definition: winuser.h:2234
#define VK_F6
Definition: winuser.h:2235
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
ULONG NumEntries
Definition: history.c:22
ush Pos
Definition: deflate.h:92
DWORD dwControlKeyState
Definition: wincon.h:248
static PHISTORY_BUFFER HistoryCurrentBuffer(IN PCONSRV_CONSOLE Console, IN PUNICODE_STRING ExeName)
Definition: history.c:47
#define VK_LEFT
Definition: winuser.h:2199
VOID HistoryGetCurrentEntry(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Entry)
Definition: history.c:241
#define VK_DOWN
Definition: winuser.h:2202
#define VK_INSERT
Definition: winuser.h:2207
#define VK_PRIOR
Definition: winuser.h:2195
#define VK_ESCAPE
Definition: winuser.h:2189
int32_t INT
Definition: typedefs.h:58
#define VK_NEXT
Definition: winuser.h:2196
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
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
#define GetConsoleInputBufferMode(Console)
Definition: conio.h:318
void DPRINT(...)
Definition: polytest.cpp:61
#define VK_DELETE
Definition: winuser.h:2208
#define LEFT_ALT_PRESSED
Definition: wincon.h:138
PPOPUP_WINDOW Popup
Definition: lineinput.c:140
PUNICODE_STRING Entries
Definition: history.c:24
PPOPUP_WINDOW HistoryDisplayCurrentHistory(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName)
Definition: history.c:315
#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
BOOL HistoryFindEntryByPrefix(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Prefix, PUNICODE_STRING Entry)
Definition: history.c:273
#define VK_F3
Definition: winuser.h:2232
union _KEY_EVENT_RECORD::@3241 uChar
#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 HistoryDeleteCurrentBuffer(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName)
Definition: history.c:350
#define VK_RIGHT
Definition: winuser.h:2201
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:78
#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:38
#define VK_F1
Definition: winuser.h:2230
CConsole Console
#define DPRINT1
Definition: precomp.h:8
VOID HistoryAddEntry(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, PUNICODE_STRING Entry)
Definition: history.c:185
#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:63
static VOID LineInputRecallHistory(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, INT Offset)
Definition: lineinput.c:106
#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 ConSrvTermReadStream().