- Tree cleanups proposed on the mailing list. Move all non-Core OS modules to rosapps...
[reactos.git] / rosapps / sysutils / utils / pice / module / hardware.c
1 /*++
2
3 Copyright (c) 1998-2001 Klaus P. Gerlicher
4
5 Module Name:
6
7 hardware.c
8
9 Abstract:
10
11 output to console
12
13 Environment:
14
15 Kernel mode only
16
17 Author:
18
19 Klaus P. Gerlicher
20
21 Revision History:
22
23 04-Aug-1998: created
24 15-Nov-2000: general cleanup of source files
25
26 Copyright notice:
27
28 This file may be distributed under the terms of the GNU Public License.
29
30 --*/
31
32 ////////////////////////////////////////////////////
33 // INCLUDES
34 ////
35 #include "remods.h"
36 #include "precomp.h"
37
38 ////////////////////////////////////////////////////
39 // PROTOTYPES
40 ////
41
42 ////////////////////////////////////////////////////
43 // DEFINES
44 ////
45
46 ////////////////////////////////////////////////////
47 // GLOBALS
48 ////
49
50 // flagging stuff
51 BOOLEAN bCursorEnabled = FALSE;
52 BOOLEAN bConsoleIsInitialized = FALSE;
53
54
55 // terminal emulation
56 ETERMINALMODE eTerminalMode = TERMINAL_MODE_NONE;
57
58 // window stuff
59 WINDOW wWindow[4];
60
61 // screen parameter
62 ULONG GLOBAL_SCREEN_WIDTH,GLOBAL_SCREEN_HEIGHT;
63
64 // jump table to real output functions
65 OUTPUT_HANDLERS ohandlers;
66 INPUT_HANDLERS ihandlers;
67
68 // ring buffer stuff
69 ULONG ulInPos = 0,ulLastPos = 0;
70 ULONG ulOldInPos = 0,ulOldDelta = 0;
71 BOOLEAN bSuspendPrintRingBuffer = FALSE;
72
73 char aBuffers[LINES_IN_BUFFER][1024];
74
75 // output lock
76 ULONG ulOutputLock;
77
78 // color of windows pane separation bars
79 USHORT usCaptionColor = BLUE;
80 USHORT usCaptionText = WHITE;
81 USHORT usForegroundColor = LTGRAY;
82 USHORT usBackgroundColor = BLACK;
83 USHORT usHiLiteColor = WHITE;
84
85 ////////////////////////////////////////////////////
86 // FUNCTIONS
87 ////
88
89 //*************************************************************************
90 // SuspendPrintRingBuffer()
91 //
92 //*************************************************************************
93 void SuspendPrintRingBuffer(BOOLEAN bSuspend)
94 {
95 ENTER_FUNC();
96 bSuspendPrintRingBuffer = bSuspend;
97 LEAVE_FUNC();
98 }
99
100 //*************************************************************************
101 // EmptyRingBuffer()
102 //
103 //*************************************************************************
104 void EmptyRingBuffer(void)
105 {
106 //ENTER_FUNC();
107 ulLastPos = ulInPos = ulOldInPos = ulOldDelta = 0;
108 PICE_memset(aBuffers,0,sizeof(aBuffers));
109 //LEAVE_FUNC();
110 }
111
112 //*************************************************************************
113 // LinesInRingBuffer()
114 //
115 //*************************************************************************
116 ULONG LinesInRingBuffer(void)
117 {
118 ULONG ulResult;
119
120 // ENTER_FUNC();
121
122 ulResult = (ulInPos-ulLastPos)%LINES_IN_BUFFER;
123
124 // LEAVE_FUNC();
125
126 return ulResult;
127 }
128
129 //*************************************************************************
130 // CheckRingBuffer()
131 //
132 //*************************************************************************
133 void CheckRingBuffer(void)
134 {
135 // ENTER_FUNC();
136
137 Acquire_Output_Lock();
138
139 if(ulInPos != ulOldInPos )
140 {
141 ulOldInPos = ulInPos;
142 PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
143 }
144
145 Release_Output_Lock();
146
147 // LEAVE_FUNC();
148 }
149
150 //*************************************************************************
151 // AddToRingBuffer()
152 //
153 //*************************************************************************
154 BOOLEAN AddToRingBuffer(LPSTR p)
155 {
156 ULONG i,j,len;
157 BOOLEAN bHadReturn = FALSE;
158 char temp[sizeof(aBuffers[0])];
159
160 // ENTER_FUNC();
161
162 // size of current string
163 j=PICE_strlen(aBuffers[ulInPos]);
164
165 // start with ':' and current has ':' in front
166 if(aBuffers[ulInPos][0]==':' && *p==':')
167 {
168 if(j==1)
169 {
170 //LEAVE_FUNC();
171 return FALSE;
172 }
173 aBuffers[ulInPos][j++]='\n';
174 aBuffers[ulInPos][j]=0;
175 ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
176 // wrap around
177 if(ulInPos == ulLastPos)
178 {
179 ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
180 PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
181 }
182 // reset to start of buffer
183 j = 0;
184 }
185 // it's an internal print ("pICE: ...")
186 else if(aBuffers[ulInPos][0]==':' && PICE_strncmpi(p,"pICE:",5)==0)
187 {
188 if(j==1)
189 {
190 PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
191 }
192 else
193 {
194 aBuffers[ulInPos][j++]='\n';
195 aBuffers[ulInPos][j]=0;
196 ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
197 // wrap around
198 if(ulInPos == ulLastPos)
199 {
200 ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
201 PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
202 }
203 }
204 // reset to start of buffer
205 j = 0;
206 }
207 // it's a debug print and the current line is starting with ':'
208 else if(aBuffers[ulInPos][0]==':' &&
209 ( (*p=='<' && PICE_isdigit(*(p+1)) && *(p+2)=='>') || bIsDebugPrint) )
210 {
211 if(j==1)
212 {
213 PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
214 }
215 else
216 {
217 aBuffers[ulInPos][j++]='\n';
218 aBuffers[ulInPos][j]=0;
219 ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
220 // wrap around
221 if(ulInPos == ulLastPos)
222 {
223 ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
224 PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
225 }
226 }
227 // reset to start of buffer
228 j = 0;
229 }
230 // it's a debug print
231 else if(( (*p=='<' && PICE_isdigit(*(p+1)) && *(p+2)=='>') || bIsDebugPrint) )
232 {
233 p += 3;
234 }
235
236 // size of new string
237 len=PICE_strlen(p);
238
239 // if combined string length too big
240 // reduce to maximum
241 if( (len+j) > sizeof(aBuffers[0])-2 )
242 {
243 PICE_memcpy(temp,p,sizeof(aBuffers[0])-2);
244 p = temp;
245 // assume we end in NEWLINE
246 p[sizeof(aBuffers[0])-2]='\n';
247 p[sizeof(aBuffers[0])-1]=0;
248 }
249
250 for(i=0;p[i]!=0;i++)
251 {
252 // newline
253 if(p[i]=='\n')
254 {
255 aBuffers[ulInPos][j++]='\n';
256 aBuffers[ulInPos][j]=0;
257 ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
258 // wrap around
259 if(ulInPos == ulLastPos)
260 {
261 ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
262 PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
263 }
264 // reset to start of buffer
265 j = 0;
266 // notify that we had a NEWLINE
267 bHadReturn = TRUE;
268 }
269 // backspace
270 else if(p[i]=='\b')
271 {
272 if(j!=0)
273 {
274 j--;
275 aBuffers[ulInPos][j] = 0;
276 }
277 }
278 // TAB
279 else if(p[i]=='\t')
280 {
281 // copy TAB
282 aBuffers[ulInPos][j++] = p[i];
283 }
284 else
285 {
286 if((UCHAR)p[i]<0x20 && (UCHAR)p[i]>0x7f)
287 p[i]=0x20;
288
289 aBuffers[ulInPos][j++] = p[i];
290 }
291 }
292 // LEAVE_FUNC();
293
294 return bHadReturn;
295 }
296
297 //*************************************************************************
298 // ReplaceRingBufferCurrent()
299 //
300 //*************************************************************************
301 void ReplaceRingBufferCurrent(LPSTR s)
302 {
303 // ENTER_FUNC();
304
305 PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
306 PICE_strcpy(aBuffers[ulInPos],s);
307
308 // LEAVE_FUNC();
309 }
310
311 //*************************************************************************
312 // PrintRingBuffer()
313 //
314 //*************************************************************************
315 void PrintRingBuffer(ULONG ulLines)
316 {
317 ULONG ulDelta = LinesInRingBuffer();
318 ULONG ulOutPos,i=0;
319
320 // ENTER_FUNC();
321
322 if(bSuspendPrintRingBuffer)
323 {
324 DPRINT((0,"PrintRingBuffer(): suspended\n"));
325 LEAVE_FUNC();
326 return;
327 }
328
329 if(!ulDelta)
330 {
331 DPRINT((0,"PrintRingBuffer(): no lines in ring buffer\n"));
332 LEAVE_FUNC();
333 return;
334 }
335
336 if(ulDelta<ulOldDelta)
337 {
338 DPRINT((0,"PrintRingBuffer(): lines already output\n"));
339 LEAVE_FUNC();
340 return;
341 }
342
343 ulOldDelta = ulDelta;
344
345 if(ulDelta < ulLines)
346 {
347 DPRINT((0,"PrintRingBuffer(): less lines than requested: ulDelta: %x, ulLines: %x\n", ulDelta, ulLines));
348 ulLines = ulDelta;
349 }
350
351 ulOutPos = (ulInPos-ulLines)%LINES_IN_BUFFER;
352 DPRINT((0,"PrintRingBuffer(): ulOutPos = %u\n",ulOutPos));
353
354 Home(OUTPUT_WINDOW);
355
356 while(ulLines--)
357 {
358 ClrLine(wWindow[OUTPUT_WINDOW].y+i);
359 Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
360 i++;
361 ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
362 }
363
364 if(aBuffers[ulOutPos][0]==':')
365 {
366 ClrLine(wWindow[OUTPUT_WINDOW].y+i);
367 Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
368 wWindow[OUTPUT_WINDOW].usCurX = 1;
369 }
370
371 // LEAVE_FUNC();
372 }
373
374 //*************************************************************************
375 // PrintRingBufferOffset()
376 //
377 //*************************************************************************
378 BOOLEAN PrintRingBufferOffset(ULONG ulLines,ULONG ulOffset)
379 {
380 ULONG ulLinesInRingBuffer = LinesInRingBuffer();
381 ULONG ulOutPos,i=0;
382
383 // ENTER_FUNC();
384
385 // no lines in ring buffer
386 if(!ulLinesInRingBuffer)
387 {
388 DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer is 0\n"));
389 LEAVE_FUNC();
390 return FALSE;
391 }
392
393 // more lines inc. offset to display than in ring buffer
394 if(ulLinesInRingBuffer < ulLines)
395 {
396 ulLines = ulLinesInRingBuffer;
397 }
398
399 if(ulLinesInRingBuffer < ulOffset+ulLines)
400 {
401 DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer < ulOffset+ulLines\n"));
402 LEAVE_FUNC();
403 return FALSE;
404 }
405
406 DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer %u ulLines %u ulOffset %u\n",ulLinesInRingBuffer,ulLines,ulOffset));
407
408 ulOutPos = (ulInPos-ulOffset-ulLines)%LINES_IN_BUFFER;
409
410 DPRINT((0,"PrintRingBufferOffset(): ulOutPos = %u\n",ulOutPos));
411
412 if(ulOutPos == ulInPos)
413 {
414 DPRINT((0,"PrintRingBufferOffset(): ulOutPos == ulInPos\n"));
415 LEAVE_FUNC();
416 return FALSE;
417 }
418
419 // start to output upper left corner of window
420 Home(OUTPUT_WINDOW);
421
422 // while not end reached...
423 while(ulLines--)
424 {
425 ClrLine(wWindow[OUTPUT_WINDOW].y+i);
426 Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
427 i++;
428 ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
429 }
430
431 if(aBuffers[ulInPos][0]==':')
432 {
433 ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy-1);
434 wWindow[OUTPUT_WINDOW].usCurY = wWindow[OUTPUT_WINDOW].cy-1;
435 Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulInPos]);
436 wWindow[OUTPUT_WINDOW].usCurX = PICE_strlen(aBuffers[ulInPos])+1;
437 }
438
439 // LEAVE_FUNC();
440 return TRUE;
441 }
442
443 //*************************************************************************
444 // PrintRingBufferHome()
445 //
446 //*************************************************************************
447 BOOLEAN PrintRingBufferHome(ULONG ulLines)
448 {
449 ULONG ulDelta = LinesInRingBuffer();
450 ULONG ulOutPos,i=0;
451
452 // ENTER_FUNC();
453
454 // no lines in ring buffer
455 if(!ulDelta)
456 {
457 DPRINT((0,"PrintRingBufferHome(): no lines in ring buffer\n"));
458 LEAVE_FUNC();
459 return FALSE;
460 }
461
462 // more lines inc. offset to display than in ring buffer
463 if(ulDelta < ulLines)
464 {
465 ulLines = ulDelta;
466 }
467
468 // calc the start out position
469 ulOutPos = ulLastPos;
470
471 // start to output upper left corner of window
472 Home(OUTPUT_WINDOW);
473
474 // while not end reached...
475 while(ulLines--)
476 {
477 ClrLine(wWindow[OUTPUT_WINDOW].y+i);
478 Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
479 i++;
480 ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
481 }
482
483 if(aBuffers[ulInPos][0]==':')
484 {
485 ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy-1);
486 wWindow[OUTPUT_WINDOW].usCurY = wWindow[OUTPUT_WINDOW].cy-1;
487 Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulInPos]);
488 wWindow[OUTPUT_WINDOW].usCurX = PICE_strlen(aBuffers[ulInPos])+1;
489 }
490
491 // LEAVE_FUNC();
492
493 return TRUE;
494 }
495
496 //*************************************************************************
497 // ResetColor()
498 //
499 //*************************************************************************
500 void ResetColor(void)
501 {
502 SetForegroundColor(COLOR_FOREGROUND);
503 SetBackgroundColor(COLOR_BACKGROUND);
504 }
505
506 // OUTPUT handlers
507
508 //*************************************************************************
509 // PrintGraf()
510 //
511 //*************************************************************************
512 void PrintGraf(ULONG x,ULONG y,UCHAR c)
513 {
514 ohandlers.PrintGraf(x,y,c);
515 }
516
517 //*************************************************************************
518 // Flush()
519 //
520 // Flush the stream of chars to PrintGraf()
521 //*************************************************************************
522 void Flush(void)
523 {
524 if(ohandlers.Flush)
525 ohandlers.Flush();
526 }
527
528 //*************************************************************************
529 // EnableScroll()
530 //
531 //*************************************************************************
532 void EnableScroll(USHORT Window)
533 {
534 ENTER_FUNC();
535 wWindow[Window].bScrollDisabled=FALSE;
536 LEAVE_FUNC();
537 }
538
539 //*************************************************************************
540 // DisableScroll()
541 //
542 //*************************************************************************
543 void DisableScroll(USHORT Window)
544 {
545 ENTER_FUNC();
546 wWindow[Window].bScrollDisabled=TRUE;
547 LEAVE_FUNC();
548 }
549
550
551 //*************************************************************************
552 // ShowCursor()
553 //
554 // show hardware cursor
555 //*************************************************************************
556 void ShowCursor(void)
557 {
558 ohandlers.ShowCursor();
559 }
560
561 //*************************************************************************
562 // HideCursor()
563 //
564 // hide hardware cursor
565 //*************************************************************************
566 void HideCursor(void)
567 {
568 ohandlers.HideCursor();
569 }
570
571 //*************************************************************************
572 // SetForegroundColor()
573 //
574 // set foreground color
575 //*************************************************************************
576 void SetForegroundColor(ECOLORS c)
577 {
578 // ENTER_FUNC();
579
580 ohandlers.SetForegroundColor(c);
581
582 // LEAVE_FUNC();
583 }
584
585 //*************************************************************************
586 // SetBackgroundColor()
587 //
588 // set background color
589 //*************************************************************************
590 void SetBackgroundColor(ECOLORS c)
591 {
592 // ENTER_FUNC();
593
594 ohandlers.SetBackgroundColor(c);
595
596 // LEAVE_FUNC();
597 }
598
599 //*************************************************************************
600 // PutChar()
601 //
602 // put a zero terminated string at position (x,y)
603 //*************************************************************************
604 void PutChar(LPSTR p,ULONG x,ULONG y)
605 {
606 ULONG i;
607
608 // ENTER_FUNC();
609
610 Acquire_Output_Lock();
611
612 for(i=0;p[i]!=0;i++)
613 {
614 if((UCHAR)p[i]>=0x20 && (UCHAR)p[i]<0x80)
615 {
616 PrintGraf(x+i,y,p[i]);
617 }
618 }
619
620 Flush();
621
622 Release_Output_Lock();
623
624 // LEAVE_FUNC();
625 }
626
627 //*************************************************************************
628 // CopyLineTo()
629 //
630 // copy a line from src to dest
631 //*************************************************************************
632 void CopyLineTo(USHORT dest,USHORT src)
633 {
634 ohandlers.CopyLineTo(dest,src);
635 }
636
637 //*************************************************************************
638 // InvertLine()
639 //
640 // invert a line on the screen
641 //*************************************************************************
642 void InvertLine(ULONG line)
643 {
644 ohandlers.InvertLine(line);
645 }
646
647 //*************************************************************************
648 // HatchLine()
649 //
650 // hatches a line on the screen
651 //*************************************************************************
652 void HatchLine(ULONG line)
653 {
654 ohandlers.HatchLine(line);
655 }
656
657 //*************************************************************************
658 // ClrLine()
659 //
660 // clear a line on the screen
661 //*************************************************************************
662 void ClrLine(ULONG line)
663 {
664 ohandlers.ClrLine(line);
665 }
666
667 //*************************************************************************
668 // ScrollUp()
669 //
670 // Scroll a specific window up one line
671 //*************************************************************************
672 void ScrollUp(USHORT Window)
673 {
674 USHORT i;
675
676 return;
677
678 if(!wWindow[Window].bScrollDisabled)
679 {
680 for(i=1;i<wWindow[Window].cy;i++)
681 {
682 CopyLineTo((USHORT)(wWindow[Window].y+i-1),(USHORT)(wWindow[Window].y+i));
683 }
684 ClrLine((USHORT)(wWindow[Window].y+wWindow[Window].cy-1));
685 }
686 }
687
688 //*************************************************************************
689 // Home()
690 //
691 // cursor to home position
692 //*************************************************************************
693 void Home(USHORT Window)
694 {
695 wWindow[Window].usCurX=0;
696 wWindow[Window].usCurY=0;
697
698 }
699
700 //*************************************************************************
701 // Clear()
702 //
703 // clear a specific window
704 //*************************************************************************
705 void Clear(USHORT Window)
706 {
707 ULONG j;
708
709 for(j=0;j<wWindow[Window].cy;j++)
710 {
711 ClrLine(wWindow[Window].y+j);
712 }
713
714 Home(Window);
715 }
716
717 //*************************************************************************
718 // PrintCaption()
719 //
720 //*************************************************************************
721 void PrintCaption(void)
722 {
723 const char title[]=" PrivateICE system level debugger (REACTOS) ";
724
725 SetForegroundColor(COLOR_TEXT);
726 SetBackgroundColor(COLOR_CAPTION);
727
728 ClrLine(0);
729 PutChar((LPSTR)title,
730 (GLOBAL_SCREEN_WIDTH-sizeof(title))/2,
731 0);
732
733 ResetColor();
734 }
735
736 //*************************************************************************
737 // PrintTemplate()
738 //
739 // print the screen template
740 //*************************************************************************
741 void PrintTemplate(void)
742 {
743 USHORT i,j;
744
745 ENTER_FUNC();
746
747 ResetColor();
748
749 for(j=0;j<4;j++)
750 {
751 for(i=wWindow[j].y;i<(wWindow[j].y+wWindow[j].cy);i++)
752 {
753 ClrLine(i);
754 }
755 }
756
757 PrintCaption();
758
759 SetForegroundColor(COLOR_TEXT);
760 SetBackgroundColor(COLOR_CAPTION);
761
762 ClrLine(wWindow[DATA_WINDOW].y-1);
763 ClrLine(wWindow[SOURCE_WINDOW].y-1);
764 ClrLine(wWindow[OUTPUT_WINDOW].y-1);
765
766 ResetColor();
767
768 ShowRunningMsg();
769 PrintLogo(TRUE);
770
771 LEAVE_FUNC();
772 }
773
774 //*************************************************************************
775 // PrintLogo()
776 //
777 //*************************************************************************
778 void PrintLogo(BOOLEAN bShow)
779 {
780 ohandlers.PrintLogo(bShow);
781 }
782
783 //*************************************************************************
784 // PrintCursor()
785 //
786 // emulate a blinking cursor block
787 //*************************************************************************
788 void PrintCursor(BOOLEAN bForce)
789 {
790 ohandlers.PrintCursor(bForce);
791 }
792
793 //*************************************************************************
794 // Print()
795 //
796 //*************************************************************************
797 void Print(USHORT Window,LPSTR p)
798 {
799 ULONG i;
800
801 DPRINT((11,"%s",p));
802
803 //ENTER_FUNC();
804 if(!bConsoleIsInitialized)
805 {
806 DPRINT((0,"Print(): console is not initialized!\n"));
807 //LEAVE_FUNC();
808 return;
809 }
810
811
812 // the OUTPUT_WINDOW is specially handled
813 if(Window == OUTPUT_WINDOW)
814 {
815 DPRINT((0,"Print(): OUTPUT_WINDOW\n"));
816 if(AddToRingBuffer(p))
817 {
818 DPRINT((0,"Print(): checking ring buffer\n"));
819 CheckRingBuffer();
820 }
821 else
822 {
823 DPRINT((0,"Print(): outputting a line from ring buffer\n"));
824 wWindow[OUTPUT_WINDOW].usCurX = 0;
825 ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].usCurY);
826 Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulInPos]);
827 }
828 }
829 else
830 {
831 BOOLEAN bOutput = TRUE;
832
833 if(Window == OUTPUT_WINDOW_UNBUFFERED)
834 {
835 Window = OUTPUT_WINDOW;
836 }
837
838 for(i=0;p[i]!=0;i++)
839 {
840 if(wWindow[Window].usCurX > (GLOBAL_SCREEN_WIDTH-1))
841 bOutput = FALSE;
842
843 // newline
844 if(p[i]=='\n')
845 {
846 wWindow[Window].usCurX = 0;
847 wWindow[Window].usCurY++;
848 if(wWindow[Window].usCurY>=wWindow[Window].cy)
849 {
850 wWindow[Window].usCurY=wWindow[Window].cy-1;
851 ScrollUp(Window);
852 }
853 if(wWindow[Window].bScrollDisabled==TRUE)break;
854 }
855 // backspace
856 else if(p[i]=='\b')
857 {
858 if(wWindow[Window].usCurX>0)
859 {
860 wWindow[Window].usCurX--;
861 if(bOutput)
862 PrintGraf(wWindow[Window].usCurX,wWindow[Window].y+wWindow[Window].usCurY,0x20);
863 }
864
865 }
866 // TAB
867 else if(p[i]=='\t')
868 {
869 if((wWindow[Window].usCurX + 4) < (GLOBAL_SCREEN_WIDTH-1))
870 {
871 wWindow[Window].usCurX += 4;
872 }
873 }
874 else
875 {
876 if((UCHAR)p[i]<0x20 && (UCHAR)p[i]>0x7f)
877 p[i]=0x20;
878
879 if(bOutput)
880 PrintGraf(wWindow[Window].usCurX,wWindow[Window].y+wWindow[Window].usCurY,p[i]);
881
882 wWindow[Window].usCurX++;
883 }
884 }
885
886 // flush
887 Flush();
888 }
889 //LEAVE_FUNC();
890 }
891
892
893 //*************************************************************************
894 // SaveGraphicsState()
895 //
896 //*************************************************************************
897 void SaveGraphicsState(void)
898 {
899 ohandlers.SaveGraphicsState();
900 }
901
902 //*************************************************************************
903 // RestoreGraphicsState()
904 //
905 //*************************************************************************
906 void RestoreGraphicsState(void)
907 {
908 ohandlers.RestoreGraphicsState();
909 }
910
911 //*************************************************************************
912 // SetWindowGeometry()
913 //
914 //*************************************************************************
915 void SetWindowGeometry(PVOID pWindow)
916 {
917 PICE_memcpy(wWindow,pWindow,sizeof(wWindow));
918 }
919
920 // INPUT handlers
921
922 //*************************************************************************
923 // GetKeyPolled()
924 //
925 //*************************************************************************
926 UCHAR GetKeyPolled(void)
927 {
928 return ihandlers.GetKeyPolled();
929 }
930
931 //*************************************************************************
932 // FlushKeyboardQueue()
933 //
934 //*************************************************************************
935 void FlushKeyboardQueue(void)
936 {
937 ihandlers.FlushKeyboardQueue();
938 }
939
940
941 //*************************************************************************
942 // ConsoleInit()
943 //
944 // init terminal screen
945 //*************************************************************************
946 BOOLEAN ConsoleInit(void)
947 {
948 BOOLEAN bResult = FALSE;
949
950 ENTER_FUNC();
951
952 // preset ohandlers and ihandler to NULL
953 PICE_memset((void*)&ohandlers,0,sizeof(ohandlers));
954 PICE_memset((void*)&ihandlers,0,sizeof(ihandlers));
955
956 switch(eTerminalMode)
957 {
958 case TERMINAL_MODE_HERCULES_GRAPHICS:
959 bResult = ConsoleInitHercules();
960 break;
961 case TERMINAL_MODE_HERCULES_TEXT:
962 break;
963 case TERMINAL_MODE_VGA_TEXT:
964 bResult = ConsoleInitVga();
965 break;
966 case TERMINAL_MODE_SERIAL:
967 bResult = ConsoleInitSerial();
968 break;
969 case TERMINAL_MODE_NONE:
970 default:
971 // fail
972 break;
973 }
974
975 // check that outputhandlers have all been set
976 // ohandlers.Flush may be zero on return
977 if( !ohandlers.ClrLine ||
978 !ohandlers.CopyLineTo ||
979 !ohandlers.HatchLine ||
980 !ohandlers.HideCursor ||
981 !ohandlers.InvertLine ||
982 !ohandlers.PrintCursor ||
983 !ohandlers.PrintGraf ||
984 !ohandlers.PrintLogo ||
985 !ohandlers.RestoreGraphicsState ||
986 !ohandlers.SaveGraphicsState ||
987 !ohandlers.SetBackgroundColor ||
988 !ohandlers.SetForegroundColor ||
989 !ohandlers.ShowCursor)
990 {
991 bResult = FALSE;
992 }
993
994 // check that inputhandlers were installed
995 if( !ihandlers.GetKeyPolled ||
996 !ihandlers.FlushKeyboardQueue)
997 {
998 bResult = FALSE;
999 }
1000
1001 LEAVE_FUNC();
1002
1003 bConsoleIsInitialized = bResult;
1004
1005 return bResult;
1006 }
1007
1008 //*************************************************************************
1009 // ConsoleShutdown()
1010 //
1011 // exit terminal screen
1012 //*************************************************************************
1013 void ConsoleShutdown(void)
1014 {
1015 ENTER_FUNC();
1016
1017 // sleep for a few seconds
1018 KeStallExecutionProcessor(1000*5000);
1019
1020 switch(eTerminalMode)
1021 {
1022 case TERMINAL_MODE_HERCULES_GRAPHICS:
1023 ConsoleShutdownHercules();
1024 break;
1025 case TERMINAL_MODE_HERCULES_TEXT:
1026 break;
1027 case TERMINAL_MODE_VGA_TEXT:
1028 ConsoleShutdownVga();
1029 break;
1030 case TERMINAL_MODE_SERIAL:
1031 ConsoleShutdownSerial();
1032 break;
1033 case TERMINAL_MODE_NONE:
1034 default:
1035 // fail
1036 break;
1037 }
1038
1039 LEAVE_FUNC();
1040 }
1041
1042 // EOF