|
|
/* 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); }
|