ReactOS  0.4.14-dev-77-gd9e7c48
cmdinput.c File Reference
#include "precomp.h"
Include dependency graph for cmdinput.c:

Go to the source code of this file.

Functions

static VOID ClearCommandLine (LPTSTR str, INT maxlen, SHORT orgx, SHORT orgy)
 
BOOL ReadCommand (LPTSTR str, INT maxlen)
 

Variables

TCHAR AutoCompletionChar = _T('\t')
 
TCHAR PathCompletionChar = _T('\t')
 
SHORT maxx
 
SHORT maxy
 
static BOOL bInsert = TRUE
 

Function Documentation

◆ ClearCommandLine()

static VOID ClearCommandLine ( LPTSTR  str,
INT  maxlen,
SHORT  orgx,
SHORT  orgy 
)
static

Definition at line 125 of file cmdinput.c.

126 {
127  INT count;
128 
129  SetCursorXY (orgx, orgy);
130  for (count = 0; count < (INT)_tcslen (str); count++)
131  ConOutChar (_T(' '));
132  _tcsnset (str, _T('\0'), maxlen);
133  SetCursorXY (orgx, orgy);
134 }
VOID ConOutChar(TCHAR c)
Definition: console.c:123
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define INT
Definition: polytest.cpp:20
int32_t INT
Definition: typedefs.h:56
const WCHAR * str
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
#define _T(x)
Definition: vfdio.h:22
VOID SetCursorXY(SHORT x, SHORT y)
Definition: console.c:191
#define _tcsnset
Definition: tchar.h:1419

Referenced by ReadCommand().

◆ ReadCommand()

BOOL ReadCommand ( LPTSTR  str,
INT  maxlen 
)

Definition at line 138 of file cmdinput.c.

