3 Copyright (c) 1998-2001 Klaus P. Gerlicher
24 15-Nov-2000: general cleanup of source files
28 This file may be distributed under the terms of the GNU Public License.
32 ////////////////////////////////////////////////////
38 ////////////////////////////////////////////////////
42 ////////////////////////////////////////////////////
46 ////////////////////////////////////////////////////
51 BOOLEAN bCursorEnabled
= FALSE
;
52 BOOLEAN bConsoleIsInitialized
= FALSE
;
56 ETERMINALMODE eTerminalMode
= TERMINAL_MODE_NONE
;
62 ULONG GLOBAL_SCREEN_WIDTH
,GLOBAL_SCREEN_HEIGHT
;
64 // jump table to real output functions
65 OUTPUT_HANDLERS ohandlers
;
66 INPUT_HANDLERS ihandlers
;
69 ULONG ulInPos
= 0,ulLastPos
= 0;
70 ULONG ulOldInPos
= 0,ulOldDelta
= 0;
71 BOOLEAN bSuspendPrintRingBuffer
= FALSE
;
73 char aBuffers
[LINES_IN_BUFFER
][1024];
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
;
85 ////////////////////////////////////////////////////
89 //*************************************************************************
90 // SuspendPrintRingBuffer()
92 //*************************************************************************
93 void SuspendPrintRingBuffer(BOOLEAN bSuspend
)
96 bSuspendPrintRingBuffer
= bSuspend
;
100 //*************************************************************************
103 //*************************************************************************
104 void EmptyRingBuffer(void)
107 ulLastPos
= ulInPos
= ulOldInPos
= ulOldDelta
= 0;
108 PICE_memset(aBuffers
,0,sizeof(aBuffers
));
112 //*************************************************************************
113 // LinesInRingBuffer()
115 //*************************************************************************
116 ULONG
LinesInRingBuffer(void)
122 ulResult
= (ulInPos
-ulLastPos
)%LINES_IN_BUFFER
;
129 //*************************************************************************
132 //*************************************************************************
133 void CheckRingBuffer(void)
137 Acquire_Output_Lock();
139 if(ulInPos
!= ulOldInPos
)
141 ulOldInPos
= ulInPos
;
142 PrintRingBuffer(wWindow
[OUTPUT_WINDOW
].cy
-1);
145 Release_Output_Lock();
150 //*************************************************************************
153 //*************************************************************************
154 BOOLEAN
AddToRingBuffer(LPSTR p
)
157 BOOLEAN bHadReturn
= FALSE
;
158 char temp
[sizeof(aBuffers
[0])];
162 // size of current string
163 j
=PICE_strlen(aBuffers
[ulInPos
]);
165 // start with ':' and current has ':' in front
166 if(aBuffers
[ulInPos
][0]==':' && *p
==':')
173 aBuffers
[ulInPos
][j
++]='\n';
174 aBuffers
[ulInPos
][j
]=0;
175 ulInPos
= (ulInPos
+1)%LINES_IN_BUFFER
;
177 if(ulInPos
== ulLastPos
)
179 ulLastPos
= (ulLastPos
+1)%LINES_IN_BUFFER
;
180 PICE_memset(aBuffers
[ulInPos
],0,sizeof(aBuffers
[0]));
182 // reset to start of buffer
185 // it's an internal print ("pICE: ...")
186 else if(aBuffers
[ulInPos
][0]==':' && PICE_strncmpi(p
,"pICE:",5)==0)
190 PICE_memset(aBuffers
[ulInPos
],0,sizeof(aBuffers
[0]));
194 aBuffers
[ulInPos
][j
++]='\n';
195 aBuffers
[ulInPos
][j
]=0;
196 ulInPos
= (ulInPos
+1)%LINES_IN_BUFFER
;
198 if(ulInPos
== ulLastPos
)
200 ulLastPos
= (ulLastPos
+1)%LINES_IN_BUFFER
;
201 PICE_memset(aBuffers
[ulInPos
],0,sizeof(aBuffers
[0]));
204 // reset to start of buffer
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
) )
213 PICE_memset(aBuffers
[ulInPos
],0,sizeof(aBuffers
[0]));
217 aBuffers
[ulInPos
][j
++]='\n';
218 aBuffers
[ulInPos
][j
]=0;
219 ulInPos
= (ulInPos
+1)%LINES_IN_BUFFER
;
221 if(ulInPos
== ulLastPos
)
223 ulLastPos
= (ulLastPos
+1)%LINES_IN_BUFFER
;
224 PICE_memset(aBuffers
[ulInPos
],0,sizeof(aBuffers
[0]));
227 // reset to start of buffer
230 // it's a debug print
231 else if(( (*p
=='<' && PICE_isdigit(*(p
+1)) && *(p
+2)=='>') || bIsDebugPrint
) )
236 // size of new string
239 // if combined string length too big
241 if( (len
+j
) > sizeof(aBuffers
[0])-2 )
243 PICE_memcpy(temp
,p
,sizeof(aBuffers
[0])-2);
245 // assume we end in NEWLINE
246 p
[sizeof(aBuffers
[0])-2]='\n';
247 p
[sizeof(aBuffers
[0])-1]=0;
255 aBuffers
[ulInPos
][j
++]='\n';
256 aBuffers
[ulInPos
][j
]=0;
257 ulInPos
= (ulInPos
+1)%LINES_IN_BUFFER
;
259 if(ulInPos
== ulLastPos
)
261 ulLastPos
= (ulLastPos
+1)%LINES_IN_BUFFER
;
262 PICE_memset(aBuffers
[ulInPos
],0,sizeof(aBuffers
[0]));
264 // reset to start of buffer
266 // notify that we had a NEWLINE
275 aBuffers
[ulInPos
][j
] = 0;
282 aBuffers
[ulInPos
][j
++] = p
[i
];
286 if((UCHAR
)p
[i
]<0x20 && (UCHAR
)p
[i
]>0x7f)
289 aBuffers
[ulInPos
][j
++] = p
[i
];
297 //*************************************************************************
298 // ReplaceRingBufferCurrent()
300 //*************************************************************************
301 void ReplaceRingBufferCurrent(LPSTR s
)
305 PICE_memset(aBuffers
[ulInPos
],0,sizeof(aBuffers
[0]));
306 PICE_strcpy(aBuffers
[ulInPos
],s
);
311 //*************************************************************************
314 //*************************************************************************
315 void PrintRingBuffer(ULONG ulLines
)
317 ULONG ulDelta
= LinesInRingBuffer();
322 if(bSuspendPrintRingBuffer
)
324 DPRINT((0,"PrintRingBuffer(): suspended\n"));
331 DPRINT((0,"PrintRingBuffer(): no lines in ring buffer\n"));
336 if(ulDelta
<ulOldDelta
)
338 DPRINT((0,"PrintRingBuffer(): lines already output\n"));
343 ulOldDelta
= ulDelta
;
345 if(ulDelta
< ulLines
)
347 DPRINT((0,"PrintRingBuffer(): less lines than requested: ulDelta: %x, ulLines: %x\n", ulDelta
, ulLines
));
351 ulOutPos
= (ulInPos
-ulLines
)%LINES_IN_BUFFER
;
352 DPRINT((0,"PrintRingBuffer(): ulOutPos = %u\n",ulOutPos
));
358 ClrLine(wWindow
[OUTPUT_WINDOW
].y
+i
);
359 Print(OUTPUT_WINDOW_UNBUFFERED
,aBuffers
[ulOutPos
]);
361 ulOutPos
= (ulOutPos
+1)%LINES_IN_BUFFER
;
364 if(aBuffers
[ulOutPos
][0]==':')
366 ClrLine(wWindow
[OUTPUT_WINDOW
].y
+i
);
367 Print(OUTPUT_WINDOW_UNBUFFERED
,aBuffers
[ulOutPos
]);
368 wWindow
[OUTPUT_WINDOW
].usCurX
= 1;
374 //*************************************************************************
375 // PrintRingBufferOffset()
377 //*************************************************************************
378 BOOLEAN
PrintRingBufferOffset(ULONG ulLines
,ULONG ulOffset
)
380 ULONG ulLinesInRingBuffer
= LinesInRingBuffer();
385 // no lines in ring buffer
386 if(!ulLinesInRingBuffer
)
388 DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer is 0\n"));
393 // more lines inc. offset to display than in ring buffer
394 if(ulLinesInRingBuffer
< ulLines
)
396 ulLines
= ulLinesInRingBuffer
;
399 if(ulLinesInRingBuffer
< ulOffset
+ulLines
)
401 DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer < ulOffset+ulLines\n"));
406 DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer %u ulLines %u ulOffset %u\n",ulLinesInRingBuffer
,ulLines
,ulOffset
));
408 ulOutPos
= (ulInPos
-ulOffset
-ulLines
)%LINES_IN_BUFFER
;
410 DPRINT((0,"PrintRingBufferOffset(): ulOutPos = %u\n",ulOutPos
));
412 if(ulOutPos
== ulInPos
)
414 DPRINT((0,"PrintRingBufferOffset(): ulOutPos == ulInPos\n"));
419 // start to output upper left corner of window
422 // while not end reached...
425 ClrLine(wWindow
[OUTPUT_WINDOW
].y
+i
);
426 Print(OUTPUT_WINDOW_UNBUFFERED
,aBuffers
[ulOutPos
]);
428 ulOutPos
= (ulOutPos
+1)%LINES_IN_BUFFER
;
431 if(aBuffers
[ulInPos
][0]==':')
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;
443 //*************************************************************************
444 // PrintRingBufferHome()
446 //*************************************************************************
447 BOOLEAN
PrintRingBufferHome(ULONG ulLines
)
449 ULONG ulDelta
= LinesInRingBuffer();
454 // no lines in ring buffer
457 DPRINT((0,"PrintRingBufferHome(): no lines in ring buffer\n"));
462 // more lines inc. offset to display than in ring buffer
463 if(ulDelta
< ulLines
)
468 // calc the start out position
469 ulOutPos
= ulLastPos
;
471 // start to output upper left corner of window
474 // while not end reached...
477 ClrLine(wWindow
[OUTPUT_WINDOW
].y
+i
);
478 Print(OUTPUT_WINDOW_UNBUFFERED
,aBuffers
[ulOutPos
]);
480 ulOutPos
= (ulOutPos
+1)%LINES_IN_BUFFER
;
483 if(aBuffers
[ulInPos
][0]==':')
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;
496 //*************************************************************************
499 //*************************************************************************
500 void ResetColor(void)
502 SetForegroundColor(COLOR_FOREGROUND
);
503 SetBackgroundColor(COLOR_BACKGROUND
);
508 //*************************************************************************
511 //*************************************************************************
512 void PrintGraf(ULONG x
,ULONG y
,UCHAR c
)
514 ohandlers
.PrintGraf(x
,y
,c
);
517 //*************************************************************************
520 // Flush the stream of chars to PrintGraf()
521 //*************************************************************************
528 //*************************************************************************
531 //*************************************************************************
532 void EnableScroll(USHORT Window
)
535 wWindow
[Window
].bScrollDisabled
=FALSE
;
539 //*************************************************************************
542 //*************************************************************************
543 void DisableScroll(USHORT Window
)
546 wWindow
[Window
].bScrollDisabled
=TRUE
;
551 //*************************************************************************
554 // show hardware cursor
555 //*************************************************************************
556 void ShowCursor(void)
558 ohandlers
.ShowCursor();
561 //*************************************************************************
564 // hide hardware cursor
565 //*************************************************************************
566 void HideCursor(void)
568 ohandlers
.HideCursor();
571 //*************************************************************************
572 // SetForegroundColor()
574 // set foreground color
575 //*************************************************************************
576 void SetForegroundColor(ECOLORS c
)
580 ohandlers
.SetForegroundColor(c
);
585 //*************************************************************************
586 // SetBackgroundColor()
588 // set background color
589 //*************************************************************************
590 void SetBackgroundColor(ECOLORS c
)
594 ohandlers
.SetBackgroundColor(c
);
599 //*************************************************************************
602 // put a zero terminated string at position (x,y)
603 //*************************************************************************
604 void PutChar(LPSTR p
,ULONG x
,ULONG y
)
610 Acquire_Output_Lock();
614 if((UCHAR
)p
[i
]>=0x20 && (UCHAR
)p
[i
]<0x80)
616 PrintGraf(x
+i
,y
,p
[i
]);
622 Release_Output_Lock();
627 //*************************************************************************
630 // copy a line from src to dest
631 //*************************************************************************
632 void CopyLineTo(USHORT dest
,USHORT src
)
634 ohandlers
.CopyLineTo(dest
,src
);
637 //*************************************************************************
640 // invert a line on the screen
641 //*************************************************************************
642 void InvertLine(ULONG line
)
644 ohandlers
.InvertLine(line
);
647 //*************************************************************************
650 // hatches a line on the screen
651 //*************************************************************************
652 void HatchLine(ULONG line
)
654 ohandlers
.HatchLine(line
);
657 //*************************************************************************
660 // clear a line on the screen
661 //*************************************************************************
662 void ClrLine(ULONG line
)
664 ohandlers
.ClrLine(line
);
667 //*************************************************************************
670 // Scroll a specific window up one line
671 //*************************************************************************
672 void ScrollUp(USHORT Window
)
678 if(!wWindow
[Window
].bScrollDisabled
)
680 for(i
=1;i
<wWindow
[Window
].cy
;i
++)
682 CopyLineTo((USHORT
)(wWindow
[Window
].y
+i
-1),(USHORT
)(wWindow
[Window
].y
+i
));
684 ClrLine((USHORT
)(wWindow
[Window
].y
+wWindow
[Window
].cy
-1));
688 //*************************************************************************
691 // cursor to home position
692 //*************************************************************************
693 void Home(USHORT Window
)
695 wWindow
[Window
].usCurX
=0;
696 wWindow
[Window
].usCurY
=0;
700 //*************************************************************************
703 // clear a specific window
704 //*************************************************************************
705 void Clear(USHORT Window
)
709 for(j
=0;j
<wWindow
[Window
].cy
;j
++)
711 ClrLine(wWindow
[Window
].y
+j
);
717 //*************************************************************************
720 //*************************************************************************
721 void PrintCaption(void)
723 const char title
[]=" PrivateICE system level debugger (REACTOS) ";
725 SetForegroundColor(COLOR_TEXT
);
726 SetBackgroundColor(COLOR_CAPTION
);
729 PutChar((LPSTR
)title
,
730 (GLOBAL_SCREEN_WIDTH
-sizeof(title
))/2,
736 //*************************************************************************
739 // print the screen template
740 //*************************************************************************
741 void PrintTemplate(void)
751 for(i
=wWindow
[j
].y
;i
<(wWindow
[j
].y
+wWindow
[j
].cy
);i
++)
759 SetForegroundColor(COLOR_TEXT
);
760 SetBackgroundColor(COLOR_CAPTION
);
762 ClrLine(wWindow
[DATA_WINDOW
].y
-1);
763 ClrLine(wWindow
[SOURCE_WINDOW
].y
-1);
764 ClrLine(wWindow
[OUTPUT_WINDOW
].y
-1);
774 //*************************************************************************
777 //*************************************************************************
778 void PrintLogo(BOOLEAN bShow
)
780 ohandlers
.PrintLogo(bShow
);
783 //*************************************************************************
786 // emulate a blinking cursor block
787 //*************************************************************************
788 void PrintCursor(BOOLEAN bForce
)
790 ohandlers
.PrintCursor(bForce
);
793 //*************************************************************************
796 //*************************************************************************
797 void Print(USHORT Window
,LPSTR p
)
804 if(!bConsoleIsInitialized
)
806 DPRINT((0,"Print(): console is not initialized!\n"));
812 // the OUTPUT_WINDOW is specially handled
813 if(Window
== OUTPUT_WINDOW
)
815 DPRINT((0,"Print(): OUTPUT_WINDOW\n"));
816 if(AddToRingBuffer(p
))
818 DPRINT((0,"Print(): checking ring buffer\n"));
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
]);
831 BOOLEAN bOutput
= TRUE
;
833 if(Window
== OUTPUT_WINDOW_UNBUFFERED
)
835 Window
= OUTPUT_WINDOW
;
840 if(wWindow
[Window
].usCurX
> (GLOBAL_SCREEN_WIDTH
-1))
846 wWindow
[Window
].usCurX
= 0;
847 wWindow
[Window
].usCurY
++;
848 if(wWindow
[Window
].usCurY
>=wWindow
[Window
].cy
)
850 wWindow
[Window
].usCurY
=wWindow
[Window
].cy
-1;
853 if(wWindow
[Window
].bScrollDisabled
==TRUE
)break;
858 if(wWindow
[Window
].usCurX
>0)
860 wWindow
[Window
].usCurX
--;
862 PrintGraf(wWindow
[Window
].usCurX
,wWindow
[Window
].y
+wWindow
[Window
].usCurY
,0x20);
869 if((wWindow
[Window
].usCurX
+ 4) < (GLOBAL_SCREEN_WIDTH
-1))
871 wWindow
[Window
].usCurX
+= 4;
876 if((UCHAR
)p
[i
]<0x20 && (UCHAR
)p
[i
]>0x7f)
880 PrintGraf(wWindow
[Window
].usCurX
,wWindow
[Window
].y
+wWindow
[Window
].usCurY
,p
[i
]);
882 wWindow
[Window
].usCurX
++;
893 //*************************************************************************
894 // SaveGraphicsState()
896 //*************************************************************************
897 void SaveGraphicsState(void)
899 ohandlers
.SaveGraphicsState();
902 //*************************************************************************
903 // RestoreGraphicsState()
905 //*************************************************************************
906 void RestoreGraphicsState(void)
908 ohandlers
.RestoreGraphicsState();
911 //*************************************************************************
912 // SetWindowGeometry()
914 //*************************************************************************
915 void SetWindowGeometry(PVOID pWindow
)
917 PICE_memcpy(wWindow
,pWindow
,sizeof(wWindow
));
922 //*************************************************************************
925 //*************************************************************************
926 UCHAR
GetKeyPolled(void)
928 return ihandlers
.GetKeyPolled();
931 //*************************************************************************
932 // FlushKeyboardQueue()
934 //*************************************************************************
935 void FlushKeyboardQueue(void)
937 ihandlers
.FlushKeyboardQueue();
941 //*************************************************************************
944 // init terminal screen
945 //*************************************************************************
946 BOOLEAN
ConsoleInit(void)
948 BOOLEAN bResult
= FALSE
;
952 // preset ohandlers and ihandler to NULL
953 PICE_memset((void*)&ohandlers
,0,sizeof(ohandlers
));
954 PICE_memset((void*)&ihandlers
,0,sizeof(ihandlers
));
956 switch(eTerminalMode
)
958 case TERMINAL_MODE_HERCULES_GRAPHICS
:
959 bResult
= ConsoleInitHercules();
961 case TERMINAL_MODE_HERCULES_TEXT
:
963 case TERMINAL_MODE_VGA_TEXT
:
964 bResult
= ConsoleInitVga();
966 case TERMINAL_MODE_SERIAL
:
967 bResult
= ConsoleInitSerial();
969 case TERMINAL_MODE_NONE
:
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
)
994 // check that inputhandlers were installed
995 if( !ihandlers
.GetKeyPolled
||
996 !ihandlers
.FlushKeyboardQueue
)
1003 bConsoleIsInitialized
= bResult
;
1008 //*************************************************************************
1009 // ConsoleShutdown()
1011 // exit terminal screen
1012 //*************************************************************************
1013 void ConsoleShutdown(void)
1017 // sleep for a few seconds
1018 KeStallExecutionProcessor(1000*5000);
1020 switch(eTerminalMode
)
1022 case TERMINAL_MODE_HERCULES_GRAPHICS
:
1023 ConsoleShutdownHercules();
1025 case TERMINAL_MODE_HERCULES_TEXT
:
1027 case TERMINAL_MODE_VGA_TEXT
:
1028 ConsoleShutdownVga();
1030 case TERMINAL_MODE_SERIAL
:
1031 ConsoleShutdownSerial();
1033 case TERMINAL_MODE_NONE
: