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

  1. /* File: D:\WACKER\tdll\termhdl.c (Created: 10-Dec-1993)
  2. *
  3. * Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
  4. * All rights reserved
  5. *
  6. * $Revision: 15 $
  7. * $Date: 7/08/02 6:50p $
  8. */
  9. #include <windows.h>
  10. #pragma hdrstop
  11. #include <string.h>
  12. #include "stdtyp.h"
  13. #include <term\res.h>
  14. #include "tdll.h"
  15. #include "globals.h"
  16. #include "mc.h"
  17. #include "assert.h"
  18. #include "session.h"
  19. #include "timers.h"
  20. #include "update.h"
  21. #include <emu\emu.h>
  22. #include <emu\emu.hh>
  23. #include "htchar.h"
  24. #include "term.h"
  25. #include "term.hh"
  26. #include "misc.h"
  27. // This structure never referenced directly. Instead, a pointer is
  28. // stored to this array. Was easier to initialize by being static.
  29. static const COLORREF crEmuColors[MAX_EMUCOLORS] =
  30. {
  31. RGB( 0, 0, 0), // black
  32. RGB( 0, 0, 128), // blue
  33. RGB( 0, 128, 0), // green
  34. RGB( 0, 128, 128), // cyan
  35. RGB(128, 0, 0), // red
  36. RGB(128, 0, 128), // magenta
  37. RGB(128, 128, 32), // yellow
  38. RGB(192, 192, 192), // white (lt gray)
  39. RGB(128, 128, 128), // black (gray)
  40. RGB( 0, 0, 255), // intense blue
  41. RGB( 0, 255, 0), // intense green
  42. RGB( 0, 255, 255), // intense cyan
  43. RGB(255, 0, 0), // intense red
  44. RGB(255, 0, 255), // intense magenta
  45. RGB(255, 255, 0), // intense yellow
  46. RGB(255, 255, 255) // intense white
  47. };
  48. static BOOL AllocTxtBuf(ECHAR ***fpalpstr, int const sRows, int const sCols);
  49. static BOOL AllocAttrBuf(PSTATTR **fpapst, const int sRows, const int sCols);
  50. static void FreeTxtBuf(ECHAR ***fpalpstr, const int sRows);
  51. static void FreeAttrBuf(PSTATTR **fpapst, const int sRows);
  52. static BOOL termAllocBkBuf(const HHTERM hhTerm);
  53. static void termFreeBkBuf(const HHTERM hhTerm);
  54. static void GetDefaultDBCSFont(const HHTERM hhTerm);
  55. static int APIENTRY EnumFontCallback(LPLOGFONT lplf, LPTEXTMETRIC lptm,
  56. DWORD dwType, LPVOID lpData);
  57. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  58. * FUNCTION:
  59. * RegisterTerminalClass
  60. *
  61. * DESCRIPTION:
  62. * Registers the terminal class. Called in InitApplication()
  63. *
  64. * ARGUMENTS:
  65. * hInstance - Instance handle of app.
  66. *
  67. * RETURNS:
  68. * BOOL
  69. *
  70. */
  71. BOOL RegisterTerminalClass(const HINSTANCE hInstance)
  72. {
  73. WNDCLASSEX wc;
  74. memset(&wc, 0, sizeof(WNDCLASSEX));
  75. wc.cbSize = sizeof(WNDCLASSEX);
  76. if (GetClassInfoEx(hInstance, TERM_CLASS, &wc) == FALSE)
  77. {
  78. wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
  79. wc.lpfnWndProc = TermProc;
  80. wc.cbClsExtra = 0;
  81. wc.cbWndExtra = sizeof(LONG_PTR);
  82. wc.hInstance = hInstance;
  83. wc.hIcon = NULL;
  84. wc.hCursor = LoadCursor(0, IDC_ARROW);
  85. wc.hbrBackground = NULL;
  86. wc.lpszMenuName = NULL;
  87. wc.lpszClassName = TERM_CLASS;
  88. wc.hIconSm = NULL;
  89. if (RegisterClassEx(&wc) == FALSE)
  90. {
  91. assert(FALSE);
  92. return FALSE;
  93. }
  94. }
  95. return TRUE;
  96. }
  97. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  98. * FUNCTION:
  99. * CreateTerminalWindow
  100. *
  101. * DESCRIPTION:
  102. * Creates a terminal window.
  103. *
  104. * ARGUMENTS:
  105. * hwndSession - session window handle.
  106. *
  107. * RETURNS:
  108. * hwnd or zero.
  109. *
  110. */
  111. HWND CreateTerminalWindow(const HWND hwndSession)
  112. {
  113. HWND hwnd;
  114. hwnd = CreateWindowEx(
  115. WS_EX_CLIENTEDGE,
  116. TERM_CLASS,
  117. "",
  118. WS_CHILD | WS_HSCROLL | WS_VSCROLL | WS_CLIPSIBLINGS | WS_VISIBLE,
  119. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  120. hwndSession,
  121. (HMENU)IDC_TERMINAL_WIN,
  122. glblQueryDllHinst(),
  123. 0
  124. );
  125. if (hwnd == 0)
  126. {
  127. assert(FALSE);
  128. return 0;
  129. }
  130. return hwnd;
  131. }
  132. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  133. * FUNCTION:
  134. * CreateTerminalHdl
  135. *
  136. * DESCRIPTION:
  137. * Creates an internal terminal handle.
  138. *
  139. * ARGUMENTS:
  140. * hSession - session handle
  141. * hwndTerm - terminal window handle.
  142. *
  143. * RETURNS:
  144. * HHTERM or zero on error.
  145. *
  146. */
  147. HHTERM CreateTerminalHdl(const HWND hwndTerm)
  148. {
  149. HHTERM hhTerm;
  150. hhTerm = (HHTERM)malloc(sizeof(*hhTerm));
  151. if (hhTerm == 0)
  152. {
  153. assert(FALSE);
  154. return 0;
  155. }
  156. memset(hhTerm, 0, sizeof(*hhTerm));
  157. hhTerm->hwnd = hwndTerm;
  158. hhTerm->hwndSession = GetParent(hwndTerm);
  159. hhTerm->hSession = (HSESSION)GetWindowLongPtr(GetParent(hwndTerm), GWLP_USERDATA);
  160. /* --- ProcessMessage() aquires a session handle from here. --- */
  161. SetWindowLongPtr(hwndTerm, 0, (LONG_PTR)hhTerm->hSession);
  162. hhTerm->iRows = 24; // standard, loading an emulator could change it.
  163. hhTerm->iCols = 80; // standard, loading an emulator could change it.
  164. hhTerm->pacrEmuColors = crEmuColors;
  165. hhTerm->xBezel = BEZEL_SIZE;
  166. hhTerm->xIndent = 3;
  167. hhTerm->fCursorTracking = TRUE;
  168. hhTerm->fCursorsLinked = TRUE;
  169. hhTerm->fBlink = TRUE;
  170. if ( !IsTerminalServicesEnabled() )
  171. {
  172. //
  173. // Set the caret and text blink rate to the system's caret
  174. // blink rate setting.
  175. //
  176. hhTerm->uBlinkRate = GetCaretBlinkTime();
  177. }
  178. else
  179. {
  180. //
  181. // Set the text blink rate to once every 2 seconds.
  182. //
  183. hhTerm->uBlinkRate = 2000;
  184. }
  185. hhTerm->iCurType = EMU_CURSOR_LINE;
  186. hhTerm->hUpdate = updateCreate(hhTerm->hSession);
  187. memset(hhTerm->underscores, '_', MAX_EMUCOLS);
  188. hhTerm->underscores[MAX_EMUCOLS-1] = TEXT('\0');
  189. if (hhTerm->hUpdate == 0)
  190. return 0;
  191. // Allocate space for terminal text and attributes.
  192. if (AllocTxtBuf(&hhTerm->fplpstrTxt, MAX_EMUROWS, MAX_EMUCOLS) == FALSE)
  193. return 0;
  194. if (AllocAttrBuf(&hhTerm->fppstAttr, MAX_EMUROWS, MAX_EMUCOLS) == FALSE)
  195. return 0;
  196. if (termSysColorChng(hhTerm) == FALSE)
  197. return 0;
  198. if (termSetFont(hhTerm, 0) == FALSE)
  199. return 0;
  200. if (termAllocBkBuf(hhTerm) == FALSE)
  201. return 0;
  202. return hhTerm;
  203. }
  204. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  205. * FUNCTION:
  206. * DestroyTerminalHdl
  207. *
  208. * DESCRIPTION:
  209. * Gracefully cleans up the terminal handle.
  210. *
  211. * ARGUMENTS:
  212. * hhTerm - internal terminal handle.
  213. *
  214. * RETURNS:
  215. * void
  216. *
  217. */
  218. void DestroyTerminalHdl(const HHTERM hhTerm)
  219. {
  220. if (hhTerm == 0)
  221. return;
  222. if (hhTerm->hUpdate)
  223. updateDestroy(hhTerm->hUpdate);
  224. //TODO: destroy terminal window.
  225. FreeTxtBuf(&hhTerm->fplpstrTxt, MAX_EMUROWS);
  226. FreeAttrBuf(&hhTerm->fppstAttr, MAX_EMUROWS);
  227. /* --- Delete fonts --- */
  228. if (hhTerm->hFont)
  229. DeleteObject(hhTerm->hFont);
  230. //if (hhTerm->hUFont)
  231. // DeleteObject(hhTerm->hUFont);
  232. if (hhTerm->hDblHiFont)
  233. DeleteObject(hhTerm->hDblHiFont);
  234. //if (hhTerm->hDblHiUFont)
  235. // DeleteObject(hhTerm->hDblHiUFont);
  236. if (hhTerm->hDblWiFont)
  237. DeleteObject(hhTerm->hDblWiFont);
  238. //if (hhTerm->hDblWiUFont)
  239. // DeleteObject(hhTerm->hDblWiUFont);
  240. if (hhTerm->hDblHiWiFont)
  241. DeleteObject(hhTerm->hDblHiWiFont);
  242. //if (hhTerm->hDblHiWiUFont)
  243. // DeleteObject(hhTerm->hDblHiWiUFont);
  244. /* --- Delete alternate symbol fonts --- */
  245. if (hhTerm->hSymFont)
  246. DeleteObject(hhTerm->hSymFont);
  247. //if (hhTerm->hSymUFont)
  248. // DeleteObject(hhTerm->hSymUFont);
  249. if (hhTerm->hSymDblHiFont)
  250. DeleteObject(hhTerm->hSymDblHiFont);
  251. //if (hhTerm->hSymDblHiUFont)
  252. // DeleteObject(hhTerm->hSymDblHiUFont);
  253. if (hhTerm->hSymDblWiFont)
  254. DeleteObject(hhTerm->hSymDblWiFont);
  255. //if (hhTerm->hSymDblWiUFont)
  256. // DeleteObject(hhTerm->hSymDblWiUFont);
  257. if (hhTerm->hSymDblHiWiFont)
  258. DeleteObject(hhTerm->hSymDblHiWiFont);
  259. //if (hhTerm->hSymDblHiWiUFont)
  260. // DeleteObject(hhTerm->hSymDblHiWiUFont);
  261. /* --- Other stuff --- */
  262. if (hhTerm->hbrushTerminal)
  263. DeleteObject(hhTerm->hbrushTerminal);
  264. if (hhTerm->hDkGrayPen)
  265. DeleteObject(hhTerm->hDkGrayPen);
  266. if (hhTerm->hLtGrayPen)
  267. DeleteObject(hhTerm->hLtGrayPen);
  268. if (hhTerm->hbrushTermHatch)
  269. DeleteObject(hhTerm->hbrushTermHatch);
  270. if (hhTerm->hbrushBackHatch)
  271. DeleteObject(hhTerm->hbrushBackHatch);
  272. if (hhTerm->hbrushDivider)
  273. DeleteObject(hhTerm->hbrushDivider);
  274. if (hhTerm->hbrushHighlight)
  275. DeleteObject(hhTerm->hbrushHighlight);
  276. if (hhTerm->hCursorTimer)
  277. TimerDestroy(&hhTerm->hCursorTimer);
  278. if (hhTerm->fplpstrBkTxt)
  279. termFreeBkBuf(hhTerm);
  280. free(hhTerm);
  281. return;
  282. }
  283. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  284. * FUNCTION:
  285. * AllocTxtBuf
  286. *
  287. * DESCRIPTION:
  288. * Allocates text buffer for terminal image.
  289. *
  290. * ARGUMENTS:
  291. * fpalpstr - pointer to pointer to buffer array.
  292. * sRows - number of rows
  293. * sCols - number of cols in each row.
  294. *
  295. * RETURNS:
  296. * BOOL
  297. *
  298. */
  299. static BOOL AllocTxtBuf(ECHAR ***fpalpstr, int const sRows, int const sCols)
  300. {
  301. register int i;
  302. FreeTxtBuf(fpalpstr, sRows); // free any old stuff
  303. if ((*fpalpstr = (ECHAR **)malloc((unsigned int)sRows * sizeof(ECHAR *))) == 0)
  304. {
  305. assert(FALSE);
  306. return FALSE;
  307. }
  308. memset(*fpalpstr, 0, (unsigned int)sRows * sizeof(ECHAR *));
  309. for (i = 0 ; i < sRows ; ++i)
  310. {
  311. if (((*fpalpstr)[i] = (ECHAR *)malloc(sizeof(ECHAR) * (unsigned int)sCols)) == 0)
  312. {
  313. FreeTxtBuf(fpalpstr, sRows);
  314. assert(FALSE);
  315. return FALSE;
  316. }
  317. ECHAR_Fill((*fpalpstr)[i], EMU_BLANK_CHAR, (unsigned int)sCols);
  318. }
  319. return TRUE;
  320. }
  321. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  322. * FUNCTION:
  323. * AllocAttrBuf
  324. *
  325. * DESCRIPTION:
  326. * Allocates attribute buffer for terminal image.
  327. *
  328. * ARGUMENTS:
  329. * fpapst - pointer to pointer to buffer array.
  330. * sRows - number of rows
  331. * sCols - number of cols in each row.
  332. *
  333. * RETURNS:
  334. * BOOL
  335. *
  336. */
  337. static BOOL AllocAttrBuf(PSTATTR **fpapst, const int sRows, const int sCols)
  338. {
  339. register int i, j;
  340. STATTR stAttr;
  341. memset(&stAttr, 0, sizeof(STATTR));
  342. stAttr.txtclr = (unsigned int)GetNearestColorIndex(GetSysColor(COLOR_WINDOWTEXT));
  343. stAttr.bkclr = (unsigned int)GetNearestColorIndex(GetSysColor(COLOR_WINDOW));
  344. FreeAttrBuf(fpapst, sRows); // free any old stuff
  345. if ((*fpapst = (PSTATTR *)malloc((unsigned int)sRows * sizeof(PSTATTR))) == 0)
  346. {
  347. assert(FALSE);
  348. return FALSE;
  349. }
  350. for (i = 0 ; i < sRows ; ++i)
  351. {
  352. if (((*fpapst)[i] = (PSTATTR)malloc(sizeof(STATTR) * (unsigned int)sCols)) == 0)
  353. {
  354. FreeAttrBuf(fpapst, sRows); // free any old stuff
  355. assert(FALSE);
  356. return FALSE;
  357. }
  358. for (j = 0 ; j < sCols ; ++j)
  359. MemCopy((*fpapst)[i]+j, &stAttr, sizeof(STATTR));
  360. }
  361. return TRUE;
  362. }
  363. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  364. * FUNCTION:
  365. * FreeTxtBuf
  366. *
  367. * DESCRIPTION:
  368. * Free-up any allocated buffers for terminal text image
  369. *
  370. * ARGUMENTS:
  371. * fpalpstr - pointer to pointer to buffer array.
  372. * sRows - number of rows
  373. * sCols - number of cols in each row.
  374. *
  375. * RETURNS:
  376. * void
  377. *
  378. */
  379. static void FreeTxtBuf(ECHAR ***fpalpstr, const int sRows)
  380. {
  381. register int i;
  382. ECHAR **alpstr = *fpalpstr;
  383. if (alpstr)
  384. {
  385. for (i = 0 ; *alpstr && i < sRows ; ++i)
  386. {
  387. free(*alpstr);
  388. *alpstr = NULL;
  389. alpstr += 1;
  390. }
  391. free(*fpalpstr);
  392. *fpalpstr = 0;
  393. }
  394. return;
  395. }
  396. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  397. * FUNCTION:
  398. * FreeAttrBuf
  399. *
  400. * DESCRIPTION:
  401. * Free-up any allocated buffers for terminal attribute image
  402. *
  403. * ARGUMENTS:
  404. * fpapst - pointer to pointer to buffer array.
  405. * sRows - number of rows
  406. * sCols - number of cols in each row.
  407. *
  408. * RETURNS:
  409. * void
  410. *
  411. */
  412. static void FreeAttrBuf(PSTATTR **fpapst, const int sRows)
  413. {
  414. register int i;
  415. PSTATTR *apst = *fpapst;
  416. if (apst)
  417. {
  418. for (i = 0 ; *apst && i < sRows ; ++i)
  419. {
  420. free(*apst);
  421. *apst = NULL;
  422. apst += 1;
  423. }
  424. free(*fpapst);
  425. *fpapst = 0;
  426. }
  427. return;
  428. }
  429. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  430. * FUNCTION:
  431. * termSysColorChng
  432. *
  433. * DESCRIPTION:
  434. * Creates new brushes because system colors have changed. Also used
  435. * during initialization of terminal window.
  436. *
  437. * ARGUMENTS:
  438. * hhTerm - internal terminal handle.
  439. *
  440. * RETURNS:
  441. * void
  442. *
  443. */
  444. BOOL termSysColorChng(const HHTERM hhTerm)
  445. {
  446. #define HATCH_PATTERN HS_BDIAGONAL
  447. HBRUSH hBrush;
  448. HPEN hPen;
  449. COLORREF cr;
  450. hhTerm->crBackScrl = GetSysColor(COLOR_BTNFACE);
  451. hhTerm->crBackScrlTxt = GetSysColor(COLOR_BTNTEXT);
  452. hhTerm->hBlackPen = GetStockObject(BLACK_PEN);
  453. hhTerm->hWhitePen = GetStockObject(WHITE_PEN);
  454. /* ----------------------- */
  455. cr = GetSysColor(COLOR_WINDOW);
  456. if ((hBrush = CreateSolidBrush(cr)) == 0)
  457. {
  458. assert(FALSE);
  459. return FALSE;
  460. }
  461. hhTerm->crTerm = cr;
  462. if (hhTerm->hbrushTerminal)
  463. DeleteObject(hhTerm->hbrushTerminal);
  464. hhTerm->hbrushTerminal = hBrush;
  465. /* ----------------------- */
  466. cr = GetSysColor(COLOR_BTNFACE);
  467. if ((hBrush = CreateSolidBrush(cr)) == 0)
  468. {
  469. assert(FALSE);
  470. return FALSE;
  471. }
  472. hhTerm->crBackScrl = cr;
  473. if (hhTerm->hbrushBackScrl)
  474. DeleteObject(hhTerm->hbrushBackScrl);
  475. hhTerm->hbrushBackScrl = hBrush;
  476. /* ----------------------- */
  477. cr = GetSysColor(COLOR_BTNSHADOW);
  478. if ((hBrush = CreateSolidBrush(cr)) == 0)
  479. {
  480. assert(FALSE);
  481. return FALSE;
  482. }
  483. if (hhTerm->hbrushDivider)
  484. DeleteObject(hhTerm->hbrushDivider);
  485. hhTerm->hbrushDivider = hBrush;
  486. /* ----------------------- */
  487. cr = GetSysColor(COLOR_HIGHLIGHT);
  488. if ((hBrush = CreateSolidBrush(cr)) == 0)
  489. {
  490. assert(FALSE);
  491. return FALSE;
  492. }
  493. if (hhTerm->hbrushHighlight)
  494. DeleteObject(hhTerm->hbrushHighlight);
  495. hhTerm->hbrushHighlight = hBrush;
  496. /* ----------------------- */
  497. cr = GetSysColor(COLOR_BTNFACE);
  498. if ((hPen = CreatePen(PS_SOLID, 0, cr)) == 0)
  499. {
  500. assert(FALSE);
  501. return FALSE;
  502. }
  503. if (hhTerm->hLtGrayPen)
  504. DeleteObject(hhTerm->hLtGrayPen);
  505. hhTerm->hLtGrayPen = hPen;
  506. /* ----------------------- */
  507. hBrush = CreateHatchBrush(HATCH_PATTERN, GetSysColor(COLOR_BTNFACE));
  508. if (hBrush == 0)
  509. {
  510. assert(FALSE);
  511. return FALSE;
  512. }
  513. if (hhTerm->hbrushTermHatch)
  514. DeleteObject(hhTerm->hbrushTermHatch);
  515. hhTerm->hbrushTermHatch = hBrush;
  516. /* ----------------------- */
  517. hBrush = CreateHatchBrush(HATCH_PATTERN, GetSysColor(COLOR_BTNSHADOW));
  518. if (hBrush == 0)
  519. {
  520. assert(FALSE);
  521. return FALSE;
  522. }
  523. if (hhTerm->hbrushBackHatch)
  524. DeleteObject(hhTerm->hbrushBackHatch);
  525. hhTerm->hbrushBackHatch = hBrush;
  526. /* ----------------------- */
  527. cr = GetSysColor(COLOR_BTNSHADOW);
  528. if ((hPen = CreatePen(PS_SOLID, 0, cr)) == 0)
  529. {
  530. assert(FALSE);
  531. return FALSE;
  532. }
  533. if (hhTerm->hDkGrayPen)
  534. DeleteObject(hhTerm->hDkGrayPen);
  535. hhTerm->hDkGrayPen = hPen;
  536. return TRUE;
  537. }
  538. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  539. * FUNCTION:
  540. * termSetFont
  541. *
  542. * DESCRIPTION:
  543. * Sets the terminal font to the given font. If hFont is zero,
  544. * termSetFont() trys to create a default font.
  545. *
  546. * ARGUMENTS:
  547. * hhTerm - internal term handle.
  548. * plf - pointer to logfont
  549. *
  550. * RETURNS:
  551. * BOOL
  552. *
  553. */
  554. BOOL termSetFont(const HHTERM hhTerm, const PLOGFONT plf)
  555. {
  556. HDC hdc;
  557. LOGFONT lf;
  558. HFONT hFont;
  559. char ach[256];
  560. TEXTMETRIC tm;
  561. int nSize1, nSize2;
  562. int nCharSet;
  563. if (plf == 0)
  564. {
  565. // No font, use the default font for HyperTerminal
  566. // (usually New Courier)
  567. memset(&lf, 0, sizeof(LOGFONT));
  568. // Using different font sizes based upon screen resolution
  569. // using the resource file.
  570. // For VGA screens, we need a smaller font.
  571. //
  572. if (LoadString(glblQueryDllHinst(), IDS_TERM_DEF_VGA_SIZE,
  573. ach, sizeof(ach) / sizeof(TCHAR)))
  574. {
  575. nSize1 = atoi(ach);
  576. }
  577. else
  578. {
  579. nSize1 = -11;
  580. }
  581. if (LoadString(glblQueryDllHinst(), IDS_TERM_DEF_NONVGA_SIZE,
  582. ach, sizeof(ach) / sizeof(TCHAR)))
  583. {
  584. nSize2 = atoi(ach);
  585. }
  586. else
  587. {
  588. nSize2 = -15;
  589. }
  590. lf.lfHeight = (GetSystemMetrics(SM_CXSCREEN) < 810) ? nSize1 : nSize2;
  591. // mrw:3/5/96 - Font comes out really dinky on high res screens.
  592. //
  593. #if defined(INCL_USE_TERMINAL_FONT)
  594. if (GetSystemMetrics(SM_CXSCREEN) >= 1024)
  595. lf.lfHeight = -19;
  596. #endif
  597. lf.lfPitchAndFamily = FIXED_PITCH | MONO_FONT;
  598. if (LoadString(glblQueryDllHinst(), IDS_TERM_DEF_FONT,
  599. ach, sizeof(ach) / sizeof(TCHAR)))
  600. {
  601. strncpy(lf.lfFaceName, ach, sizeof(lf.lfFaceName));
  602. lf.lfFaceName[sizeof(lf.lfFaceName)/sizeof(TCHAR)-1] = TEXT('\0');
  603. }
  604. if (LoadString(glblQueryDllHinst(), IDS_TERM_DEF_CHARSET,
  605. ach, sizeof(ach) / sizeof(TCHAR)))
  606. {
  607. nCharSet = atoi(ach);
  608. lf.lfCharSet = (BYTE)nCharSet;
  609. }
  610. }
  611. else
  612. {
  613. memcpy(&lf, plf, sizeof(lf));
  614. }
  615. /* --- Attempt to get the font from the system. -- */
  616. hFont = CreateFontIndirect(&lf);
  617. //
  618. // Moved GetObject() here from below in case there is a problem
  619. // with the font. REV: 05/11/2001
  620. //
  621. if (hFont == 0 || GetObject(hFont, sizeof(LOGFONT), &lf) == 0)
  622. {
  623. //*lf.lfCharSet = ANSI_CHARSET;
  624. //*hFont = CreateFontIndirect(&lf);
  625. //*if (hFont == 0 || GetObject(hFont, sizeof(LOGFONT), &lf) == 0)
  626. {
  627. assert(FALSE);
  628. //
  629. // An error occurred when attempting to create/load this
  630. // font. Post a message to display the Font selection
  631. // common control dialog to select a font. REV: 05/11/2001
  632. //
  633. PostMessage(hhTerm->hwndSession, WM_COMMAND, IDM_VIEW_FONTS, (LPARAM)0);
  634. return FALSE;
  635. }
  636. }
  637. /* --- Ok, we have our base font, blast the previous fonts --- */
  638. if (hhTerm->hFont)
  639. {
  640. DeleteObject(hhTerm->hFont);
  641. hhTerm->hFont = 0;
  642. }
  643. if (hhTerm->hDblHiFont)
  644. {
  645. DeleteObject(hhTerm->hDblHiFont);
  646. hhTerm->hDblHiFont = 0;
  647. }
  648. if (hhTerm->hDblWiFont)
  649. {
  650. DeleteObject(hhTerm->hDblWiFont);
  651. hhTerm->hDblWiFont = 0;
  652. }
  653. if (hhTerm->hDblHiWiFont)
  654. {
  655. DeleteObject(hhTerm->hDblHiWiFont);
  656. hhTerm->hDblHiWiFont = 0;
  657. }
  658. /* --- And the symbol fonts --- */
  659. if (hhTerm->hSymFont)
  660. {
  661. DeleteObject(hhTerm->hSymFont);
  662. hhTerm->hSymFont = 0;
  663. }
  664. if (hhTerm->hSymDblHiFont)
  665. {
  666. DeleteObject(hhTerm->hSymDblHiFont);
  667. hhTerm->hSymDblHiFont = 0;
  668. }
  669. if (hhTerm->hSymDblWiFont)
  670. {
  671. DeleteObject(hhTerm->hSymDblWiFont);
  672. hhTerm->hSymDblWiFont = 0;
  673. }
  674. if (hhTerm->hSymDblHiWiFont)
  675. {
  676. DeleteObject(hhTerm->hSymDblHiWiFont);
  677. hhTerm->hSymDblHiWiFont = 0;
  678. }
  679. /* --- Commit to the new font --- */
  680. hhTerm->hFont = hFont;
  681. #if 0
  682. //
  683. // Moved GetObject() from here from above in case there is a problem
  684. // with creating the font. REV: 05/11/2001
  685. //
  686. if (GetObject(hFont, sizeof(LOGFONT), &lf) == 0)
  687. {
  688. assert(FALSE);
  689. return FALSE;
  690. }
  691. #endif // 0
  692. /* --- save what we really got --- */
  693. hhTerm->lf = lf;
  694. /* --- Get size of selected font. --- */
  695. hdc = GetDC(hhTerm->hwnd);
  696. hFont = (HFONT)SelectObject(hdc, hFont);
  697. GetTextMetrics(hdc, &tm);
  698. SelectObject(hdc, hFont);
  699. ReleaseDC(hhTerm->hwnd, hdc);
  700. hhTerm->xChar = tm.tmAveCharWidth;
  701. hhTerm->yChar = tm.tmHeight;
  702. #if defined(FAR_EAST)
  703. if ((tm.tmMaxCharWidth % 2) == 0)
  704. {
  705. hhTerm->iEvenFont = TRUE;
  706. }
  707. else
  708. {
  709. hhTerm->iEvenFont = FALSE;
  710. }
  711. #else
  712. hhTerm->iEvenFont = TRUE; //mrw:10/10/95
  713. #endif
  714. // We need to know if the font is italic because it changes the
  715. // way we draw. The italic fonts are regular fonts sheared. The
  716. // shear causes the character to draw into the next text box.
  717. // This really messes us up. To get around the problem, when
  718. // we're italic, we simply repaint the whole line when an text
  719. // comes in. - mrw,12/19/94
  720. //
  721. hhTerm->fItalic = tm.tmItalic;
  722. /* --- Set bezel size based on font --- */
  723. hhTerm->xBezel = BEZEL_SIZE;
  724. if (hhTerm->yChar < BEZEL_SIZE)
  725. {
  726. hhTerm->xBezel = max(5+OUTDENT, hhTerm->yChar);
  727. }
  728. switch (hhTerm->iCurType)
  729. {
  730. case EMU_CURSOR_LINE:
  731. default:
  732. hhTerm->iHstCurSiz = GetSystemMetrics(SM_CYBORDER) * 2;
  733. break;
  734. case EMU_CURSOR_BLOCK:
  735. hhTerm->iHstCurSiz = hhTerm->yChar;
  736. break;
  737. case EMU_CURSOR_NONE:
  738. hhTerm->iHstCurSiz = 0;
  739. break;
  740. }
  741. return TRUE;
  742. }
  743. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  744. * FUNCTION:
  745. * termMakeFont
  746. *
  747. * DESCRIPTION:
  748. * When user selects a font, we only create the standard non-underlined
  749. * font. If the paint routines encounter an attribute that needs a
  750. * a different font, then we create it on the spot. This is more
  751. * economic since often we won't need all 8 fonts for a given session.
  752. *
  753. * ARGUMENTS:
  754. * hhTerm - internal terminal handle
  755. * fUnderline - font is underlined
  756. * fHigh - font is double high
  757. * fWide - font is double wide
  758. *
  759. * RETURNS:
  760. * 0 on error, hFont on success.
  761. *
  762. */
  763. HFONT termMakeFont(const HHTERM hhTerm, const BOOL fUnderline,
  764. const BOOL fHigh, const BOOL fWide, const BOOL fSymbol)
  765. {
  766. LOGFONT lf;
  767. HFONT hFont;
  768. lf = hhTerm->lf;
  769. lf.lfWidth = hhTerm->xChar;
  770. if (fSymbol)
  771. {
  772. //lf.lfCharSet = SYMBOL_CHARSET;
  773. StrCharCopyN(lf.lfFaceName, "Arial Alternative Symbol", sizeof(lf.lfFaceName));
  774. }
  775. if (fUnderline)
  776. lf.lfUnderline = 1;
  777. if (fHigh)
  778. lf.lfHeight *= 2;
  779. if (fWide)
  780. lf.lfWidth *= 2;
  781. if ((hFont = CreateFontIndirect(&lf)) == 0)
  782. assert(FALSE);
  783. return hFont;
  784. }
  785. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  786. * FUNCTION:
  787. * fAllocBkBuf
  788. *
  789. * DESCRIPTION:
  790. * Allocates buffer space for backscroll text
  791. *
  792. * ARGUMENTS:
  793. * hhTerm - internal terminal handle
  794. *
  795. * RETURNS:
  796. * BOOL
  797. *
  798. */
  799. static BOOL termAllocBkBuf(const HHTERM hhTerm)
  800. {
  801. register int i;
  802. // This number should be big enough so that a maximized window of
  803. // backscroll text can be displayed.
  804. hhTerm->iMaxPhysicalBkRows = hhTerm->iPhysicalBkRows = min(5000,
  805. (GetSystemMetrics(SM_CYFULLSCREEN) / hhTerm->yChar) + 1);
  806. if ((hhTerm->fplpstrBkTxt = malloc((unsigned int)hhTerm->iMaxPhysicalBkRows *
  807. sizeof(ECHAR *))) == 0)
  808. {
  809. return FALSE;
  810. }
  811. for (i = 0 ; i < hhTerm->iMaxPhysicalBkRows ; ++i)
  812. {
  813. if ((hhTerm->fplpstrBkTxt[i] =
  814. malloc(MAX_EMUCOLS * sizeof(ECHAR))) == 0)
  815. {
  816. termFreeBkBuf(hhTerm);
  817. return FALSE;
  818. }
  819. ECHAR_Fill(hhTerm->fplpstrBkTxt[i], EMU_BLANK_CHAR, MAX_EMUCOLS);
  820. }
  821. return TRUE;
  822. }
  823. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  824. * FUNCTION:
  825. * FreeBkBuf
  826. *
  827. * DESCRIPTION:
  828. * Frees space allocated to backscroll buffer.
  829. *
  830. * ARGUMENTS:
  831. * hhTerm - internal terminal handle
  832. *
  833. * RETURNS:
  834. * void
  835. *
  836. */
  837. static void termFreeBkBuf(const HHTERM hhTerm)
  838. {
  839. register int i;
  840. for (i = 0 ; i < hhTerm->iMaxPhysicalBkRows ; ++i)
  841. {
  842. if (hhTerm->fplpstrBkTxt[i])
  843. {
  844. free(hhTerm->fplpstrBkTxt[i]);
  845. hhTerm->fplpstrBkTxt[i] = NULL;
  846. }
  847. }
  848. free(hhTerm->fplpstrBkTxt);
  849. hhTerm->fplpstrBkTxt = NULL;
  850. return;
  851. }
  852. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  853. * FUNCTION:
  854. * GetNearestColorIndex
  855. *
  856. * DESCRIPTION:
  857. * Duplicates a palette function that I couldn't get to work. Basicly,
  858. * the emulator has a table of colors it is allowed to use. When the
  859. * user picks a color, this function returns the index of the color that
  860. * most closely matches. How does it do this you say? Well, imagine
  861. * the problem as 3D space. The pallete colors all map into this space.
  862. * The goal is to find the pallete color closest to the given colorref
  863. * value. Borrowing from the 10th grade algrebra we know that:
  864. *
  865. * X^2 + Y^2 + Z^2 = C^2
  866. *
  867. * The distance between two points is then:
  868. *
  869. * (X - X')^2 + (Y - Y')^2 + (Z - Z') = C'^2
  870. *
  871. * The point with the smallest C'^2 value wins!
  872. *
  873. * ARGUMENTS:
  874. * COLORREF *acr - color table to use for matching
  875. * COLORREF cr - color to match.
  876. *
  877. * RETURNS:
  878. * An index of the closest matching color.
  879. *
  880. */
  881. int GetNearestColorIndex(COLORREF cr)
  882. {
  883. int i, idx = 0;
  884. unsigned int R, G, B;
  885. unsigned long C, CMin = (unsigned long)-1;
  886. for (i = 0 ; i < DIM(crEmuColors) ; ++i)
  887. {
  888. R = GetRValue(crEmuColors[i]) - GetRValue(cr); R *= R;
  889. G = GetGValue(crEmuColors[i]) - GetGValue(cr); G *= G;
  890. B = GetBValue(crEmuColors[i]) - GetBValue(cr); B *= B;
  891. C = (ULONG)(R + G + B);
  892. if (C < CMin)
  893. {
  894. CMin = C;
  895. idx = i;
  896. if (C == 0) // we matched!
  897. break;
  898. }
  899. }
  900. return idx;
  901. }
  902. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  903. * FUNCTION:
  904. * UnregisterTerminalClass
  905. *
  906. * DESCRIPTION:
  907. * unregisters the terminal class. Called in InitApplication()
  908. *
  909. * ARGUMENTS:
  910. * hInstance - Instance handle of app.
  911. *
  912. * RETURNS:
  913. * BOOL
  914. *
  915. */
  916. BOOL UnregisterTerminalClass(const HINSTANCE hInstance)
  917. {
  918. return UnregisterClass(TERM_CLASS, hInstance);
  919. }