git-svn-id: svn://svn.code.sf.net/p/bitchx/code/tags/ircii-pana-1.1-final@1 13b04d17-f746-0410-82c6-800466cd88b0
3416 lines
70 KiB
C
3416 lines
70 KiB
C
#include <windows.h>
|
|
/*#include <mingw32/process.h>*/
|
|
|
|
/* Seems to have problems getting these function declarations
|
|
* -- going to try createthread manually this time --
|
|
*/
|
|
/*unsigned long
|
|
_beginthread (void (*pfuncStart)(void *),
|
|
unsigned unStackSize, void* pArgList);
|
|
void _endthread ();*/
|
|
|
|
|
|
#include "input.h"
|
|
#define WIDTH 10
|
|
|
|
char *lastclicklinedata = NULL;
|
|
int lastclickcol, lastclickrow;
|
|
|
|
char *codeptr, *paramptr;
|
|
|
|
int menucmd;
|
|
|
|
int lastscrollerpos, lastscrollerwindow, newscrollerpos;
|
|
|
|
int contextx, contexty;
|
|
|
|
WORD MsgDlgHelp;
|
|
|
|
HWND HVTWin;
|
|
|
|
/* Start VT Code */
|
|
#define CurWidth 2
|
|
|
|
int WinWidth, WinHeight;
|
|
static BOOL Active = FALSE;
|
|
static BOOL CompletelyVisible;
|
|
HFONT VTFont[AttrFontMask+1];
|
|
int FontHeight, FontWidth, ScreenWidth, ScreenHeight;
|
|
BOOL AdjustSize;
|
|
BOOL DontChangeSize=FALSE;
|
|
static int CRTWidth, CRTHeight;
|
|
int CursorX, CursorY;
|
|
|
|
// --- scrolling status flags
|
|
int WinOrgX, WinOrgY, NewOrgX, NewOrgY;
|
|
|
|
int NumOfLines, NumOfColumns;
|
|
int PageStart, BuffEnd;
|
|
|
|
static BOOL CursorOnDBCS = FALSE;
|
|
static LOGFONT VTlf;
|
|
static BOOL SaveWinSize = FALSE;
|
|
static int WinWidthOld, WinHeightOld;
|
|
static HBRUSH Background;
|
|
static COLORREF ANSIColor[16];
|
|
static int Dx[256];
|
|
|
|
// caret variables
|
|
static int CaretStatus;
|
|
static BOOL CaretEnabled = TRUE;
|
|
|
|
// ---- device context and status flags
|
|
static HDC VTDC = NULL; /* Device context for VT window */
|
|
static BYTE DCAttr, DCAttr2;
|
|
static BOOL DCReverse;
|
|
static HFONT DCPrevFont;
|
|
|
|
// scrolling
|
|
static int ScrollCount = 0;
|
|
static int dScroll = 0;
|
|
static int SRegionTop;
|
|
static int SRegionBottom;
|
|
|
|
// for clipboard copy
|
|
static HGLOBAL CBCopyHandle = NULL;
|
|
static PCHAR CBCopyPtr = NULL;
|
|
|
|
// for clipboard paste
|
|
static HGLOBAL CBMemHandle = NULL;
|
|
static PCHAR CBMemPtr = NULL;
|
|
static LONG CBMemPtr2 = 0;
|
|
static BOOL CBAddCR = FALSE;
|
|
static BYTE CBByte;
|
|
static BOOL CBRetrySend;
|
|
static BOOL CBRetryEcho;
|
|
static BOOL CBSendCR;
|
|
static BOOL CBDDE;
|
|
|
|
/* Everything below here should be screen specific */
|
|
/* character attribute */
|
|
static BYTE CharAttr, CharAttr2;
|
|
|
|
/* various modes of VT emulation */
|
|
static BOOL RelativeOrgMode;
|
|
static BOOL ReverseColor;
|
|
static BOOL InsertMode;
|
|
static BOOL LFMode;
|
|
static BOOL AutoWrapMode;
|
|
|
|
static BOOL ESCFlag, JustAfterESC;
|
|
static BOOL Special;
|
|
|
|
static int ParseMode;
|
|
|
|
|
|
PCHAR CBOpen(LONG MemSize)
|
|
{
|
|
if (MemSize==0) return (NULL);
|
|
if (CBCopyHandle!=NULL) return (NULL);
|
|
CBCopyPtr = NULL;
|
|
CBCopyHandle = GlobalAlloc(GMEM_MOVEABLE, MemSize);
|
|
if (CBCopyHandle == NULL)
|
|
MessageBeep(0);
|
|
else {
|
|
CBCopyPtr = GlobalLock(CBCopyHandle);
|
|
if (CBCopyPtr == NULL)
|
|
{
|
|
GlobalFree(CBCopyHandle);
|
|
CBCopyHandle = NULL;
|
|
MessageBeep(0);
|
|
}
|
|
}
|
|
return (CBCopyPtr);
|
|
}
|
|
|
|
void CBClose()
|
|
{
|
|
BOOL Empty;
|
|
if (CBCopyHandle==NULL) return;
|
|
|
|
Empty = FALSE;
|
|
if (CBCopyPtr!=NULL)
|
|
Empty = (CBCopyPtr[0]==0);
|
|
|
|
GlobalUnlock(CBCopyHandle);
|
|
CBCopyPtr = NULL;
|
|
|
|
if (OpenClipboard(HVTWin))
|
|
{
|
|
EmptyClipboard();
|
|
if (! Empty)
|
|
SetClipboardData(CF_TEXT, CBCopyHandle);
|
|
CloseClipboard();
|
|
}
|
|
CBCopyHandle = NULL;
|
|
}
|
|
|
|
void CBStartPaste(HWND HWin, BOOL AddCR,
|
|
int BuffSize, PCHAR DataPtr, int DataSize)
|
|
//
|
|
// DataPtr and DataSize are used only for DDE
|
|
// For clipboard, BuffSize should be 0
|
|
// DataSize should be <= BuffSize
|
|
{
|
|
UINT Cf = 0;
|
|
|
|
CBAddCR = AddCR;
|
|
|
|
if (BuffSize==0) // for clipboard
|
|
{
|
|
if (IsClipboardFormatAvailable(CF_TEXT))
|
|
Cf = CF_TEXT;
|
|
else if (IsClipboardFormatAvailable(CF_OEMTEXT))
|
|
Cf = CF_OEMTEXT;
|
|
else return;
|
|
}
|
|
|
|
CBMemHandle = NULL;
|
|
CBMemPtr = NULL;
|
|
CBMemPtr2 = 0;
|
|
CBDDE = FALSE;
|
|
if (BuffSize==0) //clipboard
|
|
{
|
|
if (OpenClipboard(HWin))
|
|
CBMemHandle = GetClipboardData(Cf);
|
|
}
|
|
else { // dde
|
|
CBMemHandle = GlobalAlloc(GHND,BuffSize);
|
|
if (CBMemHandle != NULL)
|
|
{
|
|
CBDDE = TRUE;
|
|
CBMemPtr = GlobalLock(CBMemHandle);
|
|
if (CBMemPtr != NULL)
|
|
{
|
|
memcpy(CBMemPtr,DataPtr,DataSize);
|
|
GlobalUnlock(CBMemHandle);
|
|
CBMemPtr=NULL;
|
|
}
|
|
}
|
|
}
|
|
CBRetrySend = FALSE;
|
|
CBRetryEcho = FALSE;
|
|
CBSendCR = FALSE;
|
|
}
|
|
|
|
void CBSend()
|
|
{
|
|
int c = 0;
|
|
BOOL EndFlag;
|
|
|
|
if (CBMemHandle==NULL) return;
|
|
|
|
if (CBRetrySend)
|
|
{
|
|
/*c = CommTextOut(&cv,(PCHAR)&CBByte,1);*/
|
|
CBRetrySend = (c==0);
|
|
if (CBRetrySend) return;
|
|
}
|
|
|
|
if (CBRetryEcho)
|
|
{
|
|
/*c = CommTextEcho(&cv,(PCHAR)&CBByte,1);*/
|
|
CBRetryEcho = (c==0);
|
|
if (CBRetryEcho) return;
|
|
}
|
|
|
|
CBMemPtr = GlobalLock(CBMemHandle);
|
|
if (CBMemPtr==NULL) return;
|
|
|
|
do {
|
|
if (CBSendCR && (CBMemPtr[CBMemPtr2]==0x0a))
|
|
CBMemPtr2++;
|
|
|
|
EndFlag = (CBMemPtr[CBMemPtr2]==0);
|
|
if (! EndFlag)
|
|
{
|
|
CBByte = CBMemPtr[CBMemPtr2];
|
|
CBMemPtr2++;
|
|
// Decoding characters which are encoded by MACRO
|
|
// to support NUL character sending
|
|
//
|
|
// [encoded character] --> [decoded character]
|
|
// 01 01 --> 00
|
|
// 01 02 --> 01
|
|
if (CBByte==0x01) /* 0x01 from MACRO */
|
|
{
|
|
CBByte = CBMemPtr[CBMemPtr2];
|
|
CBMemPtr2++;
|
|
CBByte = CBByte - 1; // character just after 0x01
|
|
}
|
|
}
|
|
else if (CBAddCR)
|
|
{
|
|
EndFlag = FALSE;
|
|
CBAddCR = FALSE;
|
|
CBByte = 0x0d;
|
|
}
|
|
else {
|
|
CBEndPaste();
|
|
return;
|
|
}
|
|
|
|
if (! EndFlag)
|
|
{
|
|
/*c = CommTextOut(&cv,(PCHAR)&CBByte,1);*/
|
|
CBSendCR = (CBByte==0x0D);
|
|
CBRetrySend = (c==0);
|
|
if ((! CBRetrySend))
|
|
{
|
|
/*c = CommTextEcho(&cv,(PCHAR)&CBByte,1);*/
|
|
CBRetryEcho = (c==0);
|
|
}
|
|
}
|
|
else
|
|
c=0;
|
|
}
|
|
while (c>0);
|
|
|
|
if (CBMemPtr!=NULL)
|
|
{
|
|
GlobalUnlock(CBMemHandle);
|
|
CBMemPtr=NULL;
|
|
}
|
|
}
|
|
|
|
void CBEndPaste()
|
|
{
|
|
if (CBMemHandle!=NULL)
|
|
{
|
|
if (CBMemPtr!=NULL)
|
|
GlobalUnlock(CBMemHandle);
|
|
if (CBDDE)
|
|
GlobalFree(CBMemHandle);
|
|
}
|
|
if (!CBDDE) CloseClipboard();
|
|
|
|
CBDDE = FALSE;
|
|
CBMemHandle = NULL;
|
|
CBMemPtr = NULL;
|
|
CBMemPtr2 = 0;
|
|
CBAddCR = FALSE;
|
|
}
|
|
|
|
LRESULT CALLBACK AfxWndProc(HWND handle,UINT mess,WPARAM parm1,LPARAM parm2)
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC PaintDC;
|
|
int Xs, Ys, Xe, Ye;
|
|
|
|
switch(mess) {
|
|
#if 0
|
|
case WM_PAINT:
|
|
|
|
PaintDC = BeginPaint(handle, &ps);
|
|
|
|
PaintWindow(PaintDC,ps.rcPaint,ps.fErase, &Xs,&Ys,&Xe,&Ye);
|
|
LockBuffer();
|
|
BuffUpdateRect(Xs,Ys,Xe,Ye);
|
|
UnlockBuffer();
|
|
DispEndPaint();
|
|
|
|
EndPaint(handle, &ps);
|
|
break;
|
|
#endif
|
|
default:
|
|
return DefWindowProc(handle,mess,parm1,parm2);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void InitDisp()
|
|
{
|
|
HDC TmpDC;
|
|
int i;
|
|
|
|
TmpDC = GetDC(NULL);
|
|
|
|
ANSIColor[IdBack ] = RGB( 0, 0, 0);
|
|
ANSIColor[IdRed ] = RGB(255, 0, 0);
|
|
ANSIColor[IdGreen] = RGB( 0,255, 0);
|
|
ANSIColor[IdYellow] = RGB(255,255, 0);
|
|
ANSIColor[IdBlue] = RGB( 0, 0,255);
|
|
ANSIColor[IdMagenta] = RGB(255, 0,255);
|
|
ANSIColor[IdCyan] = RGB( 0,255,255);
|
|
ANSIColor[IdFore ] = RGB(192,192,192);
|
|
|
|
ANSIColor[IdBack+8] = RGB(127,127,127);
|
|
ANSIColor[IdRed+8] = RGB(127, 0, 0);
|
|
ANSIColor[IdGreen+8] = RGB( 0,127, 0);
|
|
ANSIColor[IdYellow+8] = RGB(127,127, 0);
|
|
ANSIColor[IdBlue+8] = RGB( 0, 0,127);
|
|
ANSIColor[IdMagenta+8] = RGB(127, 0,127);
|
|
ANSIColor[IdCyan+8] = RGB( 0,128,128);
|
|
ANSIColor[IdFore+8] = RGB(192,192,192);
|
|
|
|
for (i = IdBack ; i <= IdFore+8 ; i++)
|
|
ANSIColor[i] = GetNearestColor(TmpDC, ANSIColor[i]);
|
|
|
|
/* background paintbrush */
|
|
Background = CreateSolidBrush(RGB(0,0,0));
|
|
/* CRT width & height */
|
|
CRTWidth = GetDeviceCaps(TmpDC,HORZRES);
|
|
CRTHeight = GetDeviceCaps(TmpDC,VERTRES);
|
|
|
|
ReleaseDC(NULL, TmpDC);
|
|
}
|
|
|
|
void EndDisp()
|
|
{
|
|
int i, j;
|
|
|
|
if (VTDC!=NULL) DispReleaseDC();
|
|
|
|
/* Delete fonts */
|
|
for (i = 0 ; i <= AttrFontMask; i++)
|
|
{
|
|
for (j = i+1 ; j <= AttrFontMask ; j++)
|
|
if (VTFont[j]==VTFont[i])
|
|
VTFont[j] = 0;
|
|
if (VTFont[i]!=0) DeleteObject(VTFont[i]);
|
|
}
|
|
|
|
if (Background!=0)
|
|
{
|
|
DeleteObject(Background);
|
|
Background = 0;
|
|
}
|
|
}
|
|
|
|
void DispReset()
|
|
{
|
|
/* Cursor */
|
|
CursorX = 0;
|
|
CursorY = 0;
|
|
|
|
/* Scroll status */
|
|
ScrollCount = 0;
|
|
dScroll = 0;
|
|
|
|
if (IsCaretOn()) CaretOn();
|
|
DispEnableCaret(TRUE); // enable caret
|
|
}
|
|
|
|
void DispConvWinToScreen
|
|
(int Xw, int Yw, int *Xs, int *Ys, LPBOOL Right)
|
|
// Converts window coordinate to screen cordinate
|
|
// Xs: horizontal position in window coordinate (pixels)
|
|
// Ys: vertical
|
|
// Output
|
|
// Xs, Ys: screen coordinate
|
|
// Right: TRUE if the (Xs,Ys) is on the right half of
|
|
// a character cell.
|
|
{
|
|
if (Xs!=NULL)
|
|
*Xs = Xw / FontWidth + WinOrgX;
|
|
*Ys = Yw / FontHeight + WinOrgY;
|
|
if ((Xs!=NULL) && (Right!=NULL))
|
|
*Right = (Xw - (*Xs-WinOrgX)*FontWidth) >= FontWidth/2;
|
|
}
|
|
|
|
void SetLogFont()
|
|
{
|
|
memset(&VTlf, 0, sizeof(LOGFONT));
|
|
VTlf.lfWeight = FW_NORMAL;
|
|
VTlf.lfItalic = 0;
|
|
VTlf.lfUnderline = 0;
|
|
VTlf.lfStrikeOut = 0;
|
|
/*VTlf.lfWidth = ts.VTFontSize.x;
|
|
VTlf.lfHeight = ts.VTFontSize.y;
|
|
VTlf.lfCharSet = ts.VTFontCharSet;*/
|
|
VTlf.lfOutPrecision = OUT_CHARACTER_PRECIS;
|
|
VTlf.lfClipPrecision = CLIP_CHARACTER_PRECIS;
|
|
VTlf.lfQuality = DEFAULT_QUALITY;
|
|
VTlf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
|
|
/*strcpy(VTlf.lfFaceName,ts.VTFont);*/
|
|
}
|
|
|
|
void ChangeFont()
|
|
{
|
|
int i, j;
|
|
TEXTMETRIC Metrics;
|
|
HDC TmpDC;
|
|
|
|
/* Delete Old Fonts */
|
|
for (i = 0 ; i <= AttrFontMask ; i++)
|
|
{
|
|
for (j = i+1 ; j <= AttrFontMask ; j++)
|
|
if (VTFont[j]==VTFont[i])
|
|
VTFont[j] = 0;
|
|
if (VTFont[i]!=0)
|
|
DeleteObject(VTFont[i]);
|
|
}
|
|
|
|
/* Normal Font */
|
|
SetLogFont();
|
|
VTFont[0] = CreateFontIndirect(&VTlf);
|
|
|
|
TmpDC = GetDC(HVTWin);
|
|
|
|
SelectObject(TmpDC, VTFont[0]);
|
|
GetTextMetrics(TmpDC, &Metrics);
|
|
/*FontWidth = Metrics.tmAveCharWidth + ts.FontDW;
|
|
FontHeight = Metrics.tmHeight + ts.FontDH;*/
|
|
|
|
ReleaseDC(HVTWin,TmpDC);
|
|
|
|
/* Underline */
|
|
VTlf.lfUnderline = 1;
|
|
VTFont[AttrUnder] = CreateFontIndirect(&VTlf);
|
|
|
|
/* Bold */
|
|
VTlf.lfUnderline = 0;
|
|
VTlf.lfWeight = FW_BOLD;
|
|
VTFont[AttrBold] = CreateFontIndirect(&VTlf);
|
|
/* Bold + Underline */
|
|
VTlf.lfUnderline = 1;
|
|
VTFont[AttrBold | AttrUnder] = CreateFontIndirect(&VTlf);
|
|
|
|
/* Special font */
|
|
VTlf.lfWeight = FW_NORMAL;
|
|
VTlf.lfUnderline = 0;
|
|
VTlf.lfWidth = FontWidth + 1; /* adjust width */
|
|
VTlf.lfHeight = FontHeight;
|
|
VTlf.lfCharSet = SYMBOL_CHARSET;
|
|
|
|
strcpy(VTlf.lfFaceName,"Tera Special");
|
|
VTFont[AttrSpecial] = CreateFontIndirect(&VTlf);
|
|
VTFont[AttrSpecial | AttrBold] = VTFont[AttrSpecial];
|
|
VTFont[AttrSpecial | AttrUnder] = VTFont[AttrSpecial];
|
|
VTFont[AttrSpecial | AttrBold | AttrUnder] = VTFont[AttrSpecial];
|
|
|
|
SetLogFont();
|
|
|
|
for (i = 0 ; i <= 255; i++)
|
|
Dx[i] = FontWidth;
|
|
}
|
|
|
|
void ChangeCaret()
|
|
{
|
|
UINT T;
|
|
|
|
if (! Active) return;
|
|
if (CaretEnabled)
|
|
{
|
|
DestroyCaret();
|
|
CreateCaret(HVTWin, 0, FontWidth, CurWidth);
|
|
CaretStatus = 1;
|
|
}
|
|
CaretOn();
|
|
if (CaretEnabled)
|
|
{
|
|
T = GetCaretBlinkTime() * 2 / 3;
|
|
SetTimer(HVTWin,IdCaretTimer,T,NULL);
|
|
}
|
|
}
|
|
|
|
void CaretOn()
|
|
// Turn on the cursor
|
|
{
|
|
int CaretX, CaretY;
|
|
|
|
if (! Active) return;
|
|
|
|
CaretX = (CursorX-WinOrgX)*FontWidth;
|
|
CaretY = (CursorY-WinOrgY)*FontHeight;
|
|
|
|
SetCaretPos(CaretX,CaretY);
|
|
|
|
while (CaretStatus > 0)
|
|
{
|
|
ShowCaret(HVTWin);
|
|
CaretStatus--;
|
|
}
|
|
|
|
}
|
|
|
|
void CaretOff()
|
|
{
|
|
if (! Active) return;
|
|
if (CaretStatus == 0)
|
|
{
|
|
HideCaret(HVTWin);
|
|
CaretStatus++;
|
|
}
|
|
}
|
|
|
|
void DispDestroyCaret()
|
|
{
|
|
DestroyCaret();
|
|
}
|
|
|
|
BOOL IsCaretOn()
|
|
// check if caret is on
|
|
{
|
|
return (Active && (CaretStatus==0));
|
|
}
|
|
|
|
void DispEnableCaret(BOOL On)
|
|
{
|
|
if (! On) CaretOff();
|
|
CaretEnabled = On;
|
|
}
|
|
|
|
BOOL IsCaretEnabled()
|
|
{
|
|
return CaretEnabled;
|
|
}
|
|
|
|
void DispSetCaretWidth(BOOL DW)
|
|
{
|
|
/* TRUE if cursor is on a DBCS character */
|
|
CursorOnDBCS = DW;
|
|
}
|
|
|
|
void DispChangeWinSize(int Nx, int Ny)
|
|
{
|
|
LONG W,H,dW,dH;
|
|
RECT R;
|
|
|
|
if (SaveWinSize)
|
|
{
|
|
WinWidthOld = WinWidth;
|
|
WinHeightOld = WinHeight;
|
|
SaveWinSize = FALSE;
|
|
}
|
|
else {
|
|
WinWidthOld = NumOfColumns;
|
|
WinHeightOld = NumOfLines;
|
|
}
|
|
|
|
WinWidth = Nx;
|
|
WinHeight = Ny;
|
|
|
|
ScreenWidth = WinWidth*FontWidth;
|
|
ScreenHeight = WinHeight*FontHeight;
|
|
|
|
AdjustScrollBar();
|
|
|
|
GetWindowRect(HVTWin,&R);
|
|
W = R.right-R.left;
|
|
H = R.bottom-R.top;
|
|
GetClientRect(HVTWin,&R);
|
|
dW = ScreenWidth - R.right + R.left;
|
|
dH = ScreenHeight - R.bottom + R.top;
|
|
|
|
if ((dW!=0) || (dH!=0))
|
|
{
|
|
AdjustSize = TRUE;
|
|
SetWindowPos(HVTWin,HWND_TOP,0,0,W+dW,H+dH,SWP_NOMOVE);
|
|
}
|
|
else
|
|
InvalidateRect(HVTWin,NULL,FALSE);
|
|
}
|
|
|
|
void ResizeWindow(int x, int y, int w, int h, int cw, int ch)
|
|
{
|
|
int dw,dh, NewX, NewY;
|
|
POINT Point;
|
|
|
|
if (! AdjustSize) return;
|
|
dw = ScreenWidth - cw;
|
|
dh = ScreenHeight - ch;
|
|
if ((dw!=0) || (dh!=0))
|
|
SetWindowPos(HVTWin,HWND_TOP,x,y,w+dw,h+dh,SWP_NOMOVE);
|
|
else {
|
|
AdjustSize = FALSE;
|
|
|
|
NewX = x;
|
|
NewY = y;
|
|
if (x+w > CRTWidth)
|
|
{
|
|
NewX = CRTWidth-w;
|
|
if (NewX < 0) NewX = 0;
|
|
}
|
|
if (y+h > CRTHeight)
|
|
{
|
|
NewY = CRTHeight-h;
|
|
if (NewY < 0) NewY = 0;
|
|
}
|
|
if ((NewX!=x) || (NewY!=y))
|
|
SetWindowPos(HVTWin,HWND_TOP,NewX,NewY,w,h,SWP_NOSIZE);
|
|
|
|
Point.x = 0;
|
|
Point.y = ScreenHeight;
|
|
ClientToScreen(HVTWin,&Point);
|
|
CompletelyVisible = (Point.y <= CRTHeight);
|
|
if (IsCaretOn()) CaretOn();
|
|
}
|
|
}
|
|
|
|
void PaintWindow(HDC PaintDC, RECT PaintRect, BOOL fBkGnd,
|
|
int* Xs, int* Ys, int* Xe, int* Ye)
|
|
// Paint window with background color &
|
|
// convert paint region from window coord. to screen coord.
|
|
// Called from WM_PAINT handler
|
|
// PaintRect: Paint region in window coordinate
|
|
// Return:
|
|
// *Xs, *Ys: upper left corner of the region
|
|
// in screen coord.
|
|
// *Xe, *Ye: lower right
|
|
{
|
|
if (VTDC!=NULL)
|
|
DispReleaseDC();
|
|
VTDC = PaintDC;
|
|
DCPrevFont = SelectObject(VTDC, VTFont[0]);
|
|
DispInitDC();
|
|
if (fBkGnd)
|
|
FillRect(VTDC, &PaintRect,Background);
|
|
|
|
*Xs = PaintRect.left / FontWidth + WinOrgX;
|
|
*Ys = PaintRect.top / FontHeight + WinOrgY;
|
|
*Xe = (PaintRect.right-1) / FontWidth + WinOrgX;
|
|
*Ye = (PaintRect.bottom-1) / FontHeight + WinOrgY;
|
|
}
|
|
|
|
void DispEndPaint()
|
|
{
|
|
if (VTDC==NULL) return;
|
|
SelectObject(VTDC,DCPrevFont);
|
|
VTDC = NULL;
|
|
}
|
|
|
|
void DispClearWin()
|
|
{
|
|
InvalidateRect(HVTWin,NULL,FALSE);
|
|
|
|
ScrollCount = 0;
|
|
dScroll = 0;
|
|
if (WinHeight > NumOfLines)
|
|
DispChangeWinSize(NumOfColumns,NumOfLines);
|
|
else {
|
|
/*if ((NumOfLines==WinHeight) && (ts.EnableScrollBuff>0))
|
|
{
|
|
SetScrollRange(HVTWin,SB_VERT,0,1,FALSE);
|
|
}
|
|
else
|
|
SetScrollRange(HVTWin,SB_VERT,0,NumOfLines-WinHeight,FALSE);*/
|
|
|
|
SetScrollPos(HVTWin,SB_HORZ,0,TRUE);
|
|
SetScrollPos(HVTWin,SB_VERT,0,TRUE);
|
|
}
|
|
if (IsCaretOn()) CaretOn();
|
|
}
|
|
|
|
void DispChangeBackground()
|
|
{
|
|
DispReleaseDC();
|
|
if (Background != NULL) DeleteObject(Background);
|
|
Background = CreateSolidBrush(RGB(0,0,0));
|
|
|
|
InvalidateRect(HVTWin,NULL,TRUE);
|
|
}
|
|
|
|
void DispChangeWin()
|
|
{
|
|
/* Change caret shape */
|
|
ChangeCaret();
|
|
|
|
ANSIColor[IdFore ] = RGB(255,255,255);
|
|
ANSIColor[IdBack ] = RGB( 0, 0, 0);
|
|
|
|
/* change background color */
|
|
DispChangeBackground();
|
|
}
|
|
|
|
void DispInitDC()
|
|
{
|
|
if (VTDC==NULL)
|
|
{
|
|
VTDC = GetDC(HVTWin);
|
|
DCPrevFont = SelectObject(VTDC, VTFont[0]);
|
|
}
|
|
else
|
|
SelectObject(VTDC, VTFont[0]);
|
|
SetTextColor(VTDC, RGB(192,192,192));
|
|
SetBkColor(VTDC, RGB(0,0,0));
|
|
SetBkMode(VTDC,OPAQUE);
|
|
DCAttr = AttrDefault;
|
|
DCAttr2 = AttrDefault2;
|
|
DCReverse = FALSE;
|
|
}
|
|
|
|
void DispReleaseDC()
|
|
{
|
|
if (VTDC==NULL) return;
|
|
SelectObject(VTDC, DCPrevFont);
|
|
ReleaseDC(HVTWin,VTDC);
|
|
VTDC = NULL;
|
|
}
|
|
|
|
void DispSetupDC(BYTE Attr, BYTE Attr2, BOOL Reverse)
|
|
// Setup device context
|
|
// Attr, Attr2: character attribute 1 & 2
|
|
// Reverse: true if text is selected (reversed) by mouse
|
|
{
|
|
COLORREF TextColor, BackColor;
|
|
int i, j;
|
|
|
|
if (VTDC==NULL) DispInitDC();
|
|
|
|
if ((DCAttr==Attr) && (DCAttr2==Attr2) &&
|
|
(DCReverse==Reverse)) return;
|
|
DCAttr = Attr;
|
|
DCAttr2 = Attr2;
|
|
DCReverse = Reverse;
|
|
|
|
SelectObject(VTDC, VTFont[Attr & AttrFontMask]);
|
|
|
|
if ((Attr2 & Attr2Fore) != 0)
|
|
{
|
|
if ((Attr & AttrBold) != 0)
|
|
i = 0;
|
|
else
|
|
i = 8;
|
|
j = Attr2 & Attr2ForeMask;
|
|
if (j==0)
|
|
j = 8 - i + j;
|
|
else
|
|
j = i + j;
|
|
TextColor = ANSIColor[j];
|
|
}
|
|
/*else if ((Attr & AttrBlink) != 0)
|
|
BackColor = RGB(127,127,127);
|
|
TextColor = ts.VTBlinkColor[0];*/
|
|
else if ((Attr & AttrBold) != 0)
|
|
TextColor = RGB(127,127,255);
|
|
else
|
|
TextColor = RGB(192,192,192);
|
|
|
|
if ((Attr2 & Attr2Back) != 0)
|
|
{
|
|
if ((Attr & AttrBlink) != 0)
|
|
i = 0;
|
|
else
|
|
i = 8;
|
|
j = (Attr2 & Attr2BackMask) >> SftAttrBack;
|
|
if (j==0)
|
|
j = 8 - i + j;
|
|
else
|
|
j = i + j;
|
|
BackColor = ANSIColor[j];
|
|
}
|
|
else if ((Attr & AttrBlink) != 0)
|
|
BackColor = RGB(127,127,127);
|
|
/*else if ((Attr & AttrBold) != 0)
|
|
BackColor = ts.VTBoldColor[1];*/
|
|
else
|
|
BackColor = RGB(0,0,0);
|
|
|
|
if (Reverse != ((Attr & AttrReverse) != 0))
|
|
{
|
|
SetTextColor(VTDC,BackColor);
|
|
SetBkColor( VTDC,TextColor);
|
|
}
|
|
else {
|
|
SetTextColor(VTDC,TextColor);
|
|
SetBkColor( VTDC,BackColor);
|
|
}
|
|
}
|
|
|
|
void DispANSI(PCHAR Buff)
|
|
{
|
|
DispStr(Buff, strlen(Buff), CursorY, CursorX);
|
|
}
|
|
|
|
void DispStr(PCHAR Buff, int Count, int Y, int* X)
|
|
// Display a string
|
|
// Buff: points the string
|
|
// Y: vertical position in window cordinate
|
|
// *X: horizontal position
|
|
// Return:
|
|
// *X: horizontal position shifted by the width of the string
|
|
{
|
|
RECT RText;
|
|
|
|
RText.top = Y;
|
|
RText.bottom = Y+FontHeight;
|
|
RText.left = *X;
|
|
RText.right = *X + Count*FontWidth;
|
|
/*ExtTextOut(VTDC,*X+ts.FontDX,Y+ts.FontDY,
|
|
ETO_CLIPPED | ETO_OPAQUE,
|
|
&RText,Buff,Count,&Dx[0]);*/
|
|
*X = RText.right;
|
|
}
|
|
|
|
void DispEraseCurToEnd(int YEnd)
|
|
{
|
|
RECT R;
|
|
|
|
if (VTDC==NULL) DispInitDC();
|
|
R.left = 0;
|
|
R.right = ScreenWidth;
|
|
R.top = (CursorY+1-WinOrgY)*FontHeight;
|
|
R.bottom = (YEnd+1-WinOrgY)*FontHeight;
|
|
FillRect(VTDC,&R,Background);
|
|
R.left = (CursorX-WinOrgX)*FontWidth;
|
|
R.bottom = R.top;
|
|
R.top = R.bottom-FontHeight;
|
|
FillRect(VTDC,&R,Background);
|
|
}
|
|
|
|
void DispEraseHomeToCur(int YHome)
|
|
{
|
|
RECT R;
|
|
|
|
if (VTDC==NULL) DispInitDC();
|
|
R.left = 0;
|
|
R.right = ScreenWidth;
|
|
R.top = (YHome-WinOrgY)*FontHeight;
|
|
R.bottom = (CursorY-WinOrgY)*FontHeight;
|
|
FillRect(VTDC,&R,Background);
|
|
R.top = R.bottom;
|
|
R.bottom = R.top + FontHeight;
|
|
R.right = (CursorX+1-WinOrgX)*FontWidth;
|
|
FillRect(VTDC,&R,Background);
|
|
}
|
|
|
|
void DispEraseCharsInLine(int XStart, int Count)
|
|
{
|
|
RECT R;
|
|
|
|
if (VTDC==NULL) DispInitDC();
|
|
R.top = (CursorY-WinOrgY)*FontHeight;
|
|
R.bottom = R.top+FontHeight;
|
|
R.left = (XStart-WinOrgX)*FontWidth;
|
|
R.right = R.left + Count * FontWidth;
|
|
FillRect(VTDC,&R,Background);
|
|
}
|
|
|
|
BOOL DispDeleteLines(int Count, int YEnd)
|
|
// return value:
|
|
// TRUE - screen is successfully updated
|
|
// FALSE - screen is not updated
|
|
{
|
|
RECT R;
|
|
|
|
if (Active && CompletelyVisible &&
|
|
(YEnd+1-WinOrgY <= WinHeight))
|
|
{
|
|
R.left = 0;
|
|
R.right = ScreenWidth;
|
|
R.top = (CursorY-WinOrgY)*FontHeight;
|
|
R.bottom = (YEnd+1-WinOrgY)*FontHeight;
|
|
ScrollWindow(HVTWin,0,-FontHeight*Count,&R,&R);
|
|
UpdateWindow(HVTWin);
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL DispInsertLines(int Count, int YEnd)
|
|
// return value:
|
|
// TRUE - screen is successfully updated
|
|
// FALSE - screen is not updated
|
|
{
|
|
RECT R;
|
|
|
|
if (Active && CompletelyVisible &&
|
|
(CursorY >= WinOrgY))
|
|
{
|
|
R.left = 0;
|
|
R.right = ScreenWidth;
|
|
R.top = (CursorY-WinOrgY)*FontHeight;
|
|
R.bottom = (YEnd+1-WinOrgY)*FontHeight;
|
|
ScrollWindow(HVTWin,0,FontHeight*Count,&R,&R);
|
|
UpdateWindow(HVTWin);
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL IsLineVisible(int* X, int* Y)
|
|
// Check the visibility of a line
|
|
// called from UpdateStr()
|
|
// *X, *Y: position of a character in the line. screen coord.
|
|
// Return: TRUE if the line is visible.
|
|
// *X, *Y:
|
|
// If the line is visible
|
|
// position of the character in window coord.
|
|
// Otherwise
|
|
// no change. same as input value.
|
|
{
|
|
if ((dScroll != 0) &&
|
|
(*Y>=SRegionTop) &&
|
|
(*Y<=SRegionBottom))
|
|
{
|
|
*Y = *Y + dScroll;
|
|
if ((*Y<SRegionTop) || (*Y>SRegionBottom))
|
|
return FALSE;
|
|
}
|
|
|
|
if ((*Y<WinOrgY) ||
|
|
(*Y>=WinOrgY+WinHeight))
|
|
return FALSE;
|
|
|
|
/* screen coordinate -> window coordinate */
|
|
*X = (*X-WinOrgX)*FontWidth;
|
|
*Y = (*Y-WinOrgY)*FontHeight;
|
|
return TRUE;
|
|
}
|
|
|
|
//-------------- scrolling functions --------------------
|
|
|
|
void AdjustScrollBar() /* called by ChangeWindowSize() */
|
|
{
|
|
LONG XRange, YRange;
|
|
int ScrollPosX, ScrollPosY;
|
|
|
|
if (NumOfColumns-WinWidth>0)
|
|
XRange = NumOfColumns-WinWidth;
|
|
else
|
|
XRange = 0;
|
|
|
|
if (BuffEnd-WinHeight>0)
|
|
YRange = BuffEnd-WinHeight;
|
|
else
|
|
YRange = 0;
|
|
|
|
ScrollPosX = GetScrollPos(HVTWin,SB_HORZ);
|
|
ScrollPosY = GetScrollPos(HVTWin,SB_VERT);
|
|
if (ScrollPosX > XRange)
|
|
ScrollPosX = XRange;
|
|
if (ScrollPosY > YRange)
|
|
ScrollPosY = YRange;
|
|
|
|
WinOrgX = ScrollPosX;
|
|
WinOrgY = ScrollPosY-PageStart;
|
|
NewOrgX = WinOrgX;
|
|
NewOrgY = WinOrgY;
|
|
|
|
DontChangeSize = TRUE;
|
|
|
|
SetScrollRange(HVTWin,SB_HORZ,0,XRange,FALSE);
|
|
|
|
/*if ((YRange == 0) && (ts.EnableScrollBuff>0))
|
|
{
|
|
SetScrollRange(HVTWin,SB_VERT,0,1,FALSE);
|
|
}
|
|
else {
|
|
SetScrollRange(HVTWin,SB_VERT,0,YRange,FALSE);
|
|
}
|
|
|
|
SetScrollPos(HVTWin,SB_HORZ,ScrollPosX,TRUE);
|
|
SetScrollPos(HVTWin,SB_VERT,ScrollPosY,TRUE);*/
|
|
|
|
DontChangeSize = FALSE;
|
|
}
|
|
|
|
void DispScrollToCursor(int CurX, int CurY)
|
|
{
|
|
if (CurX < NewOrgX)
|
|
NewOrgX = CurX;
|
|
else if (CurX >= NewOrgX+WinWidth)
|
|
NewOrgX = CurX + 1 - WinWidth;
|
|
|
|
if (CurY < NewOrgY)
|
|
NewOrgY = CurY;
|
|
else if (CurY >= NewOrgY+WinHeight)
|
|
NewOrgY = CurY + 1 - WinHeight;
|
|
}
|
|
|
|
void DispScrollNLines(int Top, int Bottom, int Direction)
|
|
// Scroll a region of the window by Direction lines
|
|
// updates window if necessary
|
|
// Top: top line of scroll region
|
|
// Bottom: bottom line
|
|
// Direction: +: forward, -: backward
|
|
{
|
|
if (((dScroll*Direction <0) ||
|
|
(dScroll*Direction >0)) &&
|
|
((SRegionTop!=Top) ||
|
|
(SRegionBottom!=Bottom)))
|
|
DispUpdateScroll();
|
|
SRegionTop = Top;
|
|
SRegionBottom = Bottom;
|
|
dScroll = dScroll + Direction;
|
|
if (Direction>0)
|
|
DispCountScroll(Direction);
|
|
else
|
|
DispCountScroll(-Direction);
|
|
}
|
|
|
|
void DispCountScroll(int n)
|
|
{
|
|
ScrollCount = ScrollCount + n;
|
|
/*if (ScrollCount>=ts.ScrollThreshold) DispUpdateScroll();*/
|
|
}
|
|
|
|
void DispUpdateScroll()
|
|
{
|
|
int d;
|
|
RECT R;
|
|
|
|
ScrollCount = 0;
|
|
|
|
/* Update partial scroll */
|
|
if (dScroll != 0)
|
|
{
|
|
d = dScroll * FontHeight;
|
|
R.left = 0;
|
|
R.right = ScreenWidth;
|
|
R.top = (SRegionTop-WinOrgY)*FontHeight;
|
|
R.bottom = (SRegionBottom+1-WinOrgY)*FontHeight;
|
|
ScrollWindow(HVTWin,0,-d,&R,&R);
|
|
/* if ((SRegionTop==0) && (dScroll>0))
|
|
{ // update scroll bar if BuffEnd is changed
|
|
if ((BuffEnd==WinHeight) &&
|
|
(ts.EnableScrollBuff>0))
|
|
SetScrollRange(HVTWin,SB_VERT,0,1,TRUE);
|
|
else
|
|
SetScrollRange(HVTWin,SB_VERT,0,BuffEnd-WinHeight,FALSE);
|
|
SetScrollPos(HVTWin,SB_VERT,WinOrgY+PageStart,TRUE);
|
|
}*/
|
|
dScroll = 0;
|
|
}
|
|
|
|
/* Update normal scroll */
|
|
if (NewOrgX < 0) NewOrgX = 0;
|
|
if (NewOrgX>NumOfColumns-WinWidth)
|
|
NewOrgX = NumOfColumns-WinWidth;
|
|
if (NewOrgY < -PageStart) NewOrgY = -PageStart;
|
|
if (NewOrgY>BuffEnd-WinHeight-PageStart)
|
|
NewOrgY = BuffEnd-WinHeight-PageStart;
|
|
|
|
if ((NewOrgX==WinOrgX) &&
|
|
(NewOrgY==WinOrgY)) return;
|
|
|
|
if (NewOrgX==WinOrgX)
|
|
{
|
|
d = (NewOrgY-WinOrgY) * FontHeight;
|
|
ScrollWindow(HVTWin,0,-d,NULL,NULL);
|
|
}
|
|
else if (NewOrgY==WinOrgY)
|
|
{
|
|
d = (NewOrgX-WinOrgX) * FontWidth;
|
|
ScrollWindow(HVTWin,-d,0,NULL,NULL);
|
|
}
|
|
else
|
|
InvalidateRect(HVTWin,NULL,TRUE);
|
|
|
|
/* Update scroll bars */
|
|
if (NewOrgX!=WinOrgX)
|
|
SetScrollPos(HVTWin,SB_HORZ,NewOrgX,TRUE);
|
|
|
|
if (NewOrgY!=WinOrgY)
|
|
{
|
|
/* if ((BuffEnd==WinHeight) &&
|
|
(ts.EnableScrollBuff>0))
|
|
SetScrollRange(HVTWin,SB_VERT,0,1,TRUE);
|
|
else
|
|
SetScrollRange(HVTWin,SB_VERT,0,BuffEnd-WinHeight,FALSE);
|
|
SetScrollPos(HVTWin,SB_VERT,NewOrgY+PageStart,TRUE);*/
|
|
}
|
|
|
|
WinOrgX = NewOrgX;
|
|
WinOrgY = NewOrgY;
|
|
|
|
if (IsCaretOn()) CaretOn();
|
|
}
|
|
|
|
void DispScrollHomePos()
|
|
{
|
|
NewOrgX = 0;
|
|
NewOrgY = 0;
|
|
DispUpdateScroll();
|
|
}
|
|
|
|
void DispAutoScroll(POINT p)
|
|
{
|
|
int X, Y;
|
|
|
|
X = (p.x + FontWidth / 2) / FontWidth;
|
|
Y = p.y / FontHeight;
|
|
if (X<0)
|
|
NewOrgX = WinOrgX + X;
|
|
else if (X>=WinWidth)
|
|
NewOrgX = NewOrgX + X - WinWidth + 1;
|
|
if (Y<0)
|
|
NewOrgY = WinOrgY + Y;
|
|
else if (Y>=WinHeight)
|
|
NewOrgY = NewOrgY + Y - WinHeight + 1;
|
|
|
|
DispUpdateScroll();
|
|
}
|
|
|
|
void DispHScroll(int Func, int Pos)
|
|
{
|
|
switch (Func) {
|
|
case SCROLL_BOTTOM:
|
|
NewOrgX = NumOfColumns-WinWidth;
|
|
break;
|
|
case SCROLL_LINEDOWN: NewOrgX = WinOrgX + 1; break;
|
|
case SCROLL_LINEUP: NewOrgX = WinOrgX - 1; break;
|
|
case SCROLL_PAGEDOWN:
|
|
NewOrgX = WinOrgX + WinWidth - 1;
|
|
break;
|
|
case SCROLL_PAGEUP:
|
|
NewOrgX = WinOrgX - WinWidth + 1;
|
|
break;
|
|
case SCROLL_POS: NewOrgX = Pos; break;
|
|
case SCROLL_TOP: NewOrgX = 0; break;
|
|
}
|
|
DispUpdateScroll();
|
|
}
|
|
|
|
void DispVScroll(int Func, int Pos)
|
|
{
|
|
switch (Func) {
|
|
case SCROLL_BOTTOM:
|
|
NewOrgY = BuffEnd-WinHeight-PageStart;
|
|
break;
|
|
case SCROLL_LINEDOWN: NewOrgY = WinOrgY + 1; break;
|
|
case SCROLL_LINEUP: NewOrgY = WinOrgY - 1; break;
|
|
case SCROLL_PAGEDOWN:
|
|
NewOrgY = WinOrgY + WinHeight - 1;
|
|
break;
|
|
case SCROLL_PAGEUP:
|
|
NewOrgY = WinOrgY - WinHeight + 1;
|
|
break;
|
|
case SCROLL_POS: NewOrgY = Pos-PageStart; break;
|
|
case SCROLL_TOP: NewOrgY = -PageStart; break;
|
|
}
|
|
DispUpdateScroll();
|
|
}
|
|
|
|
//-------------- end of scrolling functions --------
|
|
|
|
void DispSetupFontDlg()
|
|
// Popup the Setup Font dialogbox and
|
|
// reset window
|
|
{
|
|
BOOL Ok = 0;
|
|
|
|
/*(if (! LoadTTDLG()) return;
|
|
SetLogFont();
|
|
Ok = ChooseFontDlg(HVTWin,&VTlf,&ts);
|
|
FreeTTDLG(); */
|
|
if (! Ok) return;
|
|
|
|
/*strcpy(ts.VTFont,VTlf.lfFaceName);
|
|
ts.VTFontSize.x = VTlf.lfWidth;
|
|
ts.VTFontSize.y = VTlf.lfHeight;
|
|
ts.VTFontCharSet = VTlf.lfCharSet;*/
|
|
|
|
ChangeFont();
|
|
|
|
DispChangeWinSize(WinWidth,WinHeight);
|
|
|
|
ChangeCaret();
|
|
}
|
|
|
|
void DispRestoreWinSize()
|
|
// Restore window size by double clik on caption bar
|
|
{
|
|
if ((WinWidth==NumOfColumns) && (WinHeight==NumOfLines))
|
|
{
|
|
if (WinWidthOld > NumOfColumns)
|
|
WinWidthOld = NumOfColumns;
|
|
if (WinHeightOld > BuffEnd)
|
|
WinHeightOld = BuffEnd;
|
|
DispChangeWinSize(WinWidthOld,WinHeightOld);
|
|
}
|
|
else {
|
|
SaveWinSize = TRUE;
|
|
DispChangeWinSize(NumOfColumns,NumOfLines);
|
|
}
|
|
}
|
|
|
|
void DispSetWinPos()
|
|
{
|
|
POINT Point;
|
|
RECT R;
|
|
|
|
GetWindowRect(HVTWin,&R);
|
|
|
|
Point.x = 0;
|
|
Point.y = ScreenHeight;
|
|
ClientToScreen(HVTWin,&Point);
|
|
CompletelyVisible = (Point.y <= CRTHeight);
|
|
}
|
|
|
|
void DispSetActive(BOOL ActiveFlag)
|
|
{
|
|
Active = ActiveFlag;
|
|
if (Active)
|
|
{
|
|
SetFocus(HVTWin);
|
|
}
|
|
}
|
|
/* End VT code */
|
|
/* Start Scrollback code */
|
|
// status line
|
|
int StatusLine; //0: none 1: shown
|
|
/* top & bottom margin */
|
|
int CursorTop, CursorBottom;
|
|
BOOL Selected;
|
|
BOOL Wrap;
|
|
|
|
static WORD TabStops[256];
|
|
static int NTabStops;
|
|
|
|
static WORD BuffLock = 0;
|
|
static HANDLE HCodeBuff = 0;
|
|
static HANDLE HAttrBuff = 0;
|
|
static HANDLE HAttrBuff2 = 0;
|
|
|
|
static PCHAR CodeBuff; /* Character code buffer */
|
|
static PCHAR AttrBuff; /* Attribute buffer */
|
|
static PCHAR AttrBuff2; /* Color attr buffer */
|
|
static PCHAR CodeLine;
|
|
static PCHAR AttrLine;
|
|
static PCHAR AttrLine2;
|
|
static LONG LinePtr;
|
|
static LONG BufferSize;
|
|
static int NumOfLinesInBuff;
|
|
static int BuffStartAbs, BuffEndAbs;
|
|
static POINT SelectStart, SelectEnd, SelectEndOld;
|
|
static BOOL BoxSelect;
|
|
static POINT DblClkStart, DblClkEnd;
|
|
|
|
static int StrChangeStart, StrChangeCount;
|
|
|
|
LONG GetLinePtr(int Line)
|
|
{
|
|
LONG Ptr;
|
|
|
|
Ptr = (LONG)(BuffStartAbs + Line) *
|
|
(LONG)(NumOfColumns);
|
|
while (Ptr>=BufferSize)
|
|
Ptr = Ptr - BufferSize;
|
|
return Ptr;
|
|
}
|
|
|
|
LONG NextLinePtr(LONG Ptr)
|
|
{
|
|
Ptr = Ptr + (LONG)NumOfColumns;
|
|
if (Ptr >= BufferSize)
|
|
Ptr = Ptr - BufferSize;
|
|
return Ptr;
|
|
}
|
|
|
|
LONG PrevLinePtr(LONG Ptr)
|
|
{
|
|
Ptr = Ptr - (LONG)NumOfColumns;
|
|
if (Ptr < 0) Ptr = Ptr + BufferSize;
|
|
return Ptr;
|
|
}
|
|
|
|
BOOL ChangeBuffer(int Nx, int Ny)
|
|
{
|
|
HANDLE HCodeNew, HAttrNew, HAttr2New;
|
|
LONG NewSize;
|
|
int NxCopy, NyCopy, i;
|
|
PCHAR CodeDest, AttrDest, AttrDest2;
|
|
PCHAR Ptr;
|
|
LONG SrcPtr, DestPtr;
|
|
WORD LockOld;
|
|
|
|
if (Nx > BuffXMax) Nx = BuffXMax;
|
|
/*if (ts.ScrollBuffMax > BuffYMax)
|
|
ts.ScrollBuffMax = BuffYMax;
|
|
if (Ny > ts.ScrollBuffMax) Ny = ts.ScrollBuffMax;*/
|
|
|
|
if ( (LONG)Nx * (LONG)Ny > BuffSizeMax )
|
|
Ny = BuffSizeMax / Nx;
|
|
|
|
NewSize = (LONG)Nx * (LONG)Ny;
|
|
|
|
HCodeNew = GlobalAlloc(GMEM_MOVEABLE, NewSize);
|
|
if ( HCodeNew==0 ) return FALSE;
|
|
Ptr = GlobalLock(HCodeNew);
|
|
if ( Ptr==NULL )
|
|
{
|
|
GlobalFree(HCodeNew);
|
|
return FALSE;
|
|
}
|
|
CodeDest = Ptr;
|
|
|
|
HAttrNew = GlobalAlloc(GMEM_MOVEABLE, NewSize);
|
|
if ( HAttrNew==0 )
|
|
{
|
|
GlobalFree(HCodeNew);
|
|
return FALSE;
|
|
}
|
|
Ptr = GlobalLock(HAttrNew);
|
|
if ( Ptr==NULL )
|
|
{
|
|
GlobalFree(HCodeNew);
|
|
GlobalFree(HAttrNew);
|
|
return FALSE;
|
|
}
|
|
AttrDest = Ptr;
|
|
|
|
HAttr2New = GlobalAlloc(GMEM_MOVEABLE, NewSize);
|
|
if ( HAttr2New==0 )
|
|
{
|
|
GlobalFree(HCodeNew);
|
|
GlobalFree(HAttrNew);
|
|
return FALSE;
|
|
}
|
|
Ptr = GlobalLock(HAttr2New);
|
|
if ( Ptr==NULL )
|
|
{
|
|
GlobalFree(HCodeNew);
|
|
GlobalFree(HAttrNew);
|
|
GlobalFree(HAttr2New);
|
|
return FALSE;
|
|
}
|
|
AttrDest2 = Ptr;
|
|
|
|
memset(&CodeDest[0], 0x20, NewSize);
|
|
memset(&AttrDest[0], AttrDefault, NewSize);
|
|
memset(&AttrDest2[0], AttrDefault2, NewSize);
|
|
if ( HCodeBuff!=0 )
|
|
{
|
|
if ( NumOfColumns > Nx )
|
|
NxCopy = Nx;
|
|
else NxCopy = NumOfColumns;
|
|
if ( BuffEnd > Ny )
|
|
NyCopy = Ny;
|
|
else NyCopy = BuffEnd;
|
|
LockOld = BuffLock;
|
|
LockBuffer();
|
|
SrcPtr = GetLinePtr(BuffEnd-NyCopy);
|
|
DestPtr = 0;
|
|
for (i = 1 ; i <= NyCopy ; i++)
|
|
{
|
|
memcpy(&CodeDest[DestPtr],&CodeBuff[SrcPtr],NxCopy);
|
|
memcpy(&AttrDest[DestPtr],&AttrBuff[SrcPtr],NxCopy);
|
|
memcpy(&AttrDest2[DestPtr],&AttrBuff2[SrcPtr],NxCopy);
|
|
SrcPtr = NextLinePtr(SrcPtr);
|
|
DestPtr = DestPtr + (LONG)Nx;
|
|
}
|
|
FreeBuffer();
|
|
}
|
|
else {
|
|
LockOld = 0;
|
|
NyCopy = NumOfLines;
|
|
Selected = FALSE;
|
|
}
|
|
|
|
if (Selected)
|
|
{
|
|
SelectStart.y =
|
|
SelectStart.y - BuffEnd + NyCopy;
|
|
SelectEnd.y =
|
|
SelectEnd.y - BuffEnd + NyCopy;
|
|
if (SelectStart.y < 0)
|
|
{
|
|
SelectStart.y = 0;
|
|
SelectStart.x = 0;
|
|
}
|
|
if (SelectEnd.y<0)
|
|
{
|
|
SelectEnd.x = 0;
|
|
SelectEnd.y = 0;
|
|
}
|
|
|
|
Selected = (SelectEnd.y > SelectStart.y) ||
|
|
((SelectEnd.y=SelectStart.y) &&
|
|
(SelectEnd.x > SelectStart.x));
|
|
}
|
|
|
|
HCodeBuff = HCodeNew;
|
|
HAttrBuff = HAttrNew;
|
|
HAttrBuff2 = HAttr2New;
|
|
BufferSize = NewSize;
|
|
NumOfLinesInBuff = Ny;
|
|
BuffStartAbs = 0;
|
|
BuffEnd = NyCopy;
|
|
|
|
if (BuffEnd==NumOfLinesInBuff)
|
|
BuffEndAbs = 0;
|
|
else
|
|
BuffEndAbs = BuffEnd;
|
|
|
|
PageStart = BuffEnd - NumOfLines;
|
|
|
|
LinePtr = 0;
|
|
if (LockOld>0)
|
|
{
|
|
CodeBuff = (PCHAR)GlobalLock(HCodeBuff);
|
|
AttrBuff = (PCHAR)GlobalLock(HAttrBuff);
|
|
AttrBuff2 = (PCHAR)GlobalLock(HAttrBuff2);
|
|
CodeLine = CodeBuff;
|
|
AttrLine = AttrBuff;
|
|
AttrLine2 = AttrBuff2;
|
|
}
|
|
else {
|
|
GlobalUnlock(HCodeNew);
|
|
GlobalUnlock(HAttrNew);
|
|
}
|
|
BuffLock = LockOld;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void InitBuffer()
|
|
{
|
|
int Ny;
|
|
|
|
/* setup terminal */
|
|
NumOfColumns = 80;
|
|
NumOfLines = 25;
|
|
|
|
Ny = NumOfLines;
|
|
|
|
if (! ChangeBuffer(NumOfColumns,Ny))
|
|
PostQuitMessage(0);
|
|
|
|
StatusLine = 0;
|
|
}
|
|
|
|
void ResetTerminal() /*reset variables but don't update screen */
|
|
{
|
|
DispReset();
|
|
BuffReset();
|
|
|
|
/* Attribute */
|
|
CharAttr = AttrDefault;
|
|
CharAttr2 = AttrDefault2;
|
|
Special = FALSE;
|
|
|
|
/* Various modes */
|
|
InsertMode = FALSE;
|
|
LFMode = IdCRLF;
|
|
AutoWrapMode = TRUE;
|
|
RelativeOrgMode = FALSE;
|
|
ReverseColor = FALSE;
|
|
|
|
/* ESC flag for device control sequence */
|
|
ESCFlag = FALSE;
|
|
/* for TEK sequence */
|
|
JustAfterESC = FALSE;
|
|
|
|
/* Parse mode */
|
|
ParseMode = ModeFirst;
|
|
}
|
|
|
|
void NewLine(int Line)
|
|
{
|
|
LinePtr = GetLinePtr(Line);
|
|
CodeLine = &CodeBuff[LinePtr];
|
|
AttrLine = &AttrBuff[LinePtr];
|
|
AttrLine2 = &AttrBuff2[LinePtr];
|
|
}
|
|
|
|
void LockBuffer()
|
|
{
|
|
BuffLock++;
|
|
if (BuffLock>1) return;
|
|
CodeBuff = (PCHAR)GlobalLock(HCodeBuff);
|
|
AttrBuff = (PCHAR)GlobalLock(HAttrBuff);
|
|
AttrBuff2 = (PCHAR)GlobalLock(HAttrBuff2);
|
|
NewLine(PageStart+CursorY);
|
|
}
|
|
|
|
void UnlockBuffer()
|
|
{
|
|
if (BuffLock==0) return;
|
|
BuffLock--;
|
|
if (BuffLock>0) return;
|
|
if (HCodeBuff!=NULL)
|
|
GlobalUnlock(HCodeBuff);
|
|
if (HAttrBuff!=NULL)
|
|
GlobalUnlock(HAttrBuff);
|
|
if (HAttrBuff2!=NULL)
|
|
GlobalUnlock(HAttrBuff2);
|
|
}
|
|
|
|
void FreeBuffer()
|
|
{
|
|
BuffLock = 1;
|
|
UnlockBuffer();
|
|
if (HCodeBuff!=NULL)
|
|
{
|
|
GlobalFree(HCodeBuff);
|
|
HCodeBuff = NULL;
|
|
}
|
|
if (HAttrBuff!=NULL)
|
|
{
|
|
GlobalFree(HAttrBuff);
|
|
HAttrBuff = NULL;
|
|
}
|
|
if (HAttrBuff2!=NULL)
|
|
{
|
|
GlobalFree(HAttrBuff2);
|
|
HAttrBuff2 = NULL;
|
|
}
|
|
}
|
|
|
|
void BuffReset()
|
|
// Reset buffer status. don't update real display
|
|
// called by ResetTerminal()
|
|
{
|
|
int i;
|
|
|
|
/* Cursor */
|
|
NewLine(PageStart);
|
|
WinOrgX = 0;
|
|
WinOrgY = 0;
|
|
NewOrgX = 0;
|
|
NewOrgY = 0;
|
|
|
|
/* Top/bottom margin */
|
|
CursorTop = 0;
|
|
CursorBottom = NumOfLines-1;
|
|
|
|
/* Tab stops */
|
|
NTabStops = (NumOfColumns-1) >> 3;
|
|
for (i=1 ; i<=NTabStops ; i++)
|
|
TabStops[i-1] = i*8;
|
|
|
|
/* Initialize text selection region */
|
|
SelectStart.x = 0;
|
|
SelectStart.y = 0;
|
|
SelectEnd = SelectStart;
|
|
SelectEndOld = SelectStart;
|
|
Selected = FALSE;
|
|
|
|
StrChangeCount = 0;
|
|
Wrap = FALSE;
|
|
StatusLine = 0;
|
|
}
|
|
|
|
void BuffScroll(int Count, int Bottom)
|
|
{
|
|
int i, n;
|
|
LONG SrcPtr, DestPtr;
|
|
int BuffEndOld;
|
|
|
|
if (Count>NumOfLinesInBuff)
|
|
Count = NumOfLinesInBuff;
|
|
|
|
DestPtr = GetLinePtr(PageStart+NumOfLines-1+Count);
|
|
n = Count;
|
|
if (Bottom<NumOfLines-1)
|
|
{
|
|
SrcPtr = GetLinePtr(PageStart+NumOfLines-1);
|
|
for (i=NumOfLines-1; i>=Bottom+1; i--)
|
|
{
|
|
memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
|
|
memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
|
|
memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
|
|
memset(&(CodeBuff[SrcPtr]),0x20,NumOfColumns);
|
|
memset(&(AttrBuff[SrcPtr]),AttrDefault,NumOfColumns);
|
|
memset(&(AttrBuff2[SrcPtr]),AttrDefault2,NumOfColumns);
|
|
SrcPtr = PrevLinePtr(SrcPtr);
|
|
DestPtr = PrevLinePtr(DestPtr);
|
|
n--;
|
|
}
|
|
}
|
|
for (i = 1 ; i <= n ; i++)
|
|
{
|
|
memset(&CodeBuff[DestPtr],0x20,NumOfColumns);
|
|
memset(&AttrBuff[DestPtr],AttrDefault,NumOfColumns);
|
|
memset(&AttrBuff2[DestPtr],AttrDefault2,NumOfColumns);
|
|
DestPtr = PrevLinePtr(DestPtr);
|
|
}
|
|
|
|
BuffEndAbs = BuffEndAbs + Count;
|
|
if (BuffEndAbs >= NumOfLinesInBuff)
|
|
BuffEndAbs = BuffEndAbs - NumOfLinesInBuff;
|
|
BuffEndOld = BuffEnd;
|
|
BuffEnd = BuffEnd + Count;
|
|
if (BuffEnd >= NumOfLinesInBuff)
|
|
{
|
|
BuffEnd = NumOfLinesInBuff;
|
|
BuffStartAbs = BuffEndAbs;
|
|
}
|
|
PageStart = BuffEnd-NumOfLines;
|
|
|
|
if (Selected)
|
|
{
|
|
SelectStart.y = SelectStart.y - Count + BuffEnd - BuffEndOld;
|
|
SelectEnd.y = SelectEnd.y - Count + BuffEnd - BuffEndOld;
|
|
if ( SelectStart.y<0 )
|
|
{
|
|
SelectStart.x = 0;
|
|
SelectStart.y = 0;
|
|
}
|
|
if ( SelectEnd.y<0 )
|
|
{
|
|
SelectEnd.x = 0;
|
|
SelectEnd.y = 0;
|
|
}
|
|
Selected =
|
|
(SelectEnd.y > SelectStart.y) ||
|
|
((SelectEnd.y==SelectStart.y) &&
|
|
(SelectEnd.x > SelectStart.x));
|
|
}
|
|
|
|
NewLine(PageStart+CursorY);
|
|
}
|
|
|
|
void NextLine()
|
|
{
|
|
LinePtr = NextLinePtr(LinePtr);
|
|
CodeLine = &CodeBuff[LinePtr];
|
|
AttrLine = &AttrBuff[LinePtr];
|
|
AttrLine2 = &AttrBuff2[LinePtr];
|
|
}
|
|
|
|
void PrevLine()
|
|
{
|
|
LinePtr = PrevLinePtr(LinePtr);
|
|
CodeLine = &CodeBuff[LinePtr];
|
|
AttrLine = &AttrBuff[LinePtr];
|
|
AttrLine2 = &AttrBuff2[LinePtr];
|
|
}
|
|
|
|
void BuffInsertSpace(int Count)
|
|
// Insert space characters at the current position
|
|
// Count: Number of characters to be inserted
|
|
{
|
|
NewLine(PageStart+CursorY);
|
|
|
|
if (Count > NumOfColumns - CursorX)
|
|
Count = NumOfColumns - CursorX;
|
|
|
|
memmove(&(CodeLine[CursorX+Count]),&(CodeLine[CursorX]),
|
|
NumOfColumns-Count-CursorX);
|
|
memmove(&(AttrLine[CursorX+Count]),&(AttrLine[CursorX]),
|
|
NumOfColumns-Count-CursorX);
|
|
memmove(&(AttrLine2[CursorX+Count]),&(AttrLine2[CursorX]),
|
|
NumOfColumns-Count-CursorX);
|
|
memset(&(CodeLine[CursorX]),0x20,Count);
|
|
memset(&(AttrLine[CursorX]),AttrDefault,Count);
|
|
memset(&(AttrLine2[CursorX]),AttrDefault2,Count);
|
|
/* last char in current line is kanji first? */
|
|
if ((AttrLine[NumOfColumns-1] & AttrKanji) != 0)
|
|
{
|
|
/* then delete it */
|
|
CodeLine[NumOfColumns-1] = 0x20;
|
|
AttrLine[NumOfColumns-1] = AttrDefault;
|
|
AttrLine2[NumOfColumns-1] = AttrDefault2;
|
|
}
|
|
BuffUpdateRect(CursorX,CursorY,NumOfColumns-1,CursorY);
|
|
}
|
|
|
|
void BuffEraseCurToEnd()
|
|
// Erase characters from cursor to the end of screen
|
|
{
|
|
LONG TmpPtr;
|
|
int offset;
|
|
int i, YEnd;
|
|
|
|
NewLine(PageStart+CursorY);
|
|
offset = CursorX;
|
|
TmpPtr = GetLinePtr(PageStart+CursorY);
|
|
YEnd = NumOfLines-1;
|
|
if ((StatusLine>0) &&
|
|
(CursorY<NumOfLines-1))
|
|
YEnd--;
|
|
for (i = CursorY ; i <= YEnd ; i++)
|
|
{
|
|
memset(&(CodeBuff[TmpPtr+offset]),0x20,NumOfColumns-offset);
|
|
memset(&(AttrBuff[TmpPtr+offset]),AttrDefault,NumOfColumns-offset);
|
|
memset(&(AttrBuff2[TmpPtr+offset]),AttrDefault2,NumOfColumns-offset);
|
|
offset = 0;
|
|
TmpPtr = NextLinePtr(TmpPtr);
|
|
}
|
|
/* update window */
|
|
DispEraseCurToEnd(YEnd);
|
|
}
|
|
|
|
void BuffEraseHomeToCur()
|
|
// Erase characters from home to cursor
|
|
{
|
|
LONG TmpPtr;
|
|
int offset;
|
|
int i, YHome;
|
|
|
|
NewLine(PageStart+CursorY);
|
|
offset = NumOfColumns;
|
|
if ((StatusLine>0) && (CursorY==NumOfLines-1))
|
|
YHome = CursorY;
|
|
else
|
|
YHome = 0;
|
|
TmpPtr = GetLinePtr(PageStart+YHome);
|
|
for (i = YHome ; i <= CursorY ; i++)
|
|
{
|
|
if (i==CursorY) offset = CursorX+1;
|
|
memset(&(CodeBuff[TmpPtr]),0x20,offset);
|
|
memset(&(AttrBuff[TmpPtr]),AttrDefault,offset);
|
|
memset(&(AttrBuff2[TmpPtr]),AttrDefault2,offset);
|
|
TmpPtr = NextLinePtr(TmpPtr);
|
|
}
|
|
|
|
/* update window */
|
|
DispEraseHomeToCur(YHome);
|
|
}
|
|
|
|
void BuffInsertLines(int Count, int YEnd)
|
|
// Insert lines at current position
|
|
// Count: number of lines to be inserted
|
|
// YEnd: bottom line number of scroll region (screen coordinate)
|
|
{
|
|
int i;
|
|
LONG SrcPtr, DestPtr;
|
|
|
|
BuffUpdateScroll();
|
|
|
|
SrcPtr = GetLinePtr(PageStart+YEnd-Count);
|
|
DestPtr = GetLinePtr(PageStart+YEnd);
|
|
for (i= YEnd-Count ; i>=CursorY ; i--)
|
|
{
|
|
memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
|
|
memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
|
|
memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
|
|
SrcPtr = PrevLinePtr(SrcPtr);
|
|
DestPtr = PrevLinePtr(DestPtr);
|
|
}
|
|
for (i = 1 ; i <= Count ; i++)
|
|
{
|
|
memset(&(CodeBuff[DestPtr]),0x20,NumOfColumns);
|
|
memset(&(AttrBuff[DestPtr]),AttrDefault,NumOfColumns);
|
|
memset(&(AttrBuff2[DestPtr]),AttrDefault2,NumOfColumns);
|
|
DestPtr = PrevLinePtr(DestPtr);
|
|
}
|
|
|
|
if (! DispInsertLines(Count,YEnd))
|
|
BuffUpdateRect(WinOrgX,CursorY,WinOrgX+WinWidth-1,YEnd);
|
|
}
|
|
|
|
void BuffEraseCharsInLine(int XStart, int Count)
|
|
// erase characters in the current line
|
|
// XStart: start position of erasing
|
|
// Count: number of characters to be erased
|
|
{
|
|
NewLine(PageStart+CursorY);
|
|
memset(&(CodeLine[XStart]),0x20,Count);
|
|
memset(&(AttrLine[XStart]),AttrDefault,Count);
|
|
memset(&(AttrLine2[XStart]),AttrDefault2,Count);
|
|
|
|
DispEraseCharsInLine(XStart, Count);
|
|
}
|
|
|
|
void BuffDeleteLines(int Count, int YEnd)
|
|
// Delete lines from current line
|
|
// Count: number of lines to be deleted
|
|
// YEnd: bottom line number of scroll region (screen coordinate)
|
|
{
|
|
int i;
|
|
LONG SrcPtr, DestPtr;
|
|
|
|
BuffUpdateScroll();
|
|
|
|
SrcPtr = GetLinePtr(PageStart+CursorY+Count);
|
|
DestPtr = GetLinePtr(PageStart+CursorY);
|
|
for (i=CursorY ; i<= YEnd-Count ; i++)
|
|
{
|
|
memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
|
|
memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
|
|
memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
|
|
SrcPtr = NextLinePtr(SrcPtr);
|
|
DestPtr = NextLinePtr(DestPtr);
|
|
}
|
|
for (i = YEnd+1-Count ; i<=YEnd ; i++)
|
|
{
|
|
memset(&(CodeBuff[DestPtr]),0x20,NumOfColumns);
|
|
memset(&(AttrBuff[DestPtr]),AttrDefault,NumOfColumns);
|
|
memset(&(AttrBuff2[DestPtr]),AttrDefault2,NumOfColumns);
|
|
DestPtr = NextLinePtr(DestPtr);
|
|
}
|
|
|
|
if (! DispDeleteLines(Count,YEnd))
|
|
BuffUpdateRect(WinOrgX,CursorY,WinOrgX+WinWidth-1,YEnd);
|
|
}
|
|
|
|
void BuffDeleteChars(int Count)
|
|
// Delete characters in current line from cursor
|
|
// Count: number of characters to be deleted
|
|
{
|
|
NewLine(PageStart+CursorY);
|
|
|
|
if (Count > NumOfColumns-CursorX) Count = NumOfColumns-CursorX;
|
|
memmove(&(CodeLine[CursorX]),&(CodeLine[CursorX+Count]),
|
|
NumOfColumns-Count-CursorX);
|
|
memmove(&(AttrLine[CursorX]),&(AttrLine[CursorX+Count]),
|
|
NumOfColumns-Count-CursorX);
|
|
memmove(&(AttrLine2[CursorX]),&(AttrLine2[CursorX+Count]),
|
|
NumOfColumns-Count-CursorX);
|
|
memset(&(CodeLine[NumOfColumns-Count]),0x20,Count);
|
|
memset(&(AttrLine[NumOfColumns-Count]),AttrDefault,Count);
|
|
memset(&(AttrLine2[NumOfColumns-Count]),AttrDefault2,Count);
|
|
|
|
BuffUpdateRect(CursorX,CursorY,WinOrgX+WinWidth-1,CursorY);
|
|
}
|
|
|
|
void BuffEraseChars(int Count)
|
|
// Erase characters in current line from cursor
|
|
// Count: number of characters to be deleted
|
|
{
|
|
NewLine(PageStart+CursorY);
|
|
|
|
if (Count > NumOfColumns-CursorX) Count = NumOfColumns-CursorX;
|
|
memset(&(CodeLine[CursorX]),0x20,Count);
|
|
memset(&(AttrLine[CursorX]),AttrDefault,Count);
|
|
memset(&(AttrLine2[CursorX]),AttrDefault2,Count);
|
|
|
|
/* update window */
|
|
DispEraseCharsInLine(CursorX,Count);
|
|
}
|
|
|
|
void BuffFillWithE()
|
|
// Fill screen with 'E' characters
|
|
{
|
|
LONG TmpPtr;
|
|
int i;
|
|
|
|
TmpPtr = GetLinePtr(PageStart);
|
|
for (i = 0 ; i <= NumOfLines-1-StatusLine ; i++)
|
|
{
|
|
memset(&(CodeBuff[TmpPtr]),'E',NumOfColumns);
|
|
memset(&(AttrBuff[TmpPtr]),AttrDefault,NumOfColumns);
|
|
memset(&(AttrBuff2[TmpPtr]),AttrDefault2,NumOfColumns);
|
|
TmpPtr = NextLinePtr(TmpPtr);
|
|
}
|
|
BuffUpdateRect(WinOrgX,WinOrgY,WinOrgX+WinWidth-1,WinOrgY+WinHeight-1);
|
|
}
|
|
|
|
void BuffDrawLine(BYTE Attr, BYTE Attr2, int Direction, int C)
|
|
{ // IO-8256 terminal
|
|
LONG Ptr;
|
|
int i, X, Y;
|
|
|
|
if (C==0) return;
|
|
Attr = Attr | AttrSpecial;
|
|
|
|
switch (Direction) {
|
|
case 3:
|
|
case 4:
|
|
if (Direction==3)
|
|
{
|
|
if (CursorY==0) return;
|
|
Y = CursorY-1;
|
|
}
|
|
else {
|
|
if (CursorY==NumOfLines-1-StatusLine) return;
|
|
Y = CursorY+1;
|
|
}
|
|
if (CursorX+C > NumOfColumns)
|
|
C = NumOfColumns-CursorX;
|
|
Ptr = GetLinePtr(PageStart+Y);
|
|
memset(&(CodeBuff[Ptr+CursorX]),'q',C);
|
|
memset(&(AttrBuff[Ptr+CursorX]),Attr,C);
|
|
memset(&(AttrBuff2[Ptr+CursorX]),Attr2,C);
|
|
BuffUpdateRect(CursorX,Y,CursorX+C-1,Y);
|
|
break;
|
|
case 5:
|
|
case 6:
|
|
if (Direction==5)
|
|
{
|
|
if (CursorX==0) return;
|
|
X = CursorX - 1;
|
|
}
|
|
else {
|
|
if (CursorX==NumOfColumns-1)
|
|
X = CursorX-1;
|
|
else
|
|
X = CursorX+1;
|
|
}
|
|
Ptr = GetLinePtr(PageStart+CursorY);
|
|
if (CursorY+C > NumOfLines-StatusLine)
|
|
C = NumOfLines-StatusLine-CursorY;
|
|
for (i=1; i<=C; i++)
|
|
{
|
|
CodeBuff[Ptr+X] = 'x';
|
|
AttrBuff[Ptr+X] = Attr;
|
|
AttrBuff2[Ptr+X] = Attr2;
|
|
Ptr = NextLinePtr(Ptr);
|
|
}
|
|
BuffUpdateRect(X,CursorY,X,CursorY+C-1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void BuffEraseBox
|
|
(int XStart, int YStart, int XEnd, int YEnd)
|
|
// IO-8256 terminal
|
|
{
|
|
int C, i;
|
|
LONG Ptr;
|
|
|
|
if (XEnd>NumOfColumns-1)
|
|
XEnd = NumOfColumns-1;
|
|
if (YEnd>NumOfLines-1-StatusLine)
|
|
YEnd = NumOfLines-1-StatusLine;
|
|
if (XStart>XEnd) return;
|
|
if (YStart>YEnd) return;
|
|
C = XEnd-XStart+1;
|
|
Ptr = GetLinePtr(PageStart+YStart);
|
|
for (i=YStart; i<=YEnd; i++)
|
|
{
|
|
if ((XStart>0) &&
|
|
((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0))
|
|
{
|
|
CodeBuff[Ptr+XStart-1] = 0x20;
|
|
AttrBuff[Ptr+XStart-1] = AttrDefault;
|
|
AttrBuff2[Ptr+XStart-1] = AttrDefault2;
|
|
}
|
|
if ((XStart+C<NumOfColumns) &&
|
|
((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0))
|
|
{
|
|
CodeBuff[Ptr+XStart+C] = 0x20;
|
|
AttrBuff[Ptr+XStart+C] = AttrDefault;
|
|
AttrBuff2[Ptr+XStart+C] = AttrDefault2;
|
|
}
|
|
memset(&(CodeBuff[Ptr+XStart]),0x20,C);
|
|
memset(&(AttrBuff[Ptr+XStart]),AttrDefault,C);
|
|
memset(&(AttrBuff2[Ptr+XStart]),AttrDefault2,C);
|
|
Ptr = NextLinePtr(Ptr);
|
|
}
|
|
BuffUpdateRect(XStart,YStart,XEnd,YEnd);
|
|
}
|
|
|
|
int LeftHalfOfDBCS(LONG Line, int CharPtr)
|
|
// If CharPtr is on the right half of a DBCS character,
|
|
// return pointer to the left half
|
|
// Line: points to a line in CodeBuff
|
|
// CharPtr: points to a char
|
|
// return: points to the left half of the DBCS
|
|
{
|
|
if ((CharPtr>0) &&
|
|
((AttrBuff[Line+CharPtr-1] & AttrKanji) != 0))
|
|
CharPtr--;
|
|
return CharPtr;
|
|
}
|
|
|
|
int MoveCharPtr(LONG Line, int *x, int dx)
|
|
// move character pointer x by dx character unit
|
|
// in the line specified by Line
|
|
// Line: points to a line in CodeBuff
|
|
// x: points to a character in the line
|
|
// dx: moving distance in character unit (-: left, +: right)
|
|
// One DBCS character is counted as one character.
|
|
// The pointer stops at the beginning or the end of line.
|
|
// Output
|
|
// x: new pointer. x points to a SBCS character or
|
|
// the left half of a DBCS character.
|
|
// return: actual moving distance in character unit
|
|
{
|
|
int i;
|
|
|
|
*x = LeftHalfOfDBCS(Line,*x);
|
|
i = 0;
|
|
while (dx!=0)
|
|
{
|
|
if (dx>0) // move right
|
|
{
|
|
if ((AttrBuff[Line+*x] & AttrKanji) != 0)
|
|
{
|
|
if (*x<NumOfColumns-2)
|
|
{
|
|
i++;
|
|
*x = *x + 2;
|
|
}
|
|
}
|
|
else if (*x<NumOfColumns-1)
|
|
{
|
|
i++;
|
|
(*x)++;
|
|
}
|
|
dx--;
|
|
}
|
|
else { // move left
|
|
if (*x>0)
|
|
{
|
|
i--;
|
|
(*x)--;
|
|
}
|
|
*x = LeftHalfOfDBCS(Line,*x);
|
|
dx++;
|
|
}
|
|
}
|
|
return i;
|
|
}
|
|
|
|
void BuffCBCopy(BOOL Table)
|
|
// copy selected text to clipboard
|
|
{
|
|
LONG MemSize;
|
|
PCHAR CBPtr;
|
|
LONG TmpPtr;
|
|
int i, j, k, IStart, IEnd;
|
|
BOOL Sp, FirstChar;
|
|
BYTE b;
|
|
|
|
if (! Selected) return;
|
|
|
|
// --- open clipboard and get CB memory
|
|
if (BoxSelect)
|
|
MemSize = (SelectEnd.x-SelectStart.x+3)*
|
|
(SelectEnd.y-SelectStart.y+1) + 1;
|
|
else
|
|
MemSize = (SelectEnd.y-SelectStart.y)*
|
|
(NumOfColumns+2) +
|
|
SelectEnd.x - SelectStart.x + 1;
|
|
CBPtr = CBOpen(MemSize);
|
|
if (CBPtr==NULL) return;
|
|
|
|
// --- copy selected text to CB memory
|
|
LockBuffer();
|
|
|
|
CBPtr[0] = 0;
|
|
TmpPtr = GetLinePtr(SelectStart.y);
|
|
k = 0;
|
|
for (j = SelectStart.y ; j<=SelectEnd.y ; j++)
|
|
{
|
|
if (BoxSelect)
|
|
{
|
|
IStart = SelectStart.x;
|
|
IEnd = SelectEnd.x-1;
|
|
}
|
|
else {
|
|
IStart = 0;
|
|
IEnd = NumOfColumns-1;
|
|
if (j==SelectStart.y) IStart = SelectStart.x;
|
|
if (j==SelectEnd.y) IEnd = SelectEnd.x-1;
|
|
}
|
|
i = LeftHalfOfDBCS(TmpPtr,IStart);
|
|
if (i!=IStart)
|
|
{
|
|
if (j==SelectStart.y)
|
|
IStart = i;
|
|
else
|
|
IStart = i + 2;
|
|
}
|
|
|
|
// exclude right-side space characters
|
|
IEnd = LeftHalfOfDBCS(TmpPtr,IEnd);
|
|
while ((IEnd>0) && (CodeBuff[TmpPtr+IEnd]==0x20))
|
|
MoveCharPtr(TmpPtr,&IEnd,-1);
|
|
if ((IEnd==0) && (CodeBuff[TmpPtr]==0x20))
|
|
IEnd = -1;
|
|
else if ((AttrBuff[TmpPtr+IEnd] & AttrKanji) != 0) /* DBCS first byte? */
|
|
IEnd++;
|
|
|
|
Sp = FALSE;
|
|
FirstChar = TRUE;
|
|
i = IStart;
|
|
while (i <= IEnd)
|
|
{
|
|
b = CodeBuff[TmpPtr+i];
|
|
i++;
|
|
if (! Sp)
|
|
{
|
|
if ((Table) && (b<=0x20))
|
|
{
|
|
Sp = TRUE;
|
|
b = 0x09;
|
|
}
|
|
if ((b!=0x09) || (! FirstChar))
|
|
{
|
|
FirstChar = FALSE;
|
|
CBPtr[k] = b;
|
|
k++;
|
|
}
|
|
}
|
|
else {
|
|
if (b>0x20)
|
|
{
|
|
Sp = FALSE;
|
|
FirstChar = FALSE;
|
|
CBPtr[k] = b;
|
|
k++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (j < SelectEnd.y)
|
|
{
|
|
CBPtr[k] = 0x0d;
|
|
k++;
|
|
CBPtr[k] = 0x0a;
|
|
k++;
|
|
}
|
|
|
|
TmpPtr = NextLinePtr(TmpPtr);
|
|
}
|
|
CBPtr[k] = 0;
|
|
|
|
UnlockBuffer();
|
|
|
|
// --- send CB memory to clipboard
|
|
CBClose();
|
|
return;
|
|
}
|
|
|
|
void BuffPutChar(BYTE b, BYTE Attr, BYTE Attr2, BOOL Insert)
|
|
// Put a character in the buffer at the current position
|
|
// b: character
|
|
// Attr: attribute #1
|
|
// Attr2: attribute #2
|
|
// Insert: Insert flag
|
|
{
|
|
int XStart;
|
|
|
|
if (Insert)
|
|
{
|
|
memmove(&CodeLine[CursorX+1],&CodeLine[CursorX],NumOfColumns-1-CursorX);
|
|
memmove(&AttrLine[CursorX+1],&AttrLine[CursorX],NumOfColumns-1-CursorX);
|
|
memmove(&AttrLine2[CursorX+1],&AttrLine2[CursorX],NumOfColumns-1-CursorX);
|
|
CodeLine[CursorX] = b;
|
|
AttrLine[CursorX] = Attr;
|
|
AttrLine2[CursorX] = Attr2;
|
|
/* last char in current line is kanji first? */
|
|
if ((AttrLine[NumOfColumns-1] & AttrKanji) != 0)
|
|
{
|
|
/* then delete it */
|
|
CodeLine[NumOfColumns-1] = 0x20;
|
|
AttrLine[NumOfColumns-1] = AttrDefault;
|
|
AttrLine2[NumOfColumns-1] = AttrDefault2;
|
|
}
|
|
|
|
if (StrChangeCount==0) XStart = CursorX;
|
|
else XStart = StrChangeStart;
|
|
StrChangeCount = 0;
|
|
BuffUpdateRect(XStart,CursorY,NumOfColumns-1,CursorY);
|
|
}
|
|
else {
|
|
CodeLine[CursorX] = b;
|
|
AttrLine[CursorX] = Attr;
|
|
AttrLine2[CursorX] = Attr2;
|
|
|
|
if (StrChangeCount==0)
|
|
StrChangeStart = CursorX;
|
|
StrChangeCount++;
|
|
}
|
|
}
|
|
|
|
BOOL CheckSelect(int x, int y)
|
|
// subroutine called by BuffUpdateRect
|
|
{
|
|
LONG L, L1, L2;
|
|
|
|
if (BoxSelect)
|
|
{
|
|
return ((Selected &&
|
|
((SelectStart.x<=x) && (x<SelectEnd.x)) ||
|
|
((SelectEnd.x<=x) && (x<SelectStart.x)) &&
|
|
((SelectStart.y<=y) && (y<=SelectEnd.y)) ||
|
|
((SelectEnd.y<=y) && (y<=SelectStart.y))));
|
|
}
|
|
else {
|
|
L = MAKELONG(x,y);
|
|
L1 = MAKELONG(SelectStart.x,SelectStart.y);
|
|
L2 = MAKELONG(SelectEnd.x,SelectEnd.y);
|
|
|
|
return (Selected &&
|
|
(((L1<=L) && (L<L2)) || ((L2<=L) && (L<L1))));
|
|
}
|
|
}
|
|
|
|
void BuffUpdateRect
|
|
(int XStart, int YStart, int XEnd, int YEnd)
|
|
// Display text in a rectangular region in the screen
|
|
// XStart: x position of the upper-left corner (screen cordinate)
|
|
// YStart: y position
|
|
// XEnd: x position of the lower-right corner (last character)
|
|
// YEnd: y position
|
|
{
|
|
int i, j, count;
|
|
int IStart, IEnd;
|
|
int X, Y;
|
|
LONG TmpPtr;
|
|
BYTE CurAttr, TempAttr;
|
|
BYTE CurAttr2, TempAttr2;
|
|
BOOL CurSel, TempSel, Caret;
|
|
|
|
if (XStart >= WinOrgX+WinWidth) return;
|
|
if (YStart >= WinOrgY+WinHeight) return;
|
|
if (XEnd < WinOrgX) return;
|
|
if (YEnd < WinOrgY) return;
|
|
|
|
if (XStart < WinOrgX) XStart = WinOrgX;
|
|
if (YStart < WinOrgY) YStart = WinOrgY;
|
|
if (XEnd >= WinOrgX+WinWidth) XEnd = WinOrgX+WinWidth-1;
|
|
if (YEnd >= WinOrgY+WinHeight) YEnd = WinOrgY+WinHeight-1;
|
|
|
|
TempAttr = AttrDefault;
|
|
TempAttr2 = AttrDefault2;
|
|
TempSel = FALSE;
|
|
|
|
Caret = IsCaretOn();
|
|
if (Caret) CaretOff();
|
|
|
|
DispSetupDC(TempAttr,TempAttr2,TempSel);
|
|
|
|
Y = (YStart-WinOrgY)*FontHeight;
|
|
TmpPtr = GetLinePtr(PageStart+YStart);
|
|
for (j = YStart+PageStart ; j <= YEnd+PageStart ; j++)
|
|
{
|
|
IStart = XStart;
|
|
IEnd = XEnd;
|
|
|
|
IStart = LeftHalfOfDBCS(TmpPtr,IStart);
|
|
|
|
X = (IStart-WinOrgX)*FontWidth;
|
|
|
|
i = IStart;
|
|
do {
|
|
CurAttr = AttrBuff[TmpPtr+i] & ~ AttrKanji;
|
|
CurAttr2 = AttrBuff2[TmpPtr+i];
|
|
CurSel = CheckSelect(i,j);
|
|
count = 1;
|
|
while
|
|
(((i+count <= IEnd) &&
|
|
(CurAttr==
|
|
(AttrBuff[TmpPtr+i+count] & ~ AttrKanji)) &&
|
|
(CurAttr2==AttrBuff2[TmpPtr+i+count]) &&
|
|
(CurSel==CheckSelect(i+count,j))) ||
|
|
((i+count<NumOfColumns) &&
|
|
((AttrBuff[TmpPtr+i+count-1] & AttrKanji) != 0)))
|
|
count++;
|
|
|
|
if ((CurAttr != TempAttr) ||
|
|
(CurAttr2 != TempAttr2) ||
|
|
(CurSel != TempSel))
|
|
{
|
|
DispSetupDC(CurAttr,CurAttr2,CurSel);
|
|
TempAttr = CurAttr;
|
|
TempAttr2 = CurAttr2;
|
|
TempSel = CurSel;
|
|
}
|
|
DispStr(&CodeBuff[TmpPtr+i],count,Y, &X);
|
|
i = i+count;
|
|
}
|
|
while (i<=IEnd);
|
|
Y = Y + FontHeight;
|
|
TmpPtr = NextLinePtr(TmpPtr);
|
|
}
|
|
if (Caret) CaretOn();
|
|
}
|
|
|
|
void UpdateStr()
|
|
// Display not-yet-displayed string
|
|
{
|
|
int X, Y;
|
|
|
|
if (StrChangeCount==0) return;
|
|
X = StrChangeStart;
|
|
Y = CursorY;
|
|
if (! IsLineVisible(&X, &Y))
|
|
{
|
|
StrChangeCount = 0;
|
|
return;
|
|
}
|
|
|
|
DispSetupDC(AttrLine[StrChangeStart],
|
|
AttrLine2[StrChangeStart],FALSE);
|
|
DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
|
|
StrChangeCount = 0;
|
|
}
|
|
|
|
void MoveCursor(int Xnew, int Ynew)
|
|
{
|
|
UpdateStr();
|
|
|
|
if (CursorY!=Ynew) NewLine(PageStart+Ynew);
|
|
|
|
CursorX = Xnew;
|
|
CursorY = Ynew;
|
|
Wrap = FALSE;
|
|
|
|
DispScrollToCursor(CursorX, CursorY);
|
|
}
|
|
|
|
void MoveRight()
|
|
/* move cursor right, but dont update screen.
|
|
this procedure must be called from DispChar&DispKanji only */
|
|
{
|
|
CursorX++;
|
|
DispScrollToCursor(CursorX, CursorY);
|
|
}
|
|
|
|
void MoveLeft()
|
|
/* move cursor right, but dont update screen.
|
|
this procedure must be called from DispChar&DispKanji only */
|
|
{
|
|
CursorX--;
|
|
DispScrollToCursor(CursorX, CursorY);
|
|
}
|
|
|
|
void BuffSetCaretWidth()
|
|
{
|
|
BOOL DW;
|
|
|
|
/* check whether cursor on a DBCS character */
|
|
DW = (((BYTE)(AttrLine[CursorX]) & AttrKanji) != 0);
|
|
DispSetCaretWidth(DW);
|
|
}
|
|
|
|
void ScrollUp1Line()
|
|
{
|
|
int i;
|
|
LONG SrcPtr = 0, DestPtr;
|
|
|
|
if ((CursorTop<=CursorY) && (CursorY<=CursorBottom))
|
|
{
|
|
UpdateStr();
|
|
|
|
DestPtr = GetLinePtr(PageStart+CursorBottom);
|
|
for (i = CursorBottom-1 ; i >= CursorTop ; i--)
|
|
{
|
|
SrcPtr = PrevLinePtr(DestPtr);
|
|
memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
|
|
memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
|
|
memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
|
|
DestPtr = SrcPtr;
|
|
}
|
|
memset(&(CodeBuff[SrcPtr]),0x20,NumOfColumns);
|
|
memset(&(AttrBuff[SrcPtr]),AttrDefault,NumOfColumns);
|
|
memset(&(AttrBuff2[SrcPtr]),AttrDefault2,NumOfColumns);
|
|
|
|
DispScrollNLines(CursorTop,CursorBottom,-1);
|
|
}
|
|
}
|
|
|
|
void BuffScrollNLines(int n)
|
|
{
|
|
int i;
|
|
LONG SrcPtr, DestPtr;
|
|
|
|
if (n<1) return;
|
|
UpdateStr();
|
|
|
|
if ((CursorTop == 0) && (CursorBottom == NumOfLines-1))
|
|
{
|
|
WinOrgY = WinOrgY-n;
|
|
BuffScroll(n,CursorBottom);
|
|
DispCountScroll(n);
|
|
}
|
|
else if ((CursorTop==0) && (CursorY<=CursorBottom))
|
|
{
|
|
BuffScroll(n,CursorBottom);
|
|
DispScrollNLines(WinOrgY,CursorBottom,n);
|
|
}
|
|
else if ((CursorTop<=CursorY) && (CursorY<=CursorBottom))
|
|
{
|
|
DestPtr = GetLinePtr(PageStart+CursorTop);
|
|
if (n<CursorBottom-CursorTop+1)
|
|
{
|
|
SrcPtr = GetLinePtr(PageStart+CursorTop+n);
|
|
for (i = CursorTop+n ; i<=CursorBottom ; i++)
|
|
{
|
|
memmove(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
|
|
memmove(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
|
|
memmove(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
|
|
SrcPtr = NextLinePtr(SrcPtr);
|
|
DestPtr = NextLinePtr(DestPtr);
|
|
}
|
|
}
|
|
else
|
|
n = CursorBottom-CursorTop+1;
|
|
for (i = CursorBottom+1-n ; i<=CursorBottom; i++)
|
|
{
|
|
memset(&(CodeBuff[DestPtr]),0x20,NumOfColumns);
|
|
memset(&(AttrBuff[DestPtr]),AttrDefault,NumOfColumns);
|
|
memset(&(AttrBuff2[DestPtr]),AttrDefault2,NumOfColumns);
|
|
DestPtr = NextLinePtr(DestPtr);
|
|
}
|
|
DispScrollNLines(CursorTop,CursorBottom,n);
|
|
}
|
|
}
|
|
|
|
void BuffClearScreen()
|
|
{ // clear screen
|
|
if ((StatusLine>0) && (CursorY==NumOfLines-1))
|
|
BuffScrollNLines(1); /* clear status line */
|
|
else { /* clear main screen */
|
|
UpdateStr();
|
|
BuffScroll(NumOfLines-StatusLine,NumOfLines-1-StatusLine);
|
|
DispScrollNLines(WinOrgY,NumOfLines-1-StatusLine,NumOfLines-StatusLine);
|
|
}
|
|
}
|
|
|
|
void BuffUpdateScroll()
|
|
// Updates scrolling
|
|
{
|
|
UpdateStr();
|
|
DispUpdateScroll();
|
|
}
|
|
|
|
void CursorUpWithScroll()
|
|
{
|
|
if (((0<CursorY) && (CursorY<CursorTop)) ||
|
|
(CursorTop<CursorY))
|
|
MoveCursor(CursorX,CursorY-1);
|
|
else if (CursorY==CursorTop)
|
|
ScrollUp1Line();
|
|
}
|
|
|
|
// called by BuffDblClk --- Remove this!!! Brian
|
|
// check if a character is the word delimiter
|
|
BOOL IsDelimiter(LONG Line, int CharPtr)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void GetMinMax(int i1, int i2, int i3,
|
|
int *min, int *max)
|
|
{
|
|
if (i1<i2)
|
|
{
|
|
*min = i1;
|
|
*max = i2;
|
|
}
|
|
else {
|
|
*min = i2;
|
|
*max = i1;
|
|
}
|
|
if (i3<*min)
|
|
*min = i3;
|
|
if (i3>*max)
|
|
*max = i3;
|
|
}
|
|
|
|
void ChangeSelectRegion()
|
|
{
|
|
POINT TempStart, TempEnd;
|
|
int j, IStart, IEnd;
|
|
BOOL Caret;
|
|
|
|
if ((SelectEndOld.x==SelectEnd.x) &&
|
|
(SelectEndOld.y==SelectEnd.y)) return;
|
|
|
|
if (BoxSelect)
|
|
{
|
|
GetMinMax(SelectStart.x,SelectEndOld.x,SelectEnd.x,
|
|
(int *)&TempStart.x,(int *)&TempEnd.x);
|
|
GetMinMax(SelectStart.y,SelectEndOld.y,SelectEnd.y,
|
|
(int *)&TempStart.y,(int *)&TempEnd.y);
|
|
TempEnd.x--;
|
|
Caret = IsCaretOn();
|
|
if (Caret) CaretOff();
|
|
DispInitDC();
|
|
BuffUpdateRect(TempStart.x,TempStart.y-PageStart,
|
|
TempEnd.x,TempEnd.y-PageStart);
|
|
DispReleaseDC();
|
|
if (Caret) CaretOn();
|
|
SelectEndOld = SelectEnd;
|
|
return;
|
|
}
|
|
|
|
if ((SelectEndOld.y < SelectEnd.y) ||
|
|
((SelectEndOld.y==SelectEnd.y) &&
|
|
(SelectEndOld.x<=SelectEnd.x)))
|
|
{
|
|
TempStart = SelectEndOld;
|
|
TempEnd.x = SelectEnd.x-1;
|
|
TempEnd.y = SelectEnd.y;
|
|
}
|
|
else {
|
|
TempStart = SelectEnd;
|
|
TempEnd.x = SelectEndOld.x-1;
|
|
TempEnd.y = SelectEndOld.y;
|
|
}
|
|
if (TempEnd.x < 0)
|
|
{
|
|
TempEnd.x = NumOfColumns - 1;
|
|
TempEnd.y--;
|
|
}
|
|
|
|
Caret = IsCaretOn();
|
|
if (Caret) CaretOff();
|
|
for (j = TempStart.y ; j <= TempEnd.y ; j++)
|
|
{
|
|
IStart = 0;
|
|
IEnd = NumOfColumns-1;
|
|
if (j==TempStart.y) IStart = TempStart.x;
|
|
if (j==TempEnd.y) IEnd = TempEnd.x;
|
|
|
|
if ((IEnd>=IStart) && (j >= PageStart+WinOrgY) &&
|
|
(j < PageStart+WinOrgY+WinHeight))
|
|
{
|
|
DispInitDC();
|
|
BuffUpdateRect(IStart,j-PageStart,IEnd,j-PageStart);
|
|
DispReleaseDC();
|
|
}
|
|
}
|
|
if (Caret) CaretOn();
|
|
|
|
SelectEndOld = SelectEnd;
|
|
}
|
|
|
|
void BuffDblClk(int Xw, int Yw)
|
|
// Select a word at (Xw, Yw) by mouse double click
|
|
// Xw: horizontal position in window coordinate (pixels)
|
|
// Yw: vertical
|
|
{
|
|
int X, Y;
|
|
int IStart, IEnd, i;
|
|
LONG TmpPtr;
|
|
BYTE b;
|
|
BOOL DBCS;
|
|
|
|
CaretOff();
|
|
|
|
DispConvWinToScreen(Xw,Yw,&X,&Y,NULL);
|
|
Y = Y + PageStart;
|
|
if ((Y<0) || (Y>=BuffEnd)) return;
|
|
if (X<0) X = 0;
|
|
if (X>=NumOfColumns) X = NumOfColumns-1;
|
|
|
|
BoxSelect = FALSE;
|
|
LockBuffer();
|
|
SelectEnd = SelectStart;
|
|
ChangeSelectRegion();
|
|
|
|
if ((Y>=0) && (Y<BuffEnd))
|
|
{
|
|
TmpPtr = GetLinePtr(Y);
|
|
|
|
IStart = X;
|
|
IStart = LeftHalfOfDBCS(TmpPtr,IStart);
|
|
IEnd = IStart;
|
|
|
|
if (IsDelimiter(TmpPtr,IStart))
|
|
{
|
|
b = CodeBuff[TmpPtr+IStart];
|
|
DBCS = (AttrBuff[TmpPtr+IStart] & AttrKanji) != 0;
|
|
while (((IStart>0) &&
|
|
((b==CodeBuff[TmpPtr+IStart])) ||
|
|
(DBCS &&
|
|
((AttrBuff[TmpPtr+IStart] & AttrKanji)!=0))))
|
|
MoveCharPtr(TmpPtr,&IStart,-1); // move left
|
|
if ((b!=CodeBuff[TmpPtr+IStart]) &&
|
|
! (DBCS &&
|
|
((AttrBuff[TmpPtr+IStart] & AttrKanji)!=0)))
|
|
MoveCharPtr(TmpPtr,&IStart,1);
|
|
|
|
i = 1;
|
|
while (((i!=0) &&
|
|
((b==CodeBuff[TmpPtr+IEnd])) ||
|
|
(DBCS &&
|
|
((AttrBuff[TmpPtr+IEnd] & AttrKanji)!=0))))
|
|
i = MoveCharPtr(TmpPtr,&IEnd,1); // move right
|
|
}
|
|
else {
|
|
while ((IStart>0) &&
|
|
! IsDelimiter(TmpPtr,IStart))
|
|
MoveCharPtr(TmpPtr,&IStart,-1); // move left
|
|
if (IsDelimiter(TmpPtr,IStart))
|
|
MoveCharPtr(TmpPtr,&IStart,1);
|
|
|
|
i = 1;
|
|
while ((i!=0) &&
|
|
! IsDelimiter(TmpPtr,IEnd))
|
|
i = MoveCharPtr(TmpPtr,&IEnd,1); // move right
|
|
}
|
|
if (i==0)
|
|
IEnd = NumOfColumns;
|
|
|
|
if (IStart<=X)
|
|
{
|
|
SelectStart.x = IStart;
|
|
SelectStart.y = Y;
|
|
SelectEnd.x = IEnd;
|
|
SelectEnd.y = Y;
|
|
SelectEndOld = SelectStart;
|
|
DblClkStart = SelectStart;
|
|
DblClkEnd = SelectEnd;
|
|
Selected = TRUE;
|
|
ChangeSelectRegion();
|
|
}
|
|
}
|
|
UnlockBuffer();
|
|
}
|
|
|
|
void BuffTplClk(int Yw)
|
|
// Select a line at Yw by mouse tripple click
|
|
// Yw: vertical clicked position
|
|
// in window coordinate (pixels)
|
|
{
|
|
int Y;
|
|
|
|
CaretOff();
|
|
|
|
DispConvWinToScreen(0,Yw,NULL,&Y,NULL);
|
|
Y = Y + PageStart;
|
|
if ((Y<0) || (Y>=BuffEnd)) return;
|
|
|
|
LockBuffer();
|
|
SelectEnd = SelectStart;
|
|
ChangeSelectRegion();
|
|
SelectStart.x = 0;
|
|
SelectStart.y = Y;
|
|
SelectEnd.x = NumOfColumns;
|
|
SelectEnd.y = Y;
|
|
SelectEndOld = SelectStart;
|
|
DblClkStart = SelectStart;
|
|
DblClkEnd = SelectEnd;
|
|
Selected = TRUE;
|
|
ChangeSelectRegion();
|
|
UnlockBuffer();
|
|
}
|
|
|
|
void BuffStartSelect(int Xw, int Yw, BOOL Box)
|
|
// Start text selection by mouse button down
|
|
// Xw: horizontal position in window coordinate (pixels)
|
|
// Yw: vertical
|
|
// Box: Box selection if TRUE
|
|
{
|
|
int X, Y;
|
|
BOOL Right;
|
|
LONG TmpPtr;
|
|
|
|
DispConvWinToScreen(Xw,Yw, &X,&Y,&Right);
|
|
Y = Y + PageStart;
|
|
if ((Y<0) || (Y>=BuffEnd)) return;
|
|
if (X<0) X = 0;
|
|
if (X>=NumOfColumns) X = NumOfColumns-1;
|
|
|
|
SelectEndOld = SelectEnd;
|
|
SelectEnd = SelectStart;
|
|
|
|
LockBuffer();
|
|
ChangeSelectRegion();
|
|
UnlockBuffer();
|
|
|
|
SelectStart.x = X;
|
|
SelectStart.y = Y;
|
|
if (SelectStart.x<0) SelectStart.x = 0;
|
|
if (SelectStart.x > NumOfColumns)
|
|
SelectStart.x = NumOfColumns;
|
|
if (SelectStart.y < 0) SelectStart.y = 0;
|
|
if (SelectStart.y >= BuffEnd)
|
|
SelectStart.y = BuffEnd - 1;
|
|
|
|
TmpPtr = GetLinePtr(SelectStart.y);
|
|
// check if the cursor is on the right half of a character
|
|
if (((SelectStart.x>0) &&
|
|
((AttrBuff[TmpPtr+SelectStart.x-1] & AttrKanji) != 0)) ||
|
|
(((AttrBuff[TmpPtr+SelectStart.x] & AttrKanji) == 0) &&
|
|
Right)) SelectStart.x++;
|
|
|
|
SelectEnd = SelectStart;
|
|
SelectEndOld = SelectEnd;
|
|
CaretOff();
|
|
Selected = TRUE;
|
|
BoxSelect = Box;
|
|
}
|
|
|
|
void BuffChangeSelect(int Xw, int Yw, int NClick)
|
|
// Change selection region by mouse move
|
|
// Xw: horizontal position of the mouse cursor
|
|
// in window coordinate
|
|
// Yw: vertical
|
|
{
|
|
int X, Y;
|
|
BOOL Right;
|
|
LONG TmpPtr;
|
|
int i;
|
|
BYTE b;
|
|
BOOL DBCS;
|
|
|
|
DispConvWinToScreen(Xw,Yw,&X,&Y,&Right);
|
|
Y = Y + PageStart;
|
|
|
|
if (X<0) X = 0;
|
|
if (X > NumOfColumns)
|
|
X = NumOfColumns;
|
|
if (Y < 0) Y = 0;
|
|
if (Y >= BuffEnd)
|
|
Y = BuffEnd - 1;
|
|
|
|
TmpPtr = GetLinePtr(Y);
|
|
LockBuffer();
|
|
// check if the cursor is on the right half of a character
|
|
if (((X>0) &&
|
|
((AttrBuff[TmpPtr+X-1] & AttrKanji) != 0)) ||
|
|
((X<NumOfColumns) &&
|
|
((AttrBuff[TmpPtr+X] & AttrKanji) == 0) &&
|
|
Right)) X++;
|
|
|
|
if (X > NumOfColumns)
|
|
X = NumOfColumns;
|
|
|
|
SelectEnd.x = X;
|
|
SelectEnd.y = Y;
|
|
|
|
if (NClick==2) // drag after double click
|
|
{
|
|
if ((SelectEnd.y>SelectStart.y) ||
|
|
(SelectEnd.y==SelectStart.y) &&
|
|
(SelectEnd.x>=SelectStart.x))
|
|
{
|
|
if (SelectStart.x==DblClkEnd.x)
|
|
{
|
|
SelectEnd = DblClkStart;
|
|
ChangeSelectRegion();
|
|
SelectStart = DblClkStart;
|
|
SelectEnd.x = X;
|
|
SelectEnd.y = Y;
|
|
}
|
|
MoveCharPtr(TmpPtr,&X,-1);
|
|
if (X<SelectStart.x) X = SelectStart.x;
|
|
|
|
i = 1;
|
|
if (IsDelimiter(TmpPtr,X))
|
|
{
|
|
b = CodeBuff[TmpPtr+X];
|
|
DBCS = (AttrBuff[TmpPtr+X] & AttrKanji) != 0;
|
|
while (((i!=0) &&
|
|
((b==CodeBuff[TmpPtr+SelectEnd.x])) ||
|
|
(DBCS &&
|
|
((AttrBuff[TmpPtr+SelectEnd.x] & AttrKanji)!=0))))
|
|
i = MoveCharPtr(TmpPtr,(int *)&SelectEnd.x,1); // move right
|
|
}
|
|
else {
|
|
while ((i!=0) &&
|
|
! IsDelimiter(TmpPtr,SelectEnd.x))
|
|
i = MoveCharPtr(TmpPtr,(int *)&SelectEnd.x,1); // move right
|
|
}
|
|
if (i==0)
|
|
SelectEnd.x = NumOfColumns;
|
|
}
|
|
else {
|
|
if (SelectStart.x==DblClkStart.x)
|
|
{
|
|
SelectEnd = DblClkEnd;
|
|
ChangeSelectRegion();
|
|
SelectStart = DblClkEnd;
|
|
SelectEnd.x = X;
|
|
SelectEnd.y = Y;
|
|
}
|
|
if (IsDelimiter(TmpPtr,SelectEnd.x))
|
|
{
|
|
b = CodeBuff[TmpPtr+SelectEnd.x];
|
|
DBCS = (AttrBuff[TmpPtr+SelectEnd.x] & AttrKanji) != 0;
|
|
while (((SelectEnd.x>0) &&
|
|
((b==CodeBuff[TmpPtr+SelectEnd.x])) ||
|
|
(DBCS &&
|
|
((AttrBuff[TmpPtr+SelectEnd.x] & AttrKanji)!=0))))
|
|
MoveCharPtr(TmpPtr,(int *)&SelectEnd.x,-1); // move left
|
|
if ((b!=CodeBuff[TmpPtr+SelectEnd.x]) &&
|
|
! (DBCS &&
|
|
((AttrBuff[TmpPtr+SelectEnd.x] & AttrKanji)!=0)))
|
|
MoveCharPtr(TmpPtr,(int *)&SelectEnd.x,1);
|
|
}
|
|
else {
|
|
while ((SelectEnd.x>0) &&
|
|
! IsDelimiter(TmpPtr,SelectEnd.x))
|
|
MoveCharPtr(TmpPtr,(int *)&SelectEnd.x,-1); // move left
|
|
if (IsDelimiter(TmpPtr,SelectEnd.x))
|
|
MoveCharPtr(TmpPtr,(int *)&SelectEnd.x,1);
|
|
}
|
|
}
|
|
}
|
|
else if (NClick==3) // drag after tripple click
|
|
{
|
|
if (((SelectEnd.y>SelectStart.y) ||
|
|
(SelectEnd.y==SelectStart.y)) &&
|
|
(SelectEnd.x>=SelectStart.x))
|
|
{
|
|
if (SelectStart.x==DblClkEnd.x)
|
|
{
|
|
SelectEnd = DblClkStart;
|
|
ChangeSelectRegion();
|
|
SelectStart = DblClkStart;
|
|
SelectEnd.x = X;
|
|
SelectEnd.y = Y;
|
|
}
|
|
SelectEnd.x = NumOfColumns;
|
|
}
|
|
else {
|
|
if (SelectStart.x==DblClkStart.x)
|
|
{
|
|
SelectEnd = DblClkEnd;
|
|
ChangeSelectRegion();
|
|
SelectStart = DblClkEnd;
|
|
SelectEnd.x = X;
|
|
SelectEnd.y = Y;
|
|
}
|
|
SelectEnd.x = 0;
|
|
}
|
|
}
|
|
|
|
ChangeSelectRegion();
|
|
UnlockBuffer();
|
|
}
|
|
|
|
void BuffEndSelect()
|
|
// End text selection by mouse button up
|
|
{
|
|
Selected = (SelectStart.x!=SelectEnd.x) ||
|
|
(SelectStart.y!=SelectEnd.y);
|
|
if (Selected)
|
|
{
|
|
if (BoxSelect)
|
|
{
|
|
if (SelectStart.x>SelectEnd.x)
|
|
{
|
|
SelectEndOld.x = SelectStart.x;
|
|
SelectStart.x = SelectEnd.x;
|
|
SelectEnd.x = SelectEndOld.x;
|
|
}
|
|
if (SelectStart.y>SelectEnd.y)
|
|
{
|
|
SelectEndOld.y = SelectStart.y;
|
|
SelectStart.y = SelectEnd.y;
|
|
SelectEnd.y = SelectEndOld.y;
|
|
}
|
|
}
|
|
else if ((SelectEnd.y < SelectStart.y) ||
|
|
((SelectEnd.y == SelectStart.y) &&
|
|
(SelectEnd.x < SelectStart.x)))
|
|
{
|
|
SelectEndOld = SelectStart;
|
|
SelectStart = SelectEnd;
|
|
SelectEnd = SelectEndOld;
|
|
}
|
|
/* copy to the clipboard */
|
|
LockBuffer();
|
|
BuffCBCopy(FALSE);
|
|
UnlockBuffer();
|
|
}
|
|
}
|
|
|
|
void BuffChangeWinSize(int Nx, int Ny)
|
|
// Change window size
|
|
// Nx: new window width (number of characters)
|
|
// Ny: new window hight
|
|
{
|
|
if (Nx==0) Nx = 1;
|
|
if (Ny==0) Ny = 1;
|
|
|
|
if (((Nx!=NumOfColumns) || (Ny!=NumOfLines)))
|
|
{
|
|
LockBuffer();
|
|
BuffChangeTerminalSize(Nx,Ny-StatusLine);
|
|
UnlockBuffer();
|
|
Nx = NumOfColumns;
|
|
Ny = NumOfLines;
|
|
}
|
|
if (Nx>NumOfColumns) Nx = NumOfColumns;
|
|
if (Ny>BuffEnd) Ny = BuffEnd;
|
|
DispChangeWinSize(Nx,Ny);
|
|
}
|
|
|
|
void BuffChangeTerminalSize(int Nx, int Ny)
|
|
{
|
|
int i, Nb, W, H;
|
|
BOOL St;
|
|
|
|
Ny = Ny + StatusLine;
|
|
if (Nx < 1) Nx = 1;
|
|
if (Ny < 1) Ny = 1;
|
|
if (Nx > BuffXMax) Nx = BuffXMax;
|
|
St = ((StatusLine>0) && (CursorY==NumOfLines-1));
|
|
if ((Nx!=NumOfColumns) || (Ny!=NumOfLines))
|
|
{
|
|
Nb = Ny;
|
|
|
|
if (! ChangeBuffer(Nx,Nb)) return;
|
|
if (Ny > NumOfLinesInBuff) Ny = NumOfLinesInBuff;
|
|
|
|
NumOfColumns = Nx;
|
|
NumOfLines = Ny;
|
|
/*ts.TerminalWidth = Nx;
|
|
ts.TerminalHeight = Ny-StatusLine;*/
|
|
|
|
PageStart = BuffEnd - NumOfLines;
|
|
}
|
|
BuffScroll(NumOfLines,NumOfLines-1);
|
|
/* Set Cursor */
|
|
CursorX = 0;
|
|
if (St)
|
|
{
|
|
CursorY = NumOfLines-1;
|
|
CursorTop = CursorY;
|
|
CursorBottom = CursorY;
|
|
}
|
|
else {
|
|
CursorY = 0;
|
|
CursorTop = 0;
|
|
CursorBottom = NumOfLines-1-StatusLine;
|
|
}
|
|
|
|
SelectStart.x = 0;
|
|
SelectStart.y = 0;
|
|
SelectEnd = SelectStart;
|
|
Selected = FALSE;
|
|
|
|
/* Tab stops */
|
|
NTabStops = (NumOfColumns-1) >> 3;
|
|
for (i = 1 ; i <= NTabStops ; i++)
|
|
TabStops[i-1] = i*8;
|
|
|
|
W = NumOfColumns;
|
|
H = NumOfLines;
|
|
|
|
NewLine(PageStart+CursorY);
|
|
|
|
/* Change Window Size */
|
|
BuffChangeWinSize(W,H);
|
|
WinOrgY = -NumOfLines;
|
|
DispScrollHomePos();
|
|
}
|
|
|
|
void ChangeWin()
|
|
{
|
|
int Ny;
|
|
|
|
/* Change buffer */
|
|
Ny = NumOfLines;
|
|
|
|
if (NumOfLinesInBuff!=Ny)
|
|
{
|
|
ChangeBuffer(NumOfColumns,Ny);
|
|
|
|
if (BuffEnd < WinHeight)
|
|
BuffChangeWinSize(WinWidth,BuffEnd);
|
|
else
|
|
BuffChangeWinSize(WinWidth,WinHeight);
|
|
}
|
|
|
|
DispChangeWin();
|
|
}
|
|
|
|
void ClearBuffer()
|
|
{
|
|
/* Reset buffer */
|
|
PageStart = 0;
|
|
BuffStartAbs = 0;
|
|
BuffEnd = NumOfLines;
|
|
if (NumOfLines==NumOfLinesInBuff)
|
|
BuffEndAbs = 0;
|
|
else
|
|
BuffEndAbs = NumOfLines;
|
|
|
|
SelectStart.x = 0;
|
|
SelectStart.y = 0;
|
|
SelectEnd = SelectStart;
|
|
SelectEndOld = SelectStart;
|
|
Selected = FALSE;
|
|
|
|
NewLine(0);
|
|
memset(&CodeBuff[0],0x20,BufferSize);
|
|
memset(&AttrBuff[0],AttrDefault,BufferSize);
|
|
memset(&AttrBuff2[0],AttrDefault2,BufferSize);
|
|
|
|
/* Home position */
|
|
CursorX = 0;
|
|
CursorY = 0;
|
|
WinOrgX = 0;
|
|
WinOrgY = 0;
|
|
NewOrgX = 0;
|
|
NewOrgY = 0;
|
|
|
|
/* Top/bottom margin */
|
|
CursorTop = 0;
|
|
CursorBottom = NumOfLines-1;
|
|
|
|
StrChangeCount = 0;
|
|
|
|
DispClearWin();
|
|
}
|
|
|
|
void SetTabStop()
|
|
{
|
|
int i,j;
|
|
|
|
if (NTabStops<NumOfColumns)
|
|
{
|
|
i = 0;
|
|
while ((TabStops[i]<CursorX) && (i<NTabStops))
|
|
i++;
|
|
|
|
if ((i<NTabStops) && (TabStops[i]==CursorX)) return;
|
|
|
|
for (j=NTabStops ; j>=i+1 ; j--)
|
|
TabStops[j] = TabStops[j-1];
|
|
TabStops[i] = CursorX;
|
|
NTabStops++;
|
|
}
|
|
}
|
|
|
|
void MoveToNextTab()
|
|
{
|
|
int i;
|
|
|
|
if (NTabStops>0)
|
|
{
|
|
i = -1;
|
|
do
|
|
i++;
|
|
while ((TabStops[i]<=CursorX) && (i<NTabStops-1));
|
|
if (TabStops[i]>CursorX)
|
|
MoveCursor(TabStops[i],CursorY);
|
|
else
|
|
MoveCursor(NumOfColumns-1,CursorY);
|
|
}
|
|
else
|
|
MoveCursor(NumOfColumns-1,CursorY);
|
|
}
|
|
|
|
void ClearTabStop(int Ps)
|
|
// Clear tab stops
|
|
// Ps = 0: clear the tab stop at cursor
|
|
// = 3: clear all tab stops
|
|
{
|
|
int i,j;
|
|
|
|
if (NTabStops>0)
|
|
switch (Ps) {
|
|
case 0:
|
|
i = 0;
|
|
while ((TabStops[i]!=CursorX) && (i<NTabStops-1))
|
|
i++;
|
|
if (TabStops[i] == CursorX)
|
|
{
|
|
NTabStops--;
|
|
for (j=i ; j<=NTabStops ; j++)
|
|
TabStops[j] = TabStops[j+1];
|
|
}
|
|
break;
|
|
case 3: NTabStops = 0; break;
|
|
}
|
|
}
|
|
|
|
void ShowStatusLine(int Show)
|
|
// show/hide status line
|
|
{
|
|
int Ny = 0, Nb, W, H;
|
|
|
|
BuffUpdateScroll();
|
|
if (Show==StatusLine) return;
|
|
StatusLine = Show;
|
|
|
|
if (StatusLine==0)
|
|
{
|
|
NumOfLines--;
|
|
BuffEnd--;
|
|
BuffEndAbs=PageStart+NumOfLines;
|
|
if (BuffEndAbs >= NumOfLinesInBuff)
|
|
BuffEndAbs = BuffEndAbs-NumOfLinesInBuff;
|
|
Ny = NumOfLines;
|
|
}
|
|
/*else
|
|
Ny = ts.TerminalHeight+1;*/
|
|
|
|
Nb = Ny;
|
|
|
|
if (! ChangeBuffer(NumOfColumns,Nb)) return;
|
|
if (Ny > NumOfLinesInBuff) Ny = NumOfLinesInBuff;
|
|
|
|
NumOfLines = Ny;
|
|
|
|
if (StatusLine==1)
|
|
BuffScroll(1,NumOfLines-1);
|
|
|
|
W = NumOfColumns;
|
|
H = NumOfLines;
|
|
|
|
PageStart = BuffEnd-NumOfLines;
|
|
NewLine(PageStart+CursorY);
|
|
|
|
/* Change Window Size */
|
|
BuffChangeWinSize(W,H);
|
|
WinOrgY = -NumOfLines;
|
|
DispScrollHomePos();
|
|
|
|
MoveCursor(CursorX,CursorY);
|
|
}
|
|
/* End Scrollback code */
|
|
|
|
void winbx_init(void)
|
|
{
|
|
WNDCLASS wc;
|
|
DWORD Style;
|
|
MSG msg;
|
|
|
|
MsgDlgHelp = RegisterWindowMessage(HELPMSGSTRING);
|
|
|
|
#if 0
|
|
InitKeyboard();
|
|
SetKeyMap();
|
|
#endif
|
|
|
|
/* Initialize scroll buffer */
|
|
InitBuffer();
|
|
|
|
InitDisp();
|
|
|
|
Style = WS_VSCROLL | WS_HSCROLL |
|
|
WS_BORDER | WS_THICKFRAME |
|
|
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
|
|
|
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
|
|
wc.lpfnWndProc = AfxWndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
/*wc.hInstance = AfxGetInstanceHandle();*/
|
|
/*wc.hIcon = LoadIcon(wc.hInstance, MAKEINTRESOURCE(IDI_VT));*/
|
|
wc.hCursor = LoadCursor(NULL,IDC_IBEAM);
|
|
wc.hbrBackground = NULL;
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = "VTWin";
|
|
|
|
RegisterClass(&wc);
|
|
|
|
HVTWin = CreateWindow("VTWin", _VERSION_, Style, 100, 100, 300, 400, NULL, NULL, &wc.hInstance, NULL);
|
|
|
|
if (HVTWin == NULL) return;
|
|
|
|
// set the small icon
|
|
/* PostMessage(HVTWin,WM_SETICON,0,
|
|
(LPARAM)LoadImage(AfxGetInstanceHandle(),
|
|
MAKEINTRESOURCE(IDI_VT),
|
|
IMAGE_ICON,16,16,0));*/
|
|
|
|
/* Reset Terminal */
|
|
ResetTerminal();
|
|
|
|
ChangeFont();
|
|
|
|
BuffChangeWinSize(NumOfColumns,NumOfLines);
|
|
|
|
ShowWindow(HVTWin, SW_SHOWDEFAULT);
|
|
ChangeCaret();
|
|
|
|
current_term->TI_cols = co = 81;
|
|
current_term->TI_lines = li = 25;
|
|
|
|
#if 0
|
|
while (GetMessage(&msg,NULL,0,0)) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void gui_init(void)
|
|
{
|
|
winbx_init();
|
|
#if 0
|
|
_beginthread((void *)winbx_init, 0xFFFF, NULL);
|
|
CreateThread(NULL, 0, (void *)winbx_init, NULL, 0, NULL);
|
|
Sleep(2000);
|
|
#endif
|
|
}
|
|
|
|
void gui_clreol(void)
|
|
{
|
|
}
|
|
|
|
void gui_gotoxy(int col, int row)
|
|
{
|
|
/*MoveCursor(col, row);*/
|
|
}
|
|
|
|
void gui_clrscr(void)
|
|
{
|
|
/* BuffClearScreen();*/
|
|
}
|
|
|
|
void gui_left(int num)
|
|
{
|
|
/* int z;
|
|
|
|
for(z=0;z<num;z++)
|
|
MoveLeft();*/
|
|
}
|
|
|
|
void gui_right(int num)
|
|
{
|
|
/* int z;
|
|
|
|
for(z=0;z<num;z++)
|
|
MoveRight();*/
|
|
}
|
|
|
|
void gui_scroll(int top, int bot, int n)
|
|
{
|
|
/*BuffScroll(bot, n);*/
|
|
}
|
|
|
|
void gui_flush(void)
|
|
{
|
|
}
|
|
|
|
void gui_puts(unsigned char *buffer)
|
|
{
|
|
/*DispANSI(buffer);*/
|
|
}
|
|
|
|
void gui_new_window(Screen *new, Window *win)
|
|
{
|
|
}
|
|
|
|
void gui_kill_window(Screen *killscreen)
|
|
{
|
|
}
|
|
|
|
void gui_settitle(char *titletext, Screen *screen)
|
|
{
|
|
SetWindowText(screen->hwndFrame,titletext);
|
|
}
|
|
|
|
void gui_font_dialog(Screen *screen)
|
|
{
|
|
}
|
|
|
|
void gui_file_dialog(char *type, char *path, char *title, char *ok, char *apply, char *code, char *szButton)
|
|
{
|
|
}
|
|
|
|
void gui_properties_notebook(void)
|
|
{
|
|
}
|
|
|
|
void gui_msgbox(void)
|
|
{
|
|
}
|
|
|
|
void gui_popupmenu(char *menuname)
|
|
{
|
|
}
|
|
|
|
void gui_paste(char *args)
|
|
{
|
|
}
|
|
|
|
void gui_setfocus(Screen *screen)
|
|
{
|
|
}
|
|
|
|
void gui_scrollerchanged(Screen *screen, int position)
|
|
{
|
|
}
|
|
|
|
void gui_query_window_info(Screen *screen, char *fontinfo, int *x, int *y, int *cx, int *cy)
|
|
{
|
|
}
|
|
|
|
void gui_play_sound(char *filename)
|
|
{
|
|
}
|
|
|
|
void gui_get_sound_error(int errnum, char *errstring)
|
|
{
|
|
}
|
|
|
|
void gui_menu(Screen *screen, char *addmenu)
|
|
{
|
|
}
|
|
|
|
void gui_exit(void)
|
|
{
|
|
}
|
|
|
|
void gui_screen(Screen *new)
|
|
{
|
|
new->hwndFrame = HVTWin;
|
|
new->menu=(HWND)NULL;
|
|
new->old_li=new->li;
|
|
new->old_co=new->co;
|
|
new->nicklist = get_int_var(NICKLIST_VAR);
|
|
|
|
main_screen = new;
|
|
}
|
|
|
|
|
|
void gui_resize(Screen *this_screen)
|
|
{
|
|
if(this_screen->co < 20) this_screen->old_co=this_screen->co=20;
|
|
if(this_screen->li < 10) this_screen->old_li=this_screen->li=10;
|
|
if(this_screen->co > 199) this_screen->old_co=this_screen->co=199;
|
|
if(this_screen->li > 99) this_screen->old_li=this_screen->li=99;
|
|
/*cx = this_screen->co * this_screen->VIO_font_width;
|
|
cy = this_screen->li * this_screen->VIO_font_height;*/
|
|
|
|
co = this_screen->co; li = this_screen->li;
|
|
|
|
/* Recalculate some stuff that was done in input.c previously */
|
|
this_screen->input_line = this_screen->li-1;
|
|
|
|
this_screen->input_zone_len = this_screen->co - (WIDTH * 2);
|
|
if (this_screen->input_zone_len < 10)
|
|
this_screen->input_zone_len = 10; /* Take that! */
|
|
|
|
this_screen->input_start_zone = WIDTH;
|
|
this_screen->input_end_zone = this_screen->co - WIDTH;
|
|
}
|
|
|
|
int gui_send_mci_string(char *mcistring, char *retstring)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int gui_isset(Screen *screen, fd_set *rd, int what)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int gui_putc(int c)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int gui_read(Screen *screen, char *buffer, int maxbufsize)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int gui_screen_width(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int gui_screen_height(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void gui_setwindowpos(Screen *screen, int x, int y, int cx, int cy, int top, int bottom, int min, int max, int restore, int activate, int size, int position)
|
|
{
|
|
}
|
|
|
|
void gui_font_init(void)
|
|
{
|
|
}
|
|
|
|
void gui_font_set(char *font, Screen *screen)
|
|
{
|
|
}
|
|
|
|
void BX_gui_mutex_lock(void)
|
|
{
|
|
}
|
|
|
|
void BX_gui_mutex_unlock(void)
|
|
{
|
|
}
|
|
|
|
int gui_setmenuitem(char *menuname, int refnum, char *what, char *param)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void gui_remove_menurefs(char *menu)
|
|
{
|
|
}
|
|
|
|
void gui_mdi(Window *window, char *text, int value)
|
|
{
|
|
}
|
|
|
|
void gui_update_nicklist(char *channel)
|
|
{
|
|
}
|
|
|
|
void gui_nicklist_width(int width, Screen *this_screen)
|
|
{
|
|
}
|
|
|
|
void gui_startup(int argc, char *argv[])
|
|
{
|
|
}
|
|
|