📄 hardware.c
字号:
/*++
Copyright (c) 1998-2001 Klaus P. Gerlicher
Module Name:
hardware.c
Abstract:
output to console
Environment:
Kernel mode only
Author:
Klaus P. Gerlicher
Revision History:
04-Aug-1998: created
15-Nov-2000: general cleanup of source files
Copyright notice:
This file may be distributed under the terms of the GNU Public License.
--*/
////////////////////////////////////////////////////
// INCLUDES
////
#include "remods.h"
#include "precomp.h"
////////////////////////////////////////////////////
// PROTOTYPES
////
////////////////////////////////////////////////////
// DEFINES
////
////////////////////////////////////////////////////
// GLOBALS
////
// flagging stuff
BOOLEAN bCursorEnabled = FALSE;
BOOLEAN bConsoleIsInitialized = FALSE;
// terminal emulation
ETERMINALMODE eTerminalMode = TERMINAL_MODE_NONE;
// window stuff
WINDOW wWindow[4];
// screen parameter
ULONG GLOBAL_SCREEN_WIDTH,GLOBAL_SCREEN_HEIGHT;
// jump table to real output functions
OUTPUT_HANDLERS ohandlers;
INPUT_HANDLERS ihandlers;
// ring buffer stuff
ULONG ulInPos = 0,ulLastPos = 0;
ULONG ulOldInPos = 0,ulOldDelta = 0;
BOOLEAN bSuspendPrintRingBuffer = FALSE;
char aBuffers[LINES_IN_BUFFER][1024];
// output lock
ULONG ulOutputLock;
// color of windows pane separation bars
USHORT usCaptionColor = BLUE;
USHORT usCaptionText = WHITE;
USHORT usForegroundColor = LTGRAY;
USHORT usBackgroundColor = BLACK;
USHORT usHiLiteColor = WHITE;
////////////////////////////////////////////////////
// FUNCTIONS
////
//*************************************************************************
// SuspendPrintRingBuffer()
//
//*************************************************************************
void SuspendPrintRingBuffer(BOOLEAN bSuspend)
{
ENTER_FUNC();
bSuspendPrintRingBuffer = bSuspend;
LEAVE_FUNC();
}
//*************************************************************************
// EmptyRingBuffer()
//
//*************************************************************************
void EmptyRingBuffer(void)
{
//ENTER_FUNC();
ulLastPos = ulInPos = ulOldInPos = ulOldDelta = 0;
PICE_memset(aBuffers,0,sizeof(aBuffers));
//LEAVE_FUNC();
}
//*************************************************************************
// LinesInRingBuffer()
//
//*************************************************************************
ULONG LinesInRingBuffer(void)
{
ULONG ulResult;
// ENTER_FUNC();
ulResult = (ulInPos-ulLastPos)%LINES_IN_BUFFER;
// LEAVE_FUNC();
return ulResult;
}
//*************************************************************************
// CheckRingBuffer()
//
//*************************************************************************
void CheckRingBuffer(void)
{
// ENTER_FUNC();
Acquire_Output_Lock();
if(ulInPos != ulOldInPos )
{
ulOldInPos = ulInPos;
PrintRingBuffer(wWindow[OUTPUT_WINDOW].cy-1);
}
Release_Output_Lock();
// LEAVE_FUNC();
}
//*************************************************************************
// AddToRingBuffer()
//
//*************************************************************************
BOOLEAN AddToRingBuffer(LPSTR p)
{
ULONG i,j,len;
BOOLEAN bHadReturn = FALSE;
char temp[sizeof(aBuffers[0])];
// ENTER_FUNC();
// size of current string
j=PICE_strlen(aBuffers[ulInPos]);
// start with ':' and current has ':' in front
if(aBuffers[ulInPos][0]==':' && *p==':')
{
if(j==1)
{
//LEAVE_FUNC();
return FALSE;
}
aBuffers[ulInPos][j++]='\n';
aBuffers[ulInPos][j]=0;
ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
// wrap around
if(ulInPos == ulLastPos)
{
ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
}
// reset to start of buffer
j = 0;
}
// it's an internal print ("pICE: ...")
else if(aBuffers[ulInPos][0]==':' && PICE_strncmpi(p,"pICE:",5)==0)
{
if(j==1)
{
PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
}
else
{
aBuffers[ulInPos][j++]='\n';
aBuffers[ulInPos][j]=0;
ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
// wrap around
if(ulInPos == ulLastPos)
{
ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
}
}
// reset to start of buffer
j = 0;
}
// it's a debug print and the current line is starting with ':'
else if(aBuffers[ulInPos][0]==':' &&
( (*p=='<' && PICE_isdigit(*(p+1)) && *(p+2)=='>') || bIsDebugPrint) )
{
if(j==1)
{
PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
}
else
{
aBuffers[ulInPos][j++]='\n';
aBuffers[ulInPos][j]=0;
ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
// wrap around
if(ulInPos == ulLastPos)
{
ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
}
}
// reset to start of buffer
j = 0;
}
// it's a debug print
else if(( (*p=='<' && PICE_isdigit(*(p+1)) && *(p+2)=='>') || bIsDebugPrint) )
{
p += 3;
}
// size of new string
len=PICE_strlen(p);
// if combined string length too big
// reduce to maximum
if( (len+j) > sizeof(aBuffers[0])-2 )
{
PICE_memcpy(temp,p,sizeof(aBuffers[0])-2);
p = temp;
// assume we end in NEWLINE
p[sizeof(aBuffers[0])-2]='\n';
p[sizeof(aBuffers[0])-1]=0;
}
for(i=0;p[i]!=0;i++)
{
// newline
if(p[i]=='\n')
{
aBuffers[ulInPos][j++]='\n';
aBuffers[ulInPos][j]=0;
ulInPos = (ulInPos+1)%LINES_IN_BUFFER;
// wrap around
if(ulInPos == ulLastPos)
{
ulLastPos = (ulLastPos+1)%LINES_IN_BUFFER;
PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
}
// reset to start of buffer
j = 0;
// notify that we had a NEWLINE
bHadReturn = TRUE;
}
// backspace
else if(p[i]=='\b')
{
if(j!=0)
{
j--;
aBuffers[ulInPos][j] = 0;
}
}
// TAB
else if(p[i]=='\t')
{
// copy TAB
aBuffers[ulInPos][j++] = p[i];
}
else
{
if((UCHAR)p[i]<0x20 && (UCHAR)p[i]>0x7f)
p[i]=0x20;
aBuffers[ulInPos][j++] = p[i];
}
}
// LEAVE_FUNC();
return bHadReturn;
}
//*************************************************************************
// ReplaceRingBufferCurrent()
//
//*************************************************************************
void ReplaceRingBufferCurrent(LPSTR s)
{
// ENTER_FUNC();
PICE_memset(aBuffers[ulInPos],0,sizeof(aBuffers[0]));
PICE_strcpy(aBuffers[ulInPos],s);
// LEAVE_FUNC();
}
//*************************************************************************
// PrintRingBuffer()
//
//*************************************************************************
void PrintRingBuffer(ULONG ulLines)
{
ULONG ulDelta = LinesInRingBuffer();
ULONG ulOutPos,i=0;
// ENTER_FUNC();
if(bSuspendPrintRingBuffer)
{
DPRINT((0,"PrintRingBuffer(): suspended\n"));
LEAVE_FUNC();
return;
}
if(!ulDelta)
{
DPRINT((0,"PrintRingBuffer(): no lines in ring buffer\n"));
LEAVE_FUNC();
return;
}
if(ulDelta<ulOldDelta)
{
DPRINT((0,"PrintRingBuffer(): lines already output\n"));
LEAVE_FUNC();
return;
}
ulOldDelta = ulDelta;
if(ulDelta < ulLines)
{
DPRINT((0,"PrintRingBuffer(): less lines than requested: ulDelta: %x, ulLines: %x\n", ulDelta, ulLines));
ulLines = ulDelta;
}
ulOutPos = (ulInPos-ulLines)%LINES_IN_BUFFER;
DPRINT((0,"PrintRingBuffer(): ulOutPos = %u\n",ulOutPos));
Home(OUTPUT_WINDOW);
while(ulLines--)
{
ClrLine(wWindow[OUTPUT_WINDOW].y+i);
Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
i++;
ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
}
if(aBuffers[ulOutPos][0]==':')
{
ClrLine(wWindow[OUTPUT_WINDOW].y+i);
Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
wWindow[OUTPUT_WINDOW].usCurX = 1;
}
// LEAVE_FUNC();
}
//*************************************************************************
// PrintRingBufferOffset()
//
//*************************************************************************
BOOLEAN PrintRingBufferOffset(ULONG ulLines,ULONG ulOffset)
{
ULONG ulLinesInRingBuffer = LinesInRingBuffer();
ULONG ulOutPos,i=0;
// ENTER_FUNC();
// no lines in ring buffer
if(!ulLinesInRingBuffer)
{
DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer is 0\n"));
LEAVE_FUNC();
return FALSE;
}
// more lines inc. offset to display than in ring buffer
if(ulLinesInRingBuffer < ulLines)
{
ulLines = ulLinesInRingBuffer;
}
if(ulLinesInRingBuffer < ulOffset+ulLines)
{
DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer < ulOffset+ulLines\n"));
LEAVE_FUNC();
return FALSE;
}
DPRINT((0,"PrintRingBufferOffset(): ulLinesInRingBuffer %u ulLines %u ulOffset %u\n",ulLinesInRingBuffer,ulLines,ulOffset));
ulOutPos = (ulInPos-ulOffset-ulLines)%LINES_IN_BUFFER;
DPRINT((0,"PrintRingBufferOffset(): ulOutPos = %u\n",ulOutPos));
if(ulOutPos == ulInPos)
{
DPRINT((0,"PrintRingBufferOffset(): ulOutPos == ulInPos\n"));
LEAVE_FUNC();
return FALSE;
}
// start to output upper left corner of window
Home(OUTPUT_WINDOW);
// while not end reached...
while(ulLines--)
{
ClrLine(wWindow[OUTPUT_WINDOW].y+i);
Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
i++;
ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
}
if(aBuffers[ulInPos][0]==':')
{
ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy-1);
wWindow[OUTPUT_WINDOW].usCurY = wWindow[OUTPUT_WINDOW].cy-1;
Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulInPos]);
wWindow[OUTPUT_WINDOW].usCurX = PICE_strlen(aBuffers[ulInPos])+1;
}
// LEAVE_FUNC();
return TRUE;
}
//*************************************************************************
// PrintRingBufferHome()
//
//*************************************************************************
BOOLEAN PrintRingBufferHome(ULONG ulLines)
{
ULONG ulDelta = LinesInRingBuffer();
ULONG ulOutPos,i=0;
// ENTER_FUNC();
// no lines in ring buffer
if(!ulDelta)
{
DPRINT((0,"PrintRingBufferHome(): no lines in ring buffer\n"));
LEAVE_FUNC();
return FALSE;
}
// more lines inc. offset to display than in ring buffer
if(ulDelta < ulLines)
{
ulLines = ulDelta;
}
// calc the start out position
ulOutPos = ulLastPos;
// start to output upper left corner of window
Home(OUTPUT_WINDOW);
// while not end reached...
while(ulLines--)
{
ClrLine(wWindow[OUTPUT_WINDOW].y+i);
Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulOutPos]);
i++;
ulOutPos = (ulOutPos+1)%LINES_IN_BUFFER;
}
if(aBuffers[ulInPos][0]==':')
{
ClrLine(wWindow[OUTPUT_WINDOW].y+wWindow[OUTPUT_WINDOW].cy-1);
wWindow[OUTPUT_WINDOW].usCurY = wWindow[OUTPUT_WINDOW].cy-1;
Print(OUTPUT_WINDOW_UNBUFFERED,aBuffers[ulInPos]);
wWindow[OUTPUT_WINDOW].usCurX = PICE_strlen(aBuffers[ulInPos])+1;
}
// LEAVE_FUNC();
return TRUE;
}
//*************************************************************************
// ResetColor()
//
//*************************************************************************
void ResetColor(void)
{
SetForegroundColor(COLOR_FOREGROUND);
SetBackgroundColor(COLOR_BACKGROUND);
}
// OUTPUT handlers
//*************************************************************************
// PrintGraf()
//
//*************************************************************************
void PrintGraf(ULONG x,ULONG y,UCHAR c)
{
ohandlers.PrintGraf(x,y,c);
}
//*************************************************************************
// Flush()
//
// Flush the stream of chars to PrintGraf()
//*************************************************************************
void Flush(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -