/* 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 #pragma hdrstop #include #include "stdtyp.h" #include #include "tdll.h" #include "globals.h" #include "mc.h" #include "assert.h" #include "session.h" #include "timers.h" #include "update.h" #include #include #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); }