Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1129 lines
25 KiB

/* File: D:\WACKER\tdll\termhdl.c (Created: 10-Dec-1993)
*
* Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
* All rights reserved
*
* $Revision: 15 $
* $Date: 7/08/02 6:50p $
*/
#include <windows.h>
#pragma hdrstop
#include <string.h>
#include "stdtyp.h"
#include <term\res.h>
#include "tdll.h"
#include "globals.h"
#include "mc.h"
#include "assert.h"
#include "session.h"
#include "timers.h"
#include "update.h"
#include <emu\emu.h>
#include <emu\emu.hh>
#include "htchar.h"
#include "term.h"
#include "term.hh"
#include "misc.h"
// This structure never referenced directly. Instead, a pointer is
// stored to this array. Was easier to initialize by being static.
static const COLORREF crEmuColors[MAX_EMUCOLORS] =
{
RGB( 0, 0, 0), // black
RGB( 0, 0, 128), // blue
RGB( 0, 128, 0), // green
RGB( 0, 128, 128), // cyan
RGB(128, 0, 0), // red
RGB(128, 0, 128), // magenta
RGB(128, 128, 32), // yellow
RGB(192, 192, 192), // white (lt gray)
RGB(128, 128, 128), // black (gray)
RGB( 0, 0, 255), // intense blue
RGB( 0, 255, 0), // intense green
RGB( 0, 255, 255), // intense cyan
RGB(255, 0, 0), // intense red
RGB(255, 0, 255), // intense magenta
RGB(255, 255, 0), // intense yellow
RGB(255, 255, 255) // intense white
};
static BOOL AllocTxtBuf(ECHAR ***fpalpstr, int const sRows, int const sCols);
static BOOL AllocAttrBuf(PSTATTR **fpapst, const int sRows, const int sCols);
static void FreeTxtBuf(ECHAR ***fpalpstr, const int sRows);
static void FreeAttrBuf(PSTATTR **fpapst, const int sRows);
static BOOL termAllocBkBuf(const HHTERM hhTerm);
static void termFreeBkBuf(const HHTERM hhTerm);
static void GetDefaultDBCSFont(const HHTERM hhTerm);
static int APIENTRY EnumFontCallback(LPLOGFONT lplf, LPTEXTMETRIC lptm,
DWORD dwType, LPVOID lpData);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* RegisterTerminalClass
*
* DESCRIPTION:
* Registers the terminal class. Called in InitApplication()
*
* ARGUMENTS:
* hInstance - Instance handle of app.
*
* RETURNS:
* BOOL
*
*/
BOOL RegisterTerminalClass(const HINSTANCE hInstance)
{
WNDCLASSEX wc;
memset(&wc, 0, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
if (GetClassInfoEx(hInstance, TERM_CLASS, &wc) == FALSE)
{
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wc.lpfnWndProc = TermProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(LONG_PTR);
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = TERM_CLASS;
wc.hIconSm = NULL;
if (RegisterClassEx(&wc) == FALSE)
{
assert(FALSE);
return FALSE;
}
}
return TRUE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* CreateTerminalWindow
*
* DESCRIPTION:
* Creates a terminal window.
*
* ARGUMENTS:
* hwndSession - session window handle.
*
* RETURNS:
* hwnd or zero.
*
*/
HWND CreateTerminalWindow(const HWND hwndSession)
{
HWND hwnd;
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
TERM_CLASS,
"",
WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_CLIPSIBLINGS | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hwndSession,
(HMENU)IDC_TERMINAL_WIN,
glblQueryDllHinst(),
0
);
if (hwnd == 0)
{
assert(FALSE);
return 0;
}
return hwnd;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* CreateTerminalHdl
*
* DESCRIPTION:
* Creates an internal terminal handle.
*
* ARGUMENTS:
* hSession - session handle
* hwndTerm - terminal window handle.
*
* RETURNS:
* HHTERM or zero on error.
*
*/
HHTERM CreateTerminalHdl(const HWND hwndTerm)
{
HHTERM hhTerm;
hhTerm = (HHTERM)malloc(sizeof(*hhTerm));
if (hhTerm == 0)
{
assert(FALSE);
return 0;
}
memset(hhTerm, 0, sizeof(*hhTerm));
hhTerm->hwnd = hwndTerm;
hhTerm->hwndSession = GetParent(hwndTerm);
hhTerm->hSession = (HSESSION)GetWindowLongPtr(GetParent(hwndTerm), GWLP_USERDATA);
/* --- ProcessMessage() aquires a session handle from here. --- */
SetWindowLongPtr(hwndTerm, 0, (LONG_PTR)hhTerm->hSession);
hhTerm->iRows = 24; // standard, loading an emulator could change it.
hhTerm->iCols = 80; // standard, loading an emulator could change it.
hhTerm->pacrEmuColors = crEmuColors;
hhTerm->xBezel = BEZEL_SIZE;
hhTerm->xIndent = 3;
hhTerm->fCursorTracking = TRUE;
hhTerm->fCursorsLinked = TRUE;
hhTerm->fBlink = TRUE;
if ( !IsTerminalServicesEnabled() )
{
//
// Set the caret and text blink rate to the system's caret
// blink rate setting.
//
hhTerm->uBlinkRate = GetCaretBlinkTime();
}
else
{
//
// Set the text blink rate to once every 2 seconds.
//
hhTerm->uBlinkRate = 2000;
}
hhTerm->iCurType = EMU_CURSOR_LINE;
hhTerm->hUpdate = updateCreate(hhTerm->hSession);
memset(hhTerm->underscores, '_', MAX_EMUCOLS);
hhTerm->underscores[MAX_EMUCOLS-1] = TEXT('\0');
if (hhTerm->hUpdate == 0)
return 0;
// Allocate space for terminal text and attributes.
if (AllocTxtBuf(&hhTerm->fplpstrTxt, MAX_EMUROWS, MAX_EMUCOLS) == FALSE)
return 0;
if (AllocAttrBuf(&hhTerm->fppstAttr, MAX_EMUROWS, MAX_EMUCOLS) == FALSE)
return 0;
if (termSysColorChng(hhTerm) == FALSE)
return 0;
if (termSetFont(hhTerm, 0) == FALSE)
return 0;
if (termAllocBkBuf(hhTerm) == FALSE)
return 0;
return hhTerm;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* DestroyTerminalHdl
*
* DESCRIPTION:
* Gracefully cleans up the terminal handle.
*
* ARGUMENTS:
* hhTerm - internal terminal handle.
*
* RETURNS:
* void
*
*/
void DestroyTerminalHdl(const HHTERM hhTerm)
{
if (hhTerm == 0)
return;
if (hhTerm->hUpdate)
updateDestroy(hhTerm->hUpdate);
//TODO: destroy terminal window.
FreeTxtBuf(&hhTerm->fplpstrTxt, MAX_EMUROWS);
FreeAttrBuf(&hhTerm->fppstAttr, MAX_EMUROWS);
/* --- Delete fonts --- */
if (hhTerm->hFont)
DeleteObject(hhTerm->hFont);
//if (hhTerm->hUFont)
// DeleteObject(hhTerm->hUFont);
if (hhTerm->hDblHiFont)
DeleteObject(hhTerm->hDblHiFont);
//if (hhTerm->hDblHiUFont)
// DeleteObject(hhTerm->hDblHiUFont);
if (hhTerm->hDblWiFont)
DeleteObject(hhTerm->hDblWiFont);
//if (hhTerm->hDblWiUFont)
// DeleteObject(hhTerm->hDblWiUFont);
if (hhTerm->hDblHiWiFont)
DeleteObject(hhTerm->hDblHiWiFont);
//if (hhTerm->hDblHiWiUFont)
// DeleteObject(hhTerm->hDblHiWiUFont);
/* --- Delete alternate symbol fonts --- */
if (hhTerm->hSymFont)
DeleteObject(hhTerm->hSymFont);
//if (hhTerm->hSymUFont)
// DeleteObject(hhTerm->hSymUFont);
if (hhTerm->hSymDblHiFont)
DeleteObject(hhTerm->hSymDblHiFont);
//if (hhTerm->hSymDblHiUFont)
// DeleteObject(hhTerm->hSymDblHiUFont);
if (hhTerm->hSymDblWiFont)
DeleteObject(hhTerm->hSymDblWiFont);
//if (hhTerm->hSymDblWiUFont)
// DeleteObject(hhTerm->hSymDblWiUFont);
if (hhTerm->hSymDblHiWiFont)
DeleteObject(hhTerm->hSymDblHiWiFont);
//if (hhTerm->hSymDblHiWiUFont)
// DeleteObject(hhTerm->hSymDblHiWiUFont);
/* --- Other stuff --- */
if (hhTerm->hbrushTerminal)
DeleteObject(hhTerm->hbrushTerminal);
if (hhTerm->hDkGrayPen)
DeleteObject(hhTerm->hDkGrayPen);
if (hhTerm->hLtGrayPen)
DeleteObject(hhTerm->hLtGrayPen);
if (hhTerm->hbrushTermHatch)
DeleteObject(hhTerm->hbrushTermHatch);
if (hhTerm->hbrushBackHatch)
DeleteObject(hhTerm->hbrushBackHatch);
if (hhTerm->hbrushDivider)
DeleteObject(hhTerm->hbrushDivider);
if (hhTerm->hbrushHighlight)
DeleteObject(hhTerm->hbrushHighlight);
if (hhTerm->hCursorTimer)
TimerDestroy(&hhTerm->hCursorTimer);
if (hhTerm->fplpstrBkTxt)
termFreeBkBuf(hhTerm);
free(hhTerm);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* AllocTxtBuf
*
* DESCRIPTION:
* Allocates text buffer for terminal image.
*
* ARGUMENTS:
* fpalpstr - pointer to pointer to buffer array.
* sRows - number of rows
* sCols - number of cols in each row.
*
* RETURNS:
* BOOL
*
*/
static BOOL AllocTxtBuf(ECHAR ***fpalpstr, int const sRows, int const sCols)
{
register int i;
FreeTxtBuf(fpalpstr, sRows); // free any old stuff
if ((*fpalpstr = (ECHAR **)malloc((unsigned int)sRows * sizeof(ECHAR *))) == 0)
{
assert(FALSE);
return FALSE;
}
memset(*fpalpstr, 0, (unsigned int)sRows * sizeof(ECHAR *));
for (i = 0 ; i < sRows ; ++i)
{
if (((*fpalpstr)[i] = (ECHAR *)malloc(sizeof(ECHAR) * (unsigned int)sCols)) == 0)
{
FreeTxtBuf(fpalpstr, sRows);
assert(FALSE);
return FALSE;
}
ECHAR_Fill((*fpalpstr)[i], EMU_BLANK_CHAR, (unsigned int)sCols);
}
return TRUE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* AllocAttrBuf
*
* DESCRIPTION:
* Allocates attribute buffer for terminal image.
*
* ARGUMENTS:
* fpapst - pointer to pointer to buffer array.
* sRows - number of rows
* sCols - number of cols in each row.
*
* RETURNS:
* BOOL
*
*/
static BOOL AllocAttrBuf(PSTATTR **fpapst, const int sRows, const int sCols)
{
register int i, j;
STATTR stAttr;
memset(&stAttr, 0, sizeof(STATTR));
stAttr.txtclr = (unsigned int)GetNearestColorIndex(GetSysColor(COLOR_WINDOWTEXT));
stAttr.bkclr = (unsigned int)GetNearestColorIndex(GetSysColor(COLOR_WINDOW));
FreeAttrBuf(fpapst, sRows); // free any old stuff
if ((*fpapst = (PSTATTR *)malloc((unsigned int)sRows * sizeof(PSTATTR))) == 0)
{
assert(FALSE);
return FALSE;
}
for (i = 0 ; i < sRows ; ++i)
{
if (((*fpapst)[i] = (PSTATTR)malloc(sizeof(STATTR) * (unsigned int)sCols)) == 0)
{
FreeAttrBuf(fpapst, sRows); // free any old stuff
assert(FALSE);
return FALSE;
}
for (j = 0 ; j < sCols ; ++j)
MemCopy((*fpapst)[i]+j, &stAttr, sizeof(STATTR));
}
return TRUE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* FreeTxtBuf
*
* DESCRIPTION:
* Free-up any allocated buffers for terminal text image
*
* ARGUMENTS:
* fpalpstr - pointer to pointer to buffer array.
* sRows - number of rows
* sCols - number of cols in each row.
*
* RETURNS:
* void
*
*/
static void FreeTxtBuf(ECHAR ***fpalpstr, const int sRows)
{
register int i;
ECHAR **alpstr = *fpalpstr;
if (alpstr)
{
for (i = 0 ; *alpstr && i < sRows ; ++i)
{
free(*alpstr);
*alpstr = NULL;
alpstr += 1;
}
free(*fpalpstr);
*fpalpstr = 0;
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* FreeAttrBuf
*
* DESCRIPTION:
* Free-up any allocated buffers for terminal attribute image
*
* ARGUMENTS:
* fpapst - pointer to pointer to buffer array.
* sRows - number of rows
* sCols - number of cols in each row.
*
* RETURNS:
* void
*
*/
static void FreeAttrBuf(PSTATTR **fpapst, const int sRows)
{
register int i;
PSTATTR *apst = *fpapst;
if (apst)
{
for (i = 0 ; *apst && i < sRows ; ++i)
{
free(*apst);
*apst = NULL;
apst += 1;
}
free(*fpapst);
*fpapst = 0;
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* termSysColorChng
*
* DESCRIPTION:
* Creates new brushes because system colors have changed. Also used
* during initialization of terminal window.
*
* ARGUMENTS:
* hhTerm - internal terminal handle.
*
* RETURNS:
* void
*
*/
BOOL termSysColorChng(const HHTERM hhTerm)
{
#define HATCH_PATTERN HS_BDIAGONAL
HBRUSH hBrush;
HPEN hPen;
COLORREF cr;
hhTerm->crBackScrl = GetSysColor(COLOR_BTNFACE);
hhTerm->crBackScrlTxt = GetSysColor(COLOR_BTNTEXT);
hhTerm->hBlackPen = GetStockObject(BLACK_PEN);
hhTerm->hWhitePen = GetStockObject(WHITE_PEN);
/* ----------------------- */
cr = GetSysColor(COLOR_WINDOW);
if ((hBrush = CreateSolidBrush(cr)) == 0)
{
assert(FALSE);
return FALSE;
}
hhTerm->crTerm = cr;
if (hhTerm->hbrushTerminal)
DeleteObject(hhTerm->hbrushTerminal);
hhTerm->hbrushTerminal = hBrush;
/* ----------------------- */
cr = GetSysColor(COLOR_BTNFACE);
if ((hBrush = CreateSolidBrush(cr)) == 0)
{
assert(FALSE);
return FALSE;
}
hhTerm->crBackScrl = cr;
if (hhTerm->hbrushBackScrl)
DeleteObject(hhTerm->hbrushBackScrl);
hhTerm->hbrushBackScrl = hBrush;
/* ----------------------- */
cr = GetSysColor(COLOR_BTNSHADOW);
if ((hBrush = CreateSolidBrush(cr)) == 0)
{
assert(FALSE);
return FALSE;
}
if (hhTerm->hbrushDivider)
DeleteObject(hhTerm->hbrushDivider);
hhTerm->hbrushDivider = hBrush;
/* ----------------------- */
cr = GetSysColor(COLOR_HIGHLIGHT);
if ((hBrush = CreateSolidBrush(cr)) == 0)
{
assert(FALSE);
return FALSE;
}
if (hhTerm->hbrushHighlight)
DeleteObject(hhTerm->hbrushHighlight);
hhTerm->hbrushHighlight = hBrush;
/* ----------------------- */
cr = GetSysColor(COLOR_BTNFACE);
if ((hPen = CreatePen(PS_SOLID, 0, cr)) == 0)
{
assert(FALSE);
return FALSE;
}
if (hhTerm->hLtGrayPen)
DeleteObject(hhTerm->hLtGrayPen);
hhTerm->hLtGrayPen = hPen;
/* ----------------------- */
hBrush = CreateHatchBrush(HATCH_PATTERN, GetSysColor(COLOR_BTNFACE));
if (hBrush == 0)
{
assert(FALSE);
return FALSE;
}
if (hhTerm->hbrushTermHatch)
DeleteObject(hhTerm->hbrushTermHatch);
hhTerm->hbrushTermHatch = hBrush;
/* ----------------------- */
hBrush = CreateHatchBrush(HATCH_PATTERN, GetSysColor(COLOR_BTNSHADOW));
if (hBrush == 0)
{
assert(FALSE);
return FALSE;
}
if (hhTerm->hbrushBackHatch)
DeleteObject(hhTerm->hbrushBackHatch);
hhTerm->hbrushBackHatch = hBrush;
/* ----------------------- */
cr = GetSysColor(COLOR_BTNSHADOW);
if ((hPen = CreatePen(PS_SOLID, 0, cr)) == 0)
{
assert(FALSE);
return FALSE;
}
if (hhTerm->hDkGrayPen)
DeleteObject(hhTerm->hDkGrayPen);
hhTerm->hDkGrayPen = hPen;
return TRUE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* termSetFont
*
* DESCRIPTION:
* Sets the terminal font to the given font. If hFont is zero,
* termSetFont() trys to create a default font.
*
* ARGUMENTS:
* hhTerm - internal term handle.
* plf - pointer to logfont
*
* RETURNS:
* BOOL
*
*/
BOOL termSetFont(const HHTERM hhTerm, const PLOGFONT plf)
{
HDC hdc;
LOGFONT lf;
HFONT hFont;
char ach[256];
TEXTMETRIC tm;
int nSize1, nSize2;
int nCharSet;
if (plf == 0)
{
// No font, use the default font for HyperTerminal
// (usually New Courier)
memset(&lf, 0, sizeof(LOGFONT));
// Using different font sizes based upon screen resolution
// using the resource file.
// For VGA screens, we need a smaller font.
//
if (LoadString(glblQueryDllHinst(), IDS_TERM_DEF_VGA_SIZE,
ach, sizeof(ach) / sizeof(TCHAR)))
{
nSize1 = atoi(ach);
}
else
{
nSize1 = -11;
}
if (LoadString(glblQueryDllHinst(), IDS_TERM_DEF_NONVGA_SIZE,
ach, sizeof(ach) / sizeof(TCHAR)))
{
nSize2 = atoi(ach);
}
else
{
nSize2 = -15;
}
lf.lfHeight = (GetSystemMetrics(SM_CXSCREEN) < 810) ? nSize1 : nSize2;
// mrw:3/5/96 - Font comes out really dinky on high res screens.
//
#if defined(INCL_USE_TERMINAL_FONT)
if (GetSystemMetrics(SM_CXSCREEN) >= 1024)
lf.lfHeight = -19;
#endif
lf.lfPitchAndFamily = FIXED_PITCH | MONO_FONT;
if (LoadString(glblQueryDllHinst(), IDS_TERM_DEF_FONT,
ach, sizeof(ach) / sizeof(TCHAR)))
{
strncpy(lf.lfFaceName, ach, sizeof(lf.lfFaceName));
lf.lfFaceName[sizeof(lf.lfFaceName)/sizeof(TCHAR)-1] = TEXT('\0');
}
if (LoadString(glblQueryDllHinst(), IDS_TERM_DEF_CHARSET,
ach, sizeof(ach) / sizeof(TCHAR)))
{
nCharSet = atoi(ach);
lf.lfCharSet = (BYTE)nCharSet;
}
}
else
{
memcpy(&lf, plf, sizeof(lf));
}
/* --- Attempt to get the font from the system. -- */
hFont = CreateFontIndirect(&lf);
//
// Moved GetObject() here from below in case there is a problem
// with the font. REV: 05/11/2001
//
if (hFont == 0 || GetObject(hFont, sizeof(LOGFONT), &lf) == 0)
{
//*lf.lfCharSet = ANSI_CHARSET;
//*hFont = CreateFontIndirect(&lf);
//*if (hFont == 0 || GetObject(hFont, sizeof(LOGFONT), &lf) == 0)
{
assert(FALSE);
//
// An error occurred when attempting to create/load this
// font. Post a message to display the Font selection
// common control dialog to select a font. REV: 05/11/2001
//
PostMessage(hhTerm->hwndSession, WM_COMMAND, IDM_VIEW_FONTS, (LPARAM)0);
return FALSE;
}
}
/* --- Ok, we have our base font, blast the previous fonts --- */
if (hhTerm->hFont)
{
DeleteObject(hhTerm->hFont);
hhTerm->hFont = 0;
}
if (hhTerm->hDblHiFont)
{
DeleteObject(hhTerm->hDblHiFont);
hhTerm->hDblHiFont = 0;
}
if (hhTerm->hDblWiFont)
{
DeleteObject(hhTerm->hDblWiFont);
hhTerm->hDblWiFont = 0;
}
if (hhTerm->hDblHiWiFont)
{
DeleteObject(hhTerm->hDblHiWiFont);
hhTerm->hDblHiWiFont = 0;
}
/* --- And the symbol fonts --- */
if (hhTerm->hSymFont)
{
DeleteObject(hhTerm->hSymFont);
hhTerm->hSymFont = 0;
}
if (hhTerm->hSymDblHiFont)
{
DeleteObject(hhTerm->hSymDblHiFont);
hhTerm->hSymDblHiFont = 0;
}
if (hhTerm->hSymDblWiFont)
{
DeleteObject(hhTerm->hSymDblWiFont);
hhTerm->hSymDblWiFont = 0;
}
if (hhTerm->hSymDblHiWiFont)
{
DeleteObject(hhTerm->hSymDblHiWiFont);
hhTerm->hSymDblHiWiFont = 0;
}
/* --- Commit to the new font --- */
hhTerm->hFont = hFont;
#if 0
//
// Moved GetObject() from here from above in case there is a problem
// with creating the font. REV: 05/11/2001
//
if (GetObject(hFont, sizeof(LOGFONT), &lf) == 0)
{
assert(FALSE);
return FALSE;
}
#endif // 0
/* --- save what we really got --- */
hhTerm->lf = lf;
/* --- Get size of selected font. --- */
hdc = GetDC(hhTerm->hwnd);
hFont = (HFONT)SelectObject(hdc, hFont);
GetTextMetrics(hdc, &tm);
SelectObject(hdc, hFont);
ReleaseDC(hhTerm->hwnd, hdc);
hhTerm->xChar = tm.tmAveCharWidth;
hhTerm->yChar = tm.tmHeight;
#if defined(FAR_EAST)
if ((tm.tmMaxCharWidth % 2) == 0)
{
hhTerm->iEvenFont = TRUE;
}
else
{
hhTerm->iEvenFont = FALSE;
}
#else
hhTerm->iEvenFont = TRUE; //mrw:10/10/95
#endif
// We need to know if the font is italic because it changes the
// way we draw. The italic fonts are regular fonts sheared. The
// shear causes the character to draw into the next text box.
// This really messes us up. To get around the problem, when
// we're italic, we simply repaint the whole line when an text
// comes in. - mrw,12/19/94
//
hhTerm->fItalic = tm.tmItalic;
/* --- Set bezel size based on font --- */
hhTerm->xBezel = BEZEL_SIZE;
if (hhTerm->yChar < BEZEL_SIZE)
{
hhTerm->xBezel = max(5+OUTDENT, hhTerm->yChar);
}
switch (hhTerm->iCurType)
{
case EMU_CURSOR_LINE:
default:
hhTerm->iHstCurSiz = GetSystemMetrics(SM_CYBORDER) * 2;
break;
case EMU_CURSOR_BLOCK:
hhTerm->iHstCurSiz = hhTerm->yChar;
break;
case EMU_CURSOR_NONE:
hhTerm->iHstCurSiz = 0;
break;
}
return TRUE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* termMakeFont
*
* DESCRIPTION:
* When user selects a font, we only create the standard non-underlined
* font. If the paint routines encounter an attribute that needs a
* a different font, then we create it on the spot. This is more
* economic since often we won't need all 8 fonts for a given session.
*
* ARGUMENTS:
* hhTerm - internal terminal handle
* fUnderline - font is underlined
* fHigh - font is double high
* fWide - font is double wide
*
* RETURNS:
* 0 on error, hFont on success.
*
*/
HFONT termMakeFont(const HHTERM hhTerm, const BOOL fUnderline,
const BOOL fHigh, const BOOL fWide, const BOOL fSymbol)
{
LOGFONT lf;
HFONT hFont;
lf = hhTerm->lf;
lf.lfWidth = hhTerm->xChar;
if (fSymbol)
{
//lf.lfCharSet = SYMBOL_CHARSET;
StrCharCopyN(lf.lfFaceName, "Arial Alternative Symbol", sizeof(lf.lfFaceName));
}
if (fUnderline)
lf.lfUnderline = 1;
if (fHigh)
lf.lfHeight *= 2;
if (fWide)
lf.lfWidth *= 2;
if ((hFont = CreateFontIndirect(&lf)) == 0)
assert(FALSE);
return hFont;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* fAllocBkBuf
*
* DESCRIPTION:
* Allocates buffer space for backscroll text
*
* ARGUMENTS:
* hhTerm - internal terminal handle
*
* RETURNS:
* BOOL
*
*/
static BOOL termAllocBkBuf(const HHTERM hhTerm)
{
register int i;
// This number should be big enough so that a maximized window of
// backscroll text can be displayed.
hhTerm->iMaxPhysicalBkRows = hhTerm->iPhysicalBkRows = min(5000,
(GetSystemMetrics(SM_CYFULLSCREEN) / hhTerm->yChar) + 1);
if ((hhTerm->fplpstrBkTxt = malloc((unsigned int)hhTerm->iMaxPhysicalBkRows *
sizeof(ECHAR *))) == 0)
{
return FALSE;
}
for (i = 0 ; i < hhTerm->iMaxPhysicalBkRows ; ++i)
{
if ((hhTerm->fplpstrBkTxt[i] =
malloc(MAX_EMUCOLS * sizeof(ECHAR))) == 0)
{
termFreeBkBuf(hhTerm);
return FALSE;
}
ECHAR_Fill(hhTerm->fplpstrBkTxt[i], EMU_BLANK_CHAR, MAX_EMUCOLS);
}
return TRUE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* FreeBkBuf
*
* DESCRIPTION:
* Frees space allocated to backscroll buffer.
*
* ARGUMENTS:
* hhTerm - internal terminal handle
*
* RETURNS:
* void
*
*/
static void termFreeBkBuf(const HHTERM hhTerm)
{
register int i;
for (i = 0 ; i < hhTerm->iMaxPhysicalBkRows ; ++i)
{
if (hhTerm->fplpstrBkTxt[i])
{
free(hhTerm->fplpstrBkTxt[i]);
hhTerm->fplpstrBkTxt[i] = NULL;
}
}
free(hhTerm->fplpstrBkTxt);
hhTerm->fplpstrBkTxt = NULL;
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* GetNearestColorIndex
*
* DESCRIPTION:
* Duplicates a palette function that I couldn't get to work. Basicly,
* the emulator has a table of colors it is allowed to use. When the
* user picks a color, this function returns the index of the color that
* most closely matches. How does it do this you say? Well, imagine
* the problem as 3D space. The pallete colors all map into this space.
* The goal is to find the pallete color closest to the given colorref
* value. Borrowing from the 10th grade algrebra we know that:
*
* X^2 + Y^2 + Z^2 = C^2
*
* The distance between two points is then:
*
* (X - X')^2 + (Y - Y')^2 + (Z - Z') = C'^2
*
* The point with the smallest C'^2 value wins!
*
* ARGUMENTS:
* COLORREF *acr - color table to use for matching
* COLORREF cr - color to match.
*
* RETURNS:
* An index of the closest matching color.
*
*/
int GetNearestColorIndex(COLORREF cr)
{
int i, idx = 0;
unsigned int R, G, B;
unsigned long C, CMin = (unsigned long)-1;
for (i = 0 ; i < DIM(crEmuColors) ; ++i)
{
R = GetRValue(crEmuColors[i]) - GetRValue(cr); R *= R;
G = GetGValue(crEmuColors[i]) - GetGValue(cr); G *= G;
B = GetBValue(crEmuColors[i]) - GetBValue(cr); B *= B;
C = (ULONG)(R + G + B);
if (C < CMin)
{
CMin = C;
idx = i;
if (C == 0) // we matched!
break;
}
}
return idx;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* UnregisterTerminalClass
*
* DESCRIPTION:
* unregisters the terminal class. Called in InitApplication()
*
* ARGUMENTS:
* hInstance - Instance handle of app.
*
* RETURNS:
* BOOL
*
*/
BOOL UnregisterTerminalClass(const HINSTANCE hInstance)
{
return UnregisterClass(TERM_CLASS, hInstance);
}