139 {
141  SHORT orgx; /* origin x/y */
142  SHORT orgy;
143  SHORT curx; /*current x/y cursor position*/
144  SHORT cury;
145  SHORT tempscreen;
146  INT count; /*used in some for loops*/
147  INT current = 0; /*the position of the cursor in the string (str)*/
148  INT charcount = 0;/*chars in the string (str)*/
149  INPUT_RECORD ir;
150  DWORD dwControlKeyState;
151 #ifdef FEATURE_UNIX_FILENAME_COMPLETION
152  WORD wLastKey = 0;
153 #endif
154  TCHAR ch;
155  BOOL bReturn = FALSE;
156  BOOL bCharInput;
157 #ifdef FEATURE_4NT_FILENAME_COMPLETION
159 #endif
160 #ifdef FEATURE_HISTORY
161  //BOOL bContinue=FALSE;/*is TRUE the second case will not be executed*/
162  TCHAR PreviousChar;
163 #endif
164 
166  {
167  /* No console */
169  DWORD dwRead;
170  CHAR chr;
171  do
172  {
173  if (!ReadFile(hStdin, &chr, 1, &dwRead, NULL) || !dwRead)
174  return FALSE;
175 #ifdef _UNICODE
176  MultiByteToWideChar(InputCodePage, 0, &chr, 1, &str[charcount++], 1);
177 #endif
178  } while (chr != '\n' && charcount < maxlen);
179  str[charcount] = _T('\0');
180  return TRUE;
181  }
182 
183  /* get screen size */
184  maxx = csbi.dwSize.X;
185  maxy = csbi.dwSize.Y;
186 
187  curx = orgx = csbi.dwCursorPosition.X;
188  cury = orgy = csbi.dwCursorPosition.Y;
189 
190  memset (str, 0, maxlen * sizeof (TCHAR));
191 
193 
194  do
195  {
196  bReturn = FALSE;
197  ConInKey (&ir);
198 
199  dwControlKeyState = ir.Event.KeyEvent.dwControlKeyState;
200 
201  if (dwControlKeyState &
204  {
205  switch (ir.Event.KeyEvent.wVirtualKeyCode)
206  {
207 #ifdef FEATURE_HISTORY
208  case _T('K'):
209  /* add the current command line to the history */
210  if (dwControlKeyState &
212  {
213  if (str[0])
214  History(0,str);
215 
216  ClearCommandLine (str, maxlen, orgx, orgy);
217  current = charcount = 0;
218  curx = orgx;
219  cury = orgy;
220  //bContinue=TRUE;
221  break;
222  }
223 
224  case _T('D'):
225  /* delete current history entry */
226  if (dwControlKeyState &
228  {
229  ClearCommandLine (str, maxlen, orgx, orgy);
231  current = charcount = _tcslen (str);
232  ConOutPrintf (_T("%s"), str);
233  GetCursorXY (&curx, &cury);
234  //bContinue=TRUE;
235  break;
236  }
237 #endif /*FEATURE_HISTORY*/
238 
239  case _T('M'):
240  /* ^M does the same as return */
241  if (dwControlKeyState &
243  {
244  /* end input, return to main */
245 #ifdef FEATURE_HISTORY
246  /* add to the history */
247  if (str[0])
248  History(0, str);
249 #endif /*FEATURE_HISTORY*/
250  str[charcount++] = _T('\n');
251  str[charcount] = _T('\0');
252  ConOutChar (_T('\n'));
253  bReturn = TRUE;
254  break;
255  }
256  }
257  }
258 
259  bCharInput = FALSE;
260 
261  switch (ir.Event.KeyEvent.wVirtualKeyCode)
262  {
263  case VK_BACK:
264  /* <BACKSPACE> - delete character to left of cursor */
265  if (current > 0 && charcount > 0)
266  {
267  if (current == charcount)
268  {
269  /* if at end of line */
270  str[current - 1] = _T('\0');
271  if (GetCursorX () != 0)
272  {
273  ConOutPrintf (_T("\b \b"));
274  curx--;
275  }
276  else
277  {
278  SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1));
279  ConOutChar (_T(' '));
280  SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1));
281  cury--;
282  curx = maxx - 1;
283  }
284  }
285  else
286  {
287  for (count = current - 1; count < charcount; count++)
288  str[count] = str[count + 1];
289  if (GetCursorX () != 0)
290  {
291  SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ());
292  curx--;
293  }
294  else
295  {
296  SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1));
297  cury--;
298  curx = maxx - 1;
299  }
300  GetCursorXY (&curx, &cury);
301  ConOutPrintf (_T("%s "), &str[current - 1]);
302  SetCursorXY (curx, cury);
303  }
304  charcount--;
305  current--;
306  }
307  break;
308 
309  case VK_INSERT:
310  /* toggle insert/overstrike mode */
311  bInsert ^= TRUE;
313  break;
314 
315  case VK_DELETE:
316  /* delete character under cursor */
317  if (current != charcount && charcount > 0)
318  {
319  for (count = current; count < charcount; count++)
320  str[count] = str[count + 1];
321  charcount--;
322  GetCursorXY (&curx, &cury);
323  ConOutPrintf (_T("%s "), &str[current]);
324  SetCursorXY (curx, cury);
325  }
326  break;
327 
328  case VK_HOME:
329  /* goto beginning of string */
330  if (current != 0)
331  {
332  SetCursorXY (orgx, orgy);
333  curx = orgx;
334  cury = orgy;
335  current = 0;
336  }
337  break;
338 
339  case VK_END:
340  /* goto end of string */
341  if (current != charcount)
342  {
343  SetCursorXY (orgx, orgy);
344  ConOutPrintf (_T("%s"), str);
345  GetCursorXY (&curx, &cury);
346  current = charcount;
347  }
348  break;
349 
350  case VK_TAB:
351 #ifdef FEATURE_UNIX_FILENAME_COMPLETION
352  /* expand current file name */
353  if ((current == charcount) ||
354  (current == charcount - 1 &&
355  str[current] == _T('"'))) /* only works at end of line*/
356  {
357  if (wLastKey != VK_TAB)
358  {
359  /* if first TAB, complete filename*/
360  tempscreen = charcount;
361  CompleteFilename (str, charcount);
362  charcount = _tcslen (str);
363  current = charcount;
364 
365  SetCursorXY (orgx, orgy);
366  ConOutPrintf (_T("%s"), str);
367 
368  if (tempscreen > charcount)
369  {
370  GetCursorXY (&curx, &cury);
371  for (count = tempscreen - charcount; count--; )
372  ConOutChar (_T(' '));
373  SetCursorXY (curx, cury);
374  }
375  else
376  {
377  if (((charcount + orgx) / maxx) + orgy > maxy - 1)
378  orgy += maxy - ((charcount + orgx) / maxx + orgy + 1);
379  }
380 
381  /* set cursor position */
382  SetCursorXY ((orgx + current) % maxx,
383  orgy + (orgx + current) / maxx);
384  GetCursorXY (&curx, &cury);
385  }
386  else
387  {
388  /*if second TAB, list matches*/
389  if (ShowCompletionMatches (str, charcount))
390  {
391  PrintPrompt();
392  GetCursorXY(&orgx, &orgy);
393  ConOutPrintf(_T("%s"), str);
394 
395  /* set cursor position */
396  SetCursorXY((orgx + current) % maxx,
397  orgy + (orgx + current) / maxx);
398  GetCursorXY(&curx, &cury);
399  }
400 
401  }
402  }
403  else
404  {
405  MessageBeep(-1);
406  }
407 #endif
408 #ifdef FEATURE_4NT_FILENAME_COMPLETION
409  /* used to later see if we went down to the next line */
410  tempscreen = charcount;
411  szPath[0]=_T('\0');
412 
413  /* str is the whole things that is on the current line
414  that is and and out. arg 2 is weather it goes back
415  one file or forward one file */
417  /* Attempt to clear the line */
418  ClearCommandLine (str, maxlen, orgx, orgy);
419  curx = orgx;
420  cury = orgy;
421  current = charcount = 0;
422 
423  /* Everything is deleted, lets add it back in */
424  _tcscpy(str,szPath);
425 
426  /* Figure out where cusor is going to be after we print it */
427  charcount = _tcslen(str);
428  current = charcount;
429 
430  SetCursorXY(orgx, orgy);
431  /* Print out what we have now */
432  ConOutPrintf(_T("%s"), str);
433 
434  /* Move cursor accordingly */
435  if (tempscreen > charcount)
436  {
437  GetCursorXY(&curx, &cury);
438  for(count = tempscreen - charcount; count--; )
439  ConOutChar(_T(' '));
440  SetCursorXY(curx, cury);
441  }
442  else
443  {
444  if (((charcount + orgx) / maxx) + orgy > maxy - 1)
445  orgy += maxy - ((charcount + orgx) / maxx + orgy + 1);
446  }
447  SetCursorXY((short)(((int)orgx + current) % maxx), (short)((int)orgy + ((int)orgx + current) / maxx));
448  GetCursorXY(&curx, &cury);
449 #endif
450  break;
451 
452  case _T('C'):
453  if ((ir.Event.KeyEvent.dwControlKeyState &
455  {
456  /* Ignore the Ctrl-C key event if it has already been handled */
457  if (!bCtrlBreak)
458  break;
459 
460  /*
461  * Fully print the entered string
462  * so the command prompt would not overwrite it.
463  */
464  SetCursorXY(orgx, orgy);
465  ConOutPrintf(_T("%s"), str);
466 
467  /*
468  * A Ctrl-C. Do not clear the command line,
469  * but return an empty string in str.
470  */
471  str[0] = _T('\0');
472  curx = orgx;
473  cury = orgy;
474  current = charcount = 0;
475  bReturn = TRUE;
476  }
477  else
478  {
479  /* Just a normal 'C' character */
480  bCharInput = TRUE;
481  }
482  break;
483 
484  case VK_RETURN:
485  /* end input, return to main */
486 #ifdef FEATURE_HISTORY
487  /* add to the history */
488  if (str[0])
489  History(0, str);
490 #endif
491  str[charcount++] = _T('\n');
492  str[charcount] = _T('\0');
493  ConOutChar(_T('\n'));
494  bReturn = TRUE;
495  break;
496 
497  case VK_ESCAPE:
498  /* clear str Make this callable! */
499  ClearCommandLine (str, maxlen, orgx, orgy);
500  curx = orgx;
501  cury = orgy;
502  current = charcount = 0;
503  break;
504 
505 #ifdef FEATURE_HISTORY
506  case VK_F3:
508 #endif
509  case VK_UP:
510 #ifdef FEATURE_HISTORY
511  /* get previous command from buffer */
512  ClearCommandLine (str, maxlen, orgx, orgy);
513  History(-1, str);
514  current = charcount = _tcslen (str);
515  if (((charcount + orgx) / maxx) + orgy > maxy - 1)
516  orgy += maxy - ((charcount + orgx) / maxx + orgy + 1);
517  ConOutPrintf (_T("%s"), str);
518  GetCursorXY (&curx, &cury);
519 #endif
520  break;
521 
522  case VK_DOWN:
523 #ifdef FEATURE_HISTORY
524  /* get next command from buffer */
525  ClearCommandLine (str, maxlen, orgx, orgy);
526  History(1, str);
527  current = charcount = _tcslen (str);
528  if (((charcount + orgx) / maxx) + orgy > maxy - 1)
529  orgy += maxy - ((charcount + orgx) / maxx + orgy + 1);
530  ConOutPrintf (_T("%s"), str);
531  GetCursorXY (&curx, &cury);
532 #endif
533  break;
534 
535  case VK_LEFT:
536  if (dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
537  {
538  /* move cursor to the previous word */
539  if (current > 0)
540  {
541  while (current > 0 && str[current - 1] == _T(' '))
542  {
543  current--;
544  if (curx == 0)
545  {
546  cury--;
547  curx = maxx -1;
548  }
549  else
550  {
551  curx--;
552  }
553  }
554 
555  while (current > 0 && str[current -1] != _T(' '))
556  {
557  current--;
558  if (curx == 0)
559  {
560  cury--;
561  curx = maxx -1;
562  }
563  else
564  {
565  curx--;
566  }
567  }
568 
569  SetCursorXY(curx, cury);
570  }
571  }
572  else
573  {
574  /* move cursor left */
575  if (current > 0)
576  {
577  current--;
578  if (GetCursorX () == 0)
579  {
580  SetCursorXY ((SHORT)(maxx - 1), (SHORT)(GetCursorY () - 1));
581  curx = maxx - 1;
582  cury--;
583  }
584  else
585  {
586  SetCursorXY ((SHORT)(GetCursorX () - 1), GetCursorY ());
587  curx--;
588  }
589  }
590  else
591  {
592  MessageBeep (-1);
593  }
594  }
595  break;
596 
597  case VK_RIGHT:
598  if (dwControlKeyState & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
599  {
600  /* move cursor to the next word */
601  if (current != charcount)
602  {
603  while (current != charcount && str[current] != _T(' '))
604  {
605  current++;
606  if (curx == maxx - 1)
607  {
608  cury++;
609  curx = 0;
610  }
611  else
612  {
613  curx++;
614  }
615  }
616 
617  while (current != charcount && str[current] == _T(' '))
618  {
619  current++;
620  if (curx == maxx - 1)
621  {
622  cury++;
623  curx = 0;
624  }
625  else
626  {
627  curx++;
628  }
629  }
630 
631  SetCursorXY(curx, cury);
632  }
633  }
634  else
635  {
636  /* move cursor right */
637  if (current != charcount)
638  {
639  current++;
640  if (GetCursorX () == maxx - 1)
641  {
642  SetCursorXY (0, (SHORT)(GetCursorY () + 1));
643  curx = 0;
644  cury++;
645  }
646  else
647  {
648  SetCursorXY ((SHORT)(GetCursorX () + 1), GetCursorY ());
649  curx++;
650  }
651  }
652 #ifdef FEATURE_HISTORY
653  else
654  {
655  LPCTSTR last = PeekHistory(-1);
656  if (last && charcount < (INT)_tcslen (last))
657  {
658  PreviousChar = last[current];
659  ConOutChar(PreviousChar);
660  GetCursorXY(&curx, &cury);
661  str[current++] = PreviousChar;
662  charcount++;
663  }
664  }
665 #endif
666  }
667  break;
668 
669  default:
670  /* This input is just a normal char */
671  bCharInput = TRUE;
672 
673  }
674 #ifdef _UNICODE
676  if (ch >= 32 && (charcount != (maxlen - 2)) && bCharInput)
677 #else
678  ch = ir.Event.KeyEvent.uChar.AsciiChar;
679  if ((UCHAR)ch >= 32 && (charcount != (maxlen - 2)) && bCharInput)
680 #endif /* _UNICODE */
681  {
682  /* insert character into string... */
683  if (bInsert && current != charcount)
684  {
685  /* If this character insertion will cause screen scrolling,
686  * adjust the saved origin of the command prompt. */
687  tempscreen = _tcslen(str + current) + curx;
688  if ((tempscreen % maxx) == (maxx - 1) &&
689  (tempscreen / maxx) + cury == (maxy - 1))
690  {
691  orgy--;
692  cury--;
693  }
694 
695  for (count = charcount; count > current; count--)
696  str[count] = str[count - 1];
697  str[current++] = ch;
698  if (curx == maxx - 1)
699  curx = 0, cury++;
700  else
701  curx++;
702  ConOutPrintf (_T("%s"), &str[current - 1]);
703  SetCursorXY (curx, cury);
704  charcount++;
705  }
706  else
707  {
708  if (current == charcount)
709  charcount++;
710  str[current++] = ch;
711  if (GetCursorX () == maxx - 1 && GetCursorY () == maxy - 1)
712  orgy--, cury--;
713  if (GetCursorX () == maxx - 1)
714  curx = 0, cury++;
715  else
716  curx++;
717  ConOutChar (ch);
718  }
719  }
720 
721  //wLastKey = ir.Event.KeyEvent.wVirtualKeyCode;
722  }
723  while (!bReturn);
724 
726 
727 #ifdef FEATURE_ALIASES
728  /* expand all aliases */
729  ExpandAlias (str, maxlen);
730 #endif /* FEATURE_ALIAS */
731  return TRUE;
732 }
#define TRUE
Definition: types.h:120
const CHAR * LPCTSTR
Definition: xmlstorage.h:193
WCHAR UnicodeChar
Definition: wincon.h:230
static VOID ClearCommandLine(LPTSTR str, INT maxlen, SHORT orgx, SHORT orgy)
Definition: cmdinput.c:125
POINT last
Definition: font.c:46
VOID ConOutChar(TCHAR c)
Definition: console.c:123
VOID GetCursorXY(PSHORT x, PSHORT y)
Definition: console.c:200
GLuint GLuint GLsizei count
Definition: gl.h:1545
char CHAR
Definition: xmlstorage.h:175
VOID History_move_to_bottom(VOID)
Definition: history.c:280
DWORD dwControlKeyState
Definition: wincon.h:233
#define VK_LEFT
Definition: winuser.h:2199
_TCHAR * _tcscpy(_TCHAR *to, const _TCHAR *from)
Definition: tcscpy.h:8
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:152
#define ConOutPrintf(szStr,...)
Definition: console.h:42
#define VK_TAB
Definition: winuser.h:2174
#define VK_DOWN
Definition: winuser.h:2202
#define VK_INSERT
Definition: winuser.h:2207
#define SHIFT_PRESSED
Definition: wincon.h:135
#define VK_ESCAPE
Definition: winuser.h:2189
int32_t INT
Definition: typedefs.h:56
#define VK_RETURN
Definition: winuser.h:2176
VOID ExpandAlias(LPTSTR cmd, INT maxlen)
Definition: alias.c:89
WORD wVirtualKeyCode
Definition: wincon.h:227
union _INPUT_RECORD::@3154 Event
VOID ConInKey(PINPUT_RECORD lpBuffer)
Definition: console.c:61
#define VK_HOME
Definition: winuser.h:2198
VOID SetCursorType(BOOL bInsert, BOOL bVisible)
Definition: console.c:226
SHORT maxy
Definition: cmdinput.c:116
#define VK_UP
Definition: winuser.h:2200
unsigned int BOOL
Definition: ntddk_ex.h:94
short SHORT
Definition: pedump.c:59
SHORT GetCursorX(VOID)
Definition: console.c:210
const WCHAR * str
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
smooth NULL
Definition: ftsmooth.c:416
UINT InputCodePage
Definition: console.c:25
#define STD_INPUT_HANDLE
Definition: winbase.h:264
VOID CompleteFilename(LPTSTR, BOOL, LPTSTR, UINT)
Definition: filecomp.c:545
#define VK_DELETE
Definition: winuser.h:2208
BOOL WINAPI GetConsoleScreenBufferInfo(IN HANDLE hConsoleOutput, OUT PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
Definition: console.c:544
#define LEFT_ALT_PRESSED
Definition: wincon.h:132
HANDLE hStdin
Definition: ctm.c:55
ULONG X
Definition: bl.h:1340
char TCHAR
Definition: xmlstorage.h:189
union _KEY_EVENT_RECORD::@3153 uChar
#define _T(x)
Definition: vfdio.h:22
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define MAX_PATH
Definition: compat.h:26
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:263
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define VK_F3
Definition: winuser.h:2232
unsigned char UCHAR
Definition: xmlstorage.h:181
#define LEFT_CTRL_PRESSED
Definition: wincon.h:134
VOID History_del_current_entry(LPTSTR str)
Definition: history.c:175
#define STD_OUTPUT_HANDLE
Definition: winbase.h:265
#define VK_BACK
Definition: winuser.h:2173
int chr(char *serport)
Definition: gdblib.c:152
#define VK_RIGHT
Definition: winuser.h:2201
static BOOL bInsert
Definition: cmdinput.c:121
BOOL WINAPI MessageBeep(_In_ UINT)
LPCTSTR PeekHistory(INT)
Definition: history.c:287
LPCWSTR szPath
Definition: env.c:35
VOID SetCursorXY(SHORT x, SHORT y)
Definition: console.c:191
#define MultiByteToWideChar
Definition: compat.h:100
SHORT GetCursorY(VOID)
Definition: console.c:218
SHORT maxx
Definition: cmdinput.c:115
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:133
VOID History(INT, LPTSTR)
Definition: history.c:326
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
ULONG Y
Definition: bl.h:1341
#define memset(x, y, z)
Definition: compat.h:39
#define VK_END
Definition: winuser.h:2197
VOID PrintPrompt(VOID)
Definition: prompt.c:109
#define RIGHT_ALT_PRESSED
Definition: wincon.h:131
struct task_struct * current
Definition: linux.c:32
BOOL bCtrlBreak
Definition: cmd.c:154

Variable Documentation

◆ AutoCompletionChar

TCHAR AutoCompletionChar = _T('\t')

Definition at line 111 of file cmdinput.c.

Referenced by LoadRegistrySettings().

◆ bInsert

◆ maxx

SHORT maxx

Definition at line 115 of file cmdinput.c.

Referenced by CommandScreen(), GetScreenSize(), and ReadCommand().

◆ maxy

◆ PathCompletionChar

TCHAR PathCompletionChar = _T('\t')

Definition at line 112 of file cmdinput.c.

Referenced by LoadRegistrySettings().