ReactOS  0.4.14-dev-866-g5b3e84f
terminal.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS Console Server DLL
4  * FILE: win32ss/user/winsrv/consrv/frontends/terminal.c
5  * PURPOSE: ConSrv terminal.
6  * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <consrv.h>
12 #include "concfg/font.h"
13 
14 // #include "frontends/gui/guiterm.h"
15 #ifdef TUITERM_COMPILE
16 #include "frontends/tui/tuiterm.h"
17 #endif
18 
19 #define NDEBUG
20 #include <debug.h>
21 
22 
23 
24 
25 
26 /********** HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK ************/
27 
28 /* GLOBALS ********************************************************************/
29 
30 /*
31  * From MSDN:
32  * "The lpMultiByteStr and lpWideCharStr pointers must not be the same.
33  * If they are the same, the function fails, and GetLastError returns
34  * ERROR_INVALID_PARAMETER."
35  */
36 #define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar) \
37  ASSERT((ULONG_PTR)dChar != (ULONG_PTR)sWChar); \
38  WideCharToMultiByte((Console)->InputCodePage, 0, (sWChar), 1, (dChar), 1, NULL, NULL)
39 
40 #define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar) \
41  ASSERT((ULONG_PTR)dWChar != (ULONG_PTR)sChar); \
42  MultiByteToWideChar((Console)->InputCodePage, 0, (sChar), 1, (dWChar), 1)
43 
44 /* PRIVATE FUNCTIONS **********************************************************/
45 
46 #if 0
47 
48 static VOID
50 {
51  if (InputEvent->EventType == KEY_EVENT)
52  {
53  WCHAR UnicodeChar = InputEvent->Event.KeyEvent.uChar.UnicodeChar;
54  InputEvent->Event.KeyEvent.uChar.UnicodeChar = 0;
56  &InputEvent->Event.KeyEvent.uChar.AsciiChar,
57  &UnicodeChar);
58  }
59 }
60 
61 static VOID
63 {
64  if (InputEvent->EventType == KEY_EVENT)
65  {
66  CHAR AsciiChar = InputEvent->Event.KeyEvent.uChar.AsciiChar;
67  InputEvent->Event.KeyEvent.uChar.AsciiChar = 0;
69  &InputEvent->Event.KeyEvent.uChar.UnicodeChar,
70  &AsciiChar);
71  }
72 }
73 
74 #endif
75 
76 /********** HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK ************/
77 
78 
79 
80 
81 
82 
83 
84 
85 /* CONSRV TERMINAL FRONTENDS INTERFACE ****************************************/
86 
87 /***************/
88 #ifdef TUITERM_COMPILE
90 TuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd,
92  IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
93  IN HANDLE ConsoleLeaderProcessHandle);
95 TuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd);
96 #endif
97 
101  IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
102  IN HANDLE ConsoleLeaderProcessHandle);
105 /***************/
106 
107 typedef
110  IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
111  IN HANDLE ConsoleLeaderProcessHandle);
112 
113 typedef
115 
116 /*
117  * If we are not in GUI-mode, start the text-mode terminal emulator.
118  * If we fail, try to start the GUI-mode terminal emulator.
119  *
120  * Try to open the GUI-mode terminal emulator. Two cases are possible:
121  * - We are in GUI-mode, therefore GuiMode == TRUE, the previous test-case
122  * failed and we start GUI-mode terminal emulator.
123  * - We are in text-mode, therefore GuiMode == FALSE, the previous test-case
124  * succeeded BUT we failed at starting text-mode terminal emulator.
125  * Then GuiMode was switched to TRUE in order to try to open the GUI-mode
126  * terminal emulator (Win32k will automatically switch to graphical mode,
127  * therefore no additional code is needed).
128  */
129 
130 /*
131  * NOTE: Each entry of the table should be retrieved when loading a front-end
132  * (examples of the CSR servers which register some data for CSRSS).
133  */
134 static struct
135 {
140 {
141 #ifdef TUITERM_COMPILE
142  {"TUI", TuiLoadFrontEnd, TuiUnloadFrontEnd},
143 #endif
145 
146 // {"Not found", 0, NULL}
147 };
148 
149 static NTSTATUS
152  IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
153  IN HANDLE ConsoleLeaderProcessHandle)
154 {
156  ULONG i;
157 
158  /*
159  * Choose an adequate terminal front-end to load, and load it
160  */
161  for (i = 0; i < ARRAYSIZE(FrontEndLoadingMethods); ++i)
162  {
163  DPRINT("CONSRV: Trying to load %s frontend...\n",
165  Status = FrontEndLoadingMethods[i].FrontEndLoad(FrontEnd,
166  ConsoleInfo,
167  ConsoleInitInfo,
168  ConsoleLeaderProcessHandle);
169  if (NT_SUCCESS(Status))
170  {
171  /* Save the unload callback */
172  FrontEnd->UnloadFrontEnd = FrontEndLoadingMethods[i].FrontEndUnload;
173 
174  DPRINT("CONSRV: %s frontend loaded successfully\n",
176  break;
177  }
178  else
179  {
180  DPRINT1("CONSRV: Loading %s frontend failed, Status = 0x%08lx , continuing...\n",
182  }
183  }
184 
185  return Status;
186 }
187 
188 static NTSTATUS
190 {
191  if (FrontEnd == NULL) return STATUS_INVALID_PARAMETER;
192  // return FrontEnd->Vtbl->UnloadFrontEnd(FrontEnd);
193  return FrontEnd->UnloadFrontEnd(FrontEnd);
194 }
195 
196 // See after...
198 
202  IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo,
203  IN HANDLE ConsoleLeaderProcessHandle)
204 {
206  PFRONTEND FrontEnd;
207 
208  /* Load a suitable frontend for the ConSrv terminal */
209  FrontEnd = ConsoleAllocHeap(HEAP_ZERO_MEMORY, sizeof(*FrontEnd));
210  if (!FrontEnd) return STATUS_NO_MEMORY;
211 
212  Status = ConSrvLoadFrontEnd(FrontEnd,
213  ConsoleInfo,
214  ConsoleInitInfo,
215  ConsoleLeaderProcessHandle);
216  if (!NT_SUCCESS(Status))
217  {
218  DPRINT1("CONSRV: Failed to initialize a frontend, Status = 0x%08lx\n", Status);
219  ConsoleFreeHeap(FrontEnd);
220  return Status;
221  }
222  DPRINT("CONSRV: Frontend initialized\n");
223 
224  /* Initialize the ConSrv terminal */
225  Terminal->Vtbl = &ConSrvTermVtbl;
226  // Terminal->Console will be initialized by ConDrvAttachTerminal
227  Terminal->Context = FrontEnd; /* We store the frontend pointer in the terminal private context */
228 
229  return STATUS_SUCCESS;
230 }
231 
234 {
236  PFRONTEND FrontEnd = Terminal->Context;
237 
238  /* Reset the ConSrv terminal */
239  Terminal->Context = NULL;
240  Terminal->Vtbl = NULL;
241 
242  /* Unload the frontend */
243  if (FrontEnd != NULL)
244  {
245  Status = ConSrvUnloadFrontEnd(FrontEnd);
246  ConsoleFreeHeap(FrontEnd);
247  }
248 
249  return Status;
250 }
251 
252 
253 /* CONSRV TERMINAL INTERFACE **************************************************/
254 
255 static NTSTATUS NTAPI
258 {
260  PFRONTEND FrontEnd = This->Context;
261 
262  /* Initialize the console pointer for our frontend */
263  FrontEnd->Console = Console;
264 
266  DPRINT("Using FrontEndIFace HACK(1), should be removed after proper implementation!\n");
267  Console->FrontEndIFace = *FrontEnd;
268 
269  Status = FrontEnd->Vtbl->InitFrontEnd(FrontEnd, FrontEnd->Console);
270  if (!NT_SUCCESS(Status))
271  DPRINT1("InitFrontEnd failed, Status = 0x%08lx\n", Status);
272 
274  DPRINT("Using FrontEndIFace HACK(2), should be removed after proper implementation!\n");
275  Console->FrontEndIFace = *FrontEnd;
276 
277  return Status;
278 }
279 
280 static VOID NTAPI
282 {
283  PFRONTEND FrontEnd = This->Context;
284  FrontEnd->Vtbl->DeinitFrontEnd(FrontEnd);
285 }
286 
287 
288 
289 /************ Line discipline ***************/
290 
291 static NTSTATUS NTAPI
293  IN BOOLEAN Unicode,
295  OUT PVOID Buffer,
296  IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl,
298  IN ULONG NumCharsToRead,
299  OUT PULONG NumCharsRead OPTIONAL)
300 {
301  PFRONTEND FrontEnd = This->Context;
302  PCONSRV_CONSOLE Console = FrontEnd->Console;
303  PCONSOLE_INPUT_BUFFER InputBuffer = &Console->InputBuffer;
304  PUNICODE_STRING ExeName = Parameter;
305 
306  // STATUS_PENDING : Wait if more to read ; STATUS_SUCCESS : Don't wait.
308 
309  PLIST_ENTRY CurrentEntry;
311  ULONG i = 0;
312 
313  /* Validity checks */
314  // ASSERT(Console == InputBuffer->Header.Console);
315  ASSERT((Buffer != NULL) || (Buffer == NULL && NumCharsToRead == 0));
316 
317  /* We haven't read anything (yet) */
318 
319  if (InputBuffer->Mode & ENABLE_LINE_INPUT)
320  {
321  /* COOKED mode, call the line discipline */
322 
323  if (Console->LineBuffer == NULL)
324  {
325  /* Start a new line */
326  Console->LineMaxSize = max(256, NumCharsToRead);
327 
328  /*
329  * Fixup ReadControl->nInitialChars in case the number of initial
330  * characters is bigger than the number of characters to be read.
331  * It will always be, lesser than or equal to Console->LineMaxSize.
332  */
333  ReadControl->nInitialChars = min(ReadControl->nInitialChars, NumCharsToRead);
334 
335  Console->LineBuffer = ConsoleAllocHeap(0, Console->LineMaxSize * sizeof(WCHAR));
336  if (Console->LineBuffer == NULL) return STATUS_NO_MEMORY;
337 
338  Console->LinePos = Console->LineSize = ReadControl->nInitialChars;
339  Console->LineComplete = Console->LineUpPressed = FALSE;
340  Console->LineInsertToggle = Console->InsertMode;
341  Console->LineWakeupMask = ReadControl->dwCtrlWakeupMask;
342 
343  /*
344  * Pre-fill the buffer with the nInitialChars from the user buffer.
345  * Since pre-filling is only allowed in Unicode, we don't need to
346  * worry about ANSI <-> Unicode conversion.
347  */
348  memcpy(Console->LineBuffer, Buffer, Console->LineSize * sizeof(WCHAR));
349  if (Console->LineSize >= Console->LineMaxSize)
350  {
351  Console->LineComplete = TRUE;
352  Console->LinePos = 0;
353  }
354  }
355 
356  /* If we don't have a complete line yet, process the pending input */
357  while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents))
358  {
359  /* Remove an input event from the queue */
360  CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
361  if (IsListEmpty(&InputBuffer->InputEvents))
362  {
363  ResetEvent(InputBuffer->ActiveEvent);
364  }
365  Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
366 
367  /* Only pay attention to key down */
368  if (Input->InputEvent.EventType == KEY_EVENT &&
369  Input->InputEvent.Event.KeyEvent.bKeyDown)
370  {
371  LineInputKeyDown(Console, ExeName,
372  &Input->InputEvent.Event.KeyEvent);
373  ReadControl->dwControlKeyState = Input->InputEvent.Event.KeyEvent.dwControlKeyState;
374  }
376  }
377 
378  /* Check if we have a complete line to read from */
379  if (Console->LineComplete)
380  {
381  /*
382  * Console->LinePos keeps the next position of the character to read
383  * in the line buffer across the different calls of the function,
384  * so that the line buffer can be read by chunks after all the input
385  * has been buffered.
386  */
387 
388  while (i < NumCharsToRead && Console->LinePos < Console->LineSize)
389  {
390  WCHAR Char = Console->LineBuffer[Console->LinePos++];
391 
392  if (Unicode)
393  {
394  ((PWCHAR)Buffer)[i] = Char;
395  }
396  else
397  {
399  }
400  ++i;
401  }
402 
403  if (Console->LinePos >= Console->LineSize)
404  {
405  /* The entire line has been read */
406  ConsoleFreeHeap(Console->LineBuffer);
407  Console->LineBuffer = NULL;
408  Console->LinePos = Console->LineMaxSize = Console->LineSize = 0;
409  // Console->LineComplete = Console->LineUpPressed = FALSE;
410  Console->LineComplete = FALSE;
411  }
412 
414  }
415  }
416  else
417  {
418  /* RAW mode */
419 
420  /* Character input */
421  while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents))
422  {
423  /* Remove an input event from the queue */
424  CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents);
425  if (IsListEmpty(&InputBuffer->InputEvents))
426  {
427  ResetEvent(InputBuffer->ActiveEvent);
428  }
429  Input = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry);
430 
431  /* Only pay attention to valid characters, on key down */
432  if (Input->InputEvent.EventType == KEY_EVENT &&
433  Input->InputEvent.Event.KeyEvent.bKeyDown &&
434  Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar != L'\0')
435  {
436  WCHAR Char = Input->InputEvent.Event.KeyEvent.uChar.UnicodeChar;
437 
438  if (Unicode)
439  {
440  ((PWCHAR)Buffer)[i] = Char;
441  }
442  else
443  {
445  }
446  ++i;
447 
448  /* Did read something */
450  }
452  }
453  }
454 
455  // FIXME: Only set if Status == STATUS_SUCCESS ???
456  if (NumCharsRead) *NumCharsRead = i;
457 
458  return Status;
459 }
460 
461 
462 
463 
464 /* GLOBALS ********************************************************************/
465 
466 #define TAB_WIDTH 8
467 
468 // See condrv/text.c
469 /*static*/ VOID
471 
472 static VOID
474 {
475  /* If we hit bottom, slide the viewable screen */
476  if (++Buff->CursorPosition.Y == Buff->ScreenBufferSize.Y)
477  {
478  Buff->CursorPosition.Y--;
479  if (++Buff->VirtualY == Buff->ScreenBufferSize.Y)
480  {
481  Buff->VirtualY = 0;
482  }
483  (*ScrolledLines)++;
484  ClearLineBuffer(Buff);
485  if (UpdateRect->Top != 0)
486  {
487  UpdateRect->Top--;
488  }
489  }
490  UpdateRect->Left = 0;
491  UpdateRect->Right = Buff->ScreenBufferSize.X - 1;
492  UpdateRect->Bottom = Buff->CursorPosition.Y;
493 }
494 
495 static NTSTATUS
498  PWCHAR Buffer,
499  DWORD Length,
500  BOOL Attrib)
501 {
502  PCONSRV_CONSOLE Console = FrontEnd->Console;
503 
504  UINT i;
505  PCHAR_INFO Ptr;
507  SHORT CursorStartX, CursorStartY;
508  UINT ScrolledLines;
509  BOOL bCJK = Console->IsCJK;
510 
511  CursorStartX = Buff->CursorPosition.X;
512  CursorStartY = Buff->CursorPosition.Y;
513  UpdateRect.Left = Buff->ScreenBufferSize.X;
514  UpdateRect.Top = Buff->CursorPosition.Y;
515  UpdateRect.Right = -1;
516  UpdateRect.Bottom = Buff->CursorPosition.Y;
517  ScrolledLines = 0;
518 
519  for (i = 0; i < Length; i++)
520  {
521  /*
522  * If we are in processed mode, interpret special characters and
523  * display them correctly. Otherwise, just put them into the buffer.
524  */
525  if (Buff->Mode & ENABLE_PROCESSED_OUTPUT)
526  {
527  /* --- CR --- */
528  if (Buffer[i] == L'\r')
529  {
530  Buff->CursorPosition.X = 0;
531  UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
532  UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
533  continue;
534  }
535  /* --- LF --- */
536  else if (Buffer[i] == L'\n')
537  {
538  Buff->CursorPosition.X = 0;
539  ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
540  continue;
541  }
542  /* --- BS --- */
543  else if (Buffer[i] == L'\b')
544  {
545  /* Only handle BS if we're not on the first pos of the first line */
546  if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y)
547  {
548  if (0 == Buff->CursorPosition.X)
549  {
550  /* slide virtual position up */
551  Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1;
552  Buff->CursorPosition.Y--;
553  UpdateRect.Top = min(UpdateRect.Top, Buff->CursorPosition.Y);
554  }
555  else
556  {
557  Buff->CursorPosition.X--;
558  }
559  Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
560  Ptr->Char.UnicodeChar = L' ';
561 
562  if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE)
563  {
564  /* Delete a full-width character */
565  Ptr->Attributes = Buff->ScreenDefaultAttrib;
566  if (Buff->CursorPosition.X > 0)
567  Buff->CursorPosition.X--;
568  Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
569  Ptr->Char.UnicodeChar = L' ';
570  }
571 
572  Ptr->Attributes = Buff->ScreenDefaultAttrib;
573  UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
574  UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
575  }
576  continue;
577  }
578  /* --- TAB --- */
579  else if (Buffer[i] == L'\t')
580  {
581  UINT EndX;
582 
583  UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
584  EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1);
585  EndX = min(EndX, (UINT)Buff->ScreenBufferSize.X);
586  Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
587  while ((UINT)Buff->CursorPosition.X < EndX)
588  {
589  Ptr->Char.UnicodeChar = L' ';
590  Ptr->Attributes = Buff->ScreenDefaultAttrib;
591  ++Ptr;
592  Buff->CursorPosition.X++;
593  }
594  UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1);
595  if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
596  {
597  if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
598  {
599  Buff->CursorPosition.X = 0;
600  ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
601  }
602  else
603  {
604  Buff->CursorPosition.X--;
605  }
606  }
607  continue;
608  }
609  /* --- BEL ---*/
610  else if (Buffer[i] == L'\a')
611  {
612  FrontEnd->Vtbl->RingBell(FrontEnd);
613  continue;
614  }
615  }
616  UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X);
617  UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X);
618 
619  /* For Chinese, Japanese and Korean */
620  if (bCJK && Buffer[i] >= 0x80 && mk_wcwidth_cjk(Buffer[i]) == 2)
621  {
622  /* Buffer[i] is a fullwidth character */
623 
624  if (Buff->CursorPosition.X > 0)
625  {
626  /* Kill the previous leading byte */
627  Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X - 1, Buff->CursorPosition.Y);
628  if (Ptr->Attributes & COMMON_LVB_LEADING_BYTE)
629  {
630  Ptr->Char.UnicodeChar = L' ';
631  if (Attrib)
632  Ptr->Attributes &= ~COMMON_LVB_LEADING_BYTE;
633  }
634  }
635 
636  if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X - 1)
637  {
638  /* New line */
639  if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
640  {
641  Buff->CursorPosition.X = 0;
642  ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
643  }
644  else
645  {
646  Buff->CursorPosition.X = CursorStartX;
647  }
648  }
649 
650  /* Set leading */
651  Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
652  Ptr->Char.UnicodeChar = Buffer[i];
653  if (Attrib)
654  Ptr->Attributes = Buff->ScreenDefaultAttrib | COMMON_LVB_LEADING_BYTE;
655 
656  /* Set trailing */
657  Buff->CursorPosition.X++;
658  Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
659  if (Attrib)
660  Ptr->Attributes = Buff->ScreenDefaultAttrib | COMMON_LVB_TRAILING_BYTE;
661  }
662  else
663  {
664  Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
665  Ptr->Char.UnicodeChar = Buffer[i];
666  if (Attrib)
667  Ptr->Attributes = Buff->ScreenDefaultAttrib;
668  }
669 
670  Buff->CursorPosition.X++;
671  if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X)
672  {
673  if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT)
674  {
675  Buff->CursorPosition.X = 0;
676  ConioNextLine(Buff, &UpdateRect, &ScrolledLines);
677  }
678  else
679  {
680  Buff->CursorPosition.X = CursorStartX;
681  }
682  }
683  }
684 
685  if (bCJK && Buff->CursorPosition.X > 0)
686  {
687  /* Delete trailing */
688  Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y);
689  if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE)
690  {
691  Ptr->Char.UnicodeChar = L' ';
692  if (Attrib)
693  Ptr->Attributes = Buff->ScreenDefaultAttrib;
694  }
695  }
696 
697  if (!ConioIsRectEmpty(&UpdateRect) && (PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer)
698  {
699  // TermWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY,
700  // ScrolledLines, Buffer, Length);
701  FrontEnd->Vtbl->WriteStream(FrontEnd,
702  &UpdateRect,
703  CursorStartX,
704  CursorStartY,
705  ScrolledLines,
706  Buffer,
707  Length);
708  }
709 
710  return STATUS_SUCCESS;
711 }
712 
713 
714 
715 static NTSTATUS NTAPI
718  PWCHAR Buffer,
719  DWORD Length,
720  BOOL Attrib)
721 {
722  PFRONTEND FrontEnd = This->Context;
723  return ConioWriteConsole(FrontEnd,
724  Buff,
725  Buffer,
726  Length,
727  Attrib);
728 }
729 
730 /************ Line discipline ***************/
731 
732 
733 
734 VOID
736 {
738  PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
739 
740  if (!ActiveBuffer) return;
741 
742  ConioInitRect(&Region, 0, 0,
743  ActiveBuffer->ViewSize.Y - 1,
744  ActiveBuffer->ViewSize.X - 1);
746  // Console->FrontEndIFace.Vtbl->DrawRegion(&Console->FrontEndIFace, &Region);
747 }
748 
749 static VOID NTAPI
752 {
753  PFRONTEND FrontEnd = This->Context;
754  FrontEnd->Vtbl->DrawRegion(FrontEnd, Region);
755 }
756 
757 static BOOL NTAPI
760 {
761  PFRONTEND FrontEnd = This->Context;
762  return FrontEnd->Vtbl->SetCursorInfo(FrontEnd, ScreenBuffer);
763 }
764 
765 static BOOL NTAPI
768  SHORT OldCursorX,
769  SHORT OldCursorY)
770 {
771  PFRONTEND FrontEnd = This->Context;
772  return FrontEnd->Vtbl->SetScreenInfo(FrontEnd,
773  ScreenBuffer,
774  OldCursorX,
775  OldCursorY);
776 }
777 
778 static VOID NTAPI
780 {
781  PFRONTEND FrontEnd = This->Context;
782  FrontEnd->Vtbl->ResizeTerminal(FrontEnd);
783 }
784 
785 static VOID NTAPI
787 {
788  PFRONTEND FrontEnd = This->Context;
789  FrontEnd->Vtbl->SetActiveScreenBuffer(FrontEnd);
790 }
791 
792 static VOID NTAPI
795 {
796  PFRONTEND FrontEnd = This->Context;
797  FrontEnd->Vtbl->ReleaseScreenBuffer(FrontEnd, ScreenBuffer);
798 }
799 
800 static VOID NTAPI
802  PCOORD pSize)
803 {
804  PFRONTEND FrontEnd = This->Context;
805  FrontEnd->Vtbl->GetLargestConsoleWindowSize(FrontEnd, pSize);
806 }
807 
808 static BOOL NTAPI
810  HPALETTE PaletteHandle,
811  UINT PaletteUsage)
812 {
813  PFRONTEND FrontEnd = This->Context;
814  return FrontEnd->Vtbl->SetPalette(FrontEnd, PaletteHandle, PaletteUsage);
815 }
816 
817 static INT NTAPI
819  BOOL Show)
820 {
821  PFRONTEND FrontEnd = This->Context;
822  return FrontEnd->Vtbl->ShowMouseCursor(FrontEnd, Show);
823 }
824 
826 {
829 
832 
842 };
843 
844 #if 0
845 VOID
847 {
848  if (!Console) return;
849 
850  /* Reinitialize the frontend interface */
851  RtlZeroMemory(&Console->FrontEndIFace, sizeof(Console->FrontEndIFace));
852  Console->FrontEndIFace.Vtbl = &ConSrvTermVtbl;
853 }
854 #endif
855 
856 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
#define IN
Definition: typedefs.h:38
#define max(a, b)
Definition: svc.c:63
VOID ClearLineBuffer(PTEXTMODE_SCREEN_BUFFER Buff)
Definition: text.c:148
#define TRUE
Definition: types.h:120
WCHAR UnicodeChar
Definition: wincon.h:230
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y)
Definition: text.c:142
char CHAR
Definition: xmlstorage.h:175
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
VOID ConioDrawConsole(PCONSRV_CONSOLE Console)
Definition: terminal.c:735
LONG NTSTATUS
Definition: precomp.h:26
#define ConsoleAllocHeap(Flags, Size)
Definition: heap.h:14
#define TermDrawRegion(Console, Region)
Definition: term.h:22
Definition: arc.h:84
static NTSTATUS NTAPI ConSrvTermWriteStream(IN OUT PTERMINAL This, PTEXTMODE_SCREEN_BUFFER Buff, PWCHAR Buffer, DWORD Length, BOOL Attrib)
Definition: terminal.c:716
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
static VOID ConioInputEventToUnicode(PCONSOLE Console, PINPUT_RECORD InputEvent)
Definition: coninput.c:68
uint16_t * PWCHAR
Definition: typedefs.h:54
static HPALETTE PaletteHandle
Definition: svga.c:215
_In_ PVOID Parameter
Definition: ldrtypes.h:241
#define PCONSRV_CONSOLE
Definition: conio.h:27
VOID LineInputKeyDown(PCONSRV_CONSOLE Console, PUNICODE_STRING ExeName, KEY_EVENT_RECORD *KeyEvent)
Definition: lineinput.c:166
static NTSTATUS NTAPI ConSrvTermReadStream(IN OUT PTERMINAL This, IN BOOLEAN Unicode, OUT PVOID Buffer, IN OUT PCONSOLE_READCONSOLE_CONTROL ReadControl, IN PVOID Parameter OPTIONAL, IN ULONG NumCharsToRead, OUT PULONG NumCharsRead OPTIONAL)
Definition: terminal.c:292
int32_t INT
Definition: typedefs.h:56
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
NTSTATUS NTAPI ConSrvInitTerminal(IN OUT PTERMINAL Terminal, IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN HANDLE ConsoleLeaderProcessHandle)
Definition: terminal.c:200
CHAR InputBuffer[80]
Definition: conmgr.c:33
struct _CONSRV_CONSOLE * Console
Definition: conio_winsrv.h:120
static VOID NTAPI ConSrvTermResizeTerminal(IN OUT PTERMINAL This)
Definition: terminal.c:779
NTSTATUS NTAPI GuiUnloadFrontEnd(IN OUT PFRONTEND FrontEnd)
Definition: guiterm.c:1307
static NTSTATUS ConioWriteConsole(PFRONTEND FrontEnd, PTEXTMODE_SCREEN_BUFFER Buff, PWCHAR Buffer, DWORD Length, BOOL Attrib)
Definition: terminal.c:496
static VOID ConioInputEventToAnsi(PCONSOLE Console, PINPUT_RECORD InputEvent)
Definition: coninput.c:55
NTSTATUS NTAPI GuiLoadFrontEnd(IN OUT PFRONTEND FrontEnd, IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN HANDLE ConsoleLeaderProcessHandle)
Definition: guiterm.c:1177
NTSTATUS(NTAPI * FRONTEND_LOAD)(IN OUT PFRONTEND FrontEnd, IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN HANDLE ConsoleLeaderProcessHandle)
Definition: terminal.c:108
static BOOL NTAPI ConSrvTermSetPalette(IN OUT PTERMINAL This, HPALETTE PaletteHandle, UINT PaletteUsage)
Definition: terminal.c:809
#define ENABLE_WRAP_AT_EOL_OUTPUT
Definition: blue.h:54
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
static NTSTATUS ConSrvUnloadFrontEnd(IN PFRONTEND FrontEnd)
Definition: terminal.c:189
unsigned int BOOL
Definition: ntddk_ex.h:94
short SHORT
Definition: pedump.c:59
#define KEY_EVENT
Definition: wincon.h:122
static VOID NTAPI ConSrvTermGetLargestConsoleWindowSize(IN OUT PTERMINAL This, PCOORD pSize)
Definition: terminal.c:801
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PVOID Context
Definition: conio_winsrv.h:121
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG X
Definition: bl.h:1340
static BOOL NTAPI ConSrvTermSetCursorInfo(IN OUT PTERMINAL This, PCONSOLE_SCREEN_BUFFER ScreenBuffer)
Definition: terminal.c:758
#define TAB_WIDTH
Definition: terminal.c:466
NTSTATUS(NTAPI * FRONTEND_UNLOAD)(IN OUT PFRONTEND FrontEnd)
Definition: terminal.c:114
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
int mk_wcwidth_cjk(wchar_t ucs)
Definition: wcwidth.c:230
NTSTATUS NTAPI ConSrvDeinitTerminal(IN OUT PTERMINAL Terminal)
Definition: terminal.c:233
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:263
unsigned long DWORD
Definition: ntddk_ex.h:95
static BOOL NTAPI ConSrvTermSetScreenInfo(IN OUT PTERMINAL This, PCONSOLE_SCREEN_BUFFER ScreenBuffer, SHORT OldCursorX, SHORT OldCursorY)
Definition: terminal.c:766
#define ENABLE_LINE_INPUT
Definition: wincon.h:76
PFRONTEND_VTBL Vtbl
Definition: conio_winsrv.h:117
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
CHAR FrontEndName[80]
Definition: terminal.c:136
#define ConsoleInputUnicodeCharToAnsiChar(Console, dChar, sWChar)
Definition: terminal.c:36
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static TERMINAL_VTBL ConSrvTermVtbl
Definition: terminal.c:197
FRONTEND_UNLOAD FrontEndUnload
Definition: terminal.c:138
static const WCHAR L[]
Definition: oid.c:1250
static VOID NTAPI ConSrvTermDeinitTerminal(IN OUT PTERMINAL This)
Definition: terminal.c:281
static NTSTATUS ConSrvLoadFrontEnd(IN OUT PFRONTEND FrontEnd, IN OUT PCONSOLE_STATE_INFO ConsoleInfo, IN OUT PCONSOLE_INIT_INFO ConsoleInitInfo, IN HANDLE ConsoleLeaderProcessHandle)
Definition: terminal.c:150
#define NTSTATUS
Definition: precomp.h:20
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: typedefs.h:117
Definition: bl.h:1338
#define ConioInitRect(Rect, top, left, bottom, right)
Definition: rect.h:20
Status
Definition: gdiplustypes.h:24
#define ENABLE_PROCESSED_OUTPUT
Definition: blue.h:53
static VOID ConioNextLine(PTEXTMODE_SCREEN_BUFFER Buff, PSMALL_RECT UpdateRect, PUINT ScrolledLines)
Definition: terminal.c:473
union _KEY_EVENT_RECORD::@3172 uChar
static VOID NTAPI ConSrvTermDrawRegion(IN OUT PTERMINAL This, SMALL_RECT *Region)
Definition: terminal.c:750
static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo
Definition: video.c:47
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
VOID ResetFrontEnd(IN PCONSOLE Console)
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
static VOID NTAPI ConSrvTermReleaseScreenBuffer(IN OUT PTERMINAL This, IN PCONSOLE_SCREEN_BUFFER ScreenBuffer)
Definition: terminal.c:793
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
static VOID NTAPI ConSrvTermSetActiveScreenBuffer(IN OUT PTERMINAL This)
Definition: terminal.c:786
CConsole Console
WORD EventType
Definition: wincon.h:261
#define DPRINT1
Definition: precomp.h:8
#define ConsoleFreeHeap(HeapBase)
Definition: heap.h:15
HANDLE ScreenBuffer
Definition: notevil.c:37
#define OUT
Definition: typedefs.h:39
#define COMMON_LVB_LEADING_BYTE
Definition: wincon.h:48
static INT NTAPI ConSrvTermShowMouseCursor(IN OUT PTERMINAL This, BOOL Show)
Definition: terminal.c:818
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
static int UpdateRect(TreeListData *pData, unsigned uItem, unsigned uSub)
Definition: treelist.c:1529
#define COMMON_LVB_TRAILING_BYTE
Definition: wincon.h:49
static struct @4157 FrontEndLoadingMethods[]
FRONTEND_LOAD FrontEndLoad
Definition: terminal.c:137
#define ConioIsRectEmpty(Rect)
Definition: rect.h:28
union _INPUT_RECORD::@3173 Event
#define ConsoleInputAnsiCharToUnicodeChar(Console, dWChar, sChar)
Definition: terminal.c:40
return STATUS_SUCCESS
Definition: btrfs.c:2938
ULONG Y
Definition: bl.h:1341
unsigned int * PUINT
Definition: ndis.h:50
static NTSTATUS NTAPI ConSrvTermInitTerminal(IN OUT PTERMINAL This, IN PCONSOLE Console)
Definition: terminal.c:256
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68