home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / win100.zip / win19n.c < prev    next >
C/C++ Source or Header  |  1991-10-20  |  19KB  |  652 lines

  1. /*
  2.  * Windows H19 Terminal Emulator Initialization Module
  3.  * 
  4.  * Written by William S. Hall
  5.  *          3665 Benton Street, #66
  6.  *          Santa Clara, CA 95051
  7.  */
  8.  
  9. #define NOMINMAX
  10. #define NOATOM
  11. #define NOKANJI
  12. #include <windows.h>
  13. #include <limits.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <stdlib.h>
  17.  
  18. #include "winasc.h"
  19. #include "winh19.h"
  20. #include "win19d.h"
  21.  
  22. #if defined(KERMIT)
  23. #include "winkpf.h"
  24. extern krmState;
  25. #endif
  26.  
  27. /* default lines and columns */
  28. static int lines = H19LINES;
  29. static int columns = H19COLS;
  30.  
  31. /* local functions */
  32. static void NEAR GetCurrentInstanceData(HANDLE);
  33. static void NEAR GetPrevInstanceData(HANDLE);
  34. static HFONT NEAR GetFontInfo(HANDLE, short *, short *);
  35. static BOOL NEAR RegisterMainWindow(HANDLE);
  36. static BOOL NEAR RegisterTermWindow(HANDLE);
  37. static BOOL NEAR RegisterStatusWindow(HANDLE);
  38. static BOOL NEAR MakeAndShowMainWindow(HANDLE, short);
  39. static BOOL NEAR MakeAndShowTermWindow(HANDLE);
  40. static BOOL NEAR MakeAndShowStatusWindow(HANDLE);
  41. static BOOL NEAR GetDefaultSettings(HANDLE);
  42. static BOOL NEAR OpenAndSetCommPort(HANDLE);
  43. static void NEAR LoadSpecialKeys(HANDLE hInstance, int base, char *key[]);
  44.  
  45. /* search keystrings for match */
  46. BOOL NEAR SearchKey(char *str, char *key, int len)
  47. {
  48.     int i;
  49.     char *startptr;
  50.     startptr = str;
  51.  
  52.     for (i = 0; i < len; i++) {
  53.     if (*str++)
  54.         ;
  55.     else {
  56.         if (strcmp(key, startptr) == 0)
  57.         return(TRUE);
  58.         startptr = str;
  59.     }
  60.     }
  61.     return (FALSE);
  62. }
  63.  
  64. /* init entry */
  65. BOOL FAR InitProgram(hInstance,hPrevInstance, lpszCmdLine, cmdShow)
  66. HANDLE hInstance, hPrevInstance;
  67. LPSTR lpszCmdLine;
  68. short cmdShow;
  69. {
  70.  
  71.     char ch;
  72.     LPSTR lptr;
  73.     int i, len;
  74.  
  75.     hInst = hInstance;
  76.     hPrevInst = hPrevInstance;
  77.     cid = INT_MIN;
  78.     
  79.     len = 0;
  80.     lptr = lpszCmdLine;
  81.     while (ch = *lptr++)
  82.     if (isspace(ch))
  83.         break;
  84.     else
  85.         len++;
  86.  
  87.     if (hCommandLine = LocalAlloc(LPTR, len + 1)) {
  88.     pCommandLine = LocalLock(hCommandLine);
  89.     for (i = 0; i < len; i++)
  90.         *(pCommandLine + i) = *(lpszCmdLine + i);
  91.     }
  92.     *(pCommandLine + len) = NUL;
  93.  
  94.     if (!hPrevInstance) {
  95.  
  96.     if (LOBYTE(GetVersion()) < (BYTE)2)
  97.         return FALSE;
  98.  
  99.     GetCurrentInstanceData(hInstance);
  100.  
  101.     if ((CD.hScreenFont = 
  102.              GetFontInfo(hInstance,&TW.CharWidth, &TW.CharHeight)) == NULL)
  103.         return FALSE;
  104.  
  105.     if (!RegisterMainWindow(hInstance))
  106.         return FALSE;
  107.  
  108.     if (!RegisterTermWindow(hInstance))
  109.         return FALSE;
  110.  
  111.     if (!RegisterStatusWindow(hInstance))
  112.         return FALSE;
  113.  
  114.   }
  115.     else
  116.     GetPrevInstanceData(hPrevInstance);
  117.  
  118.     if (!GetDefaultSettings(hInstance))
  119.     return FALSE;
  120.  
  121.     if (!MakeAndShowMainWindow(hInstance,cmdShow))
  122.     return FALSE;
  123.  
  124. #if defined(KERMIT)
  125.     if (!krmInit(MW.hWnd, hInstance))
  126.     return FALSE;
  127. #endif
  128.  
  129.     if (!MakeAndShowTermWindow(hInstance))
  130.     return FALSE;
  131.  
  132.     if (!MakeAndShowStatusWindow(hInstance))
  133.     return FALSE;
  134.  
  135.     if (!OpenAndSetCommPort(hInstance))
  136.     return FALSE;
  137.  
  138.     hWndNext = SetClipboardViewer(MW.hWnd);
  139.     hWndActive = TW.hWnd;
  140.  
  141.     fpTerminal = (FARPROC)GetClassLong(MW.hWnd, GCL_WNDPROC);
  142.  
  143.     SetWindowLong(MW.hWnd, GWL_WNDPROC, (LONG)MainWndSubclassProc);
  144.     CD.LineState = IDM_ONLINE;
  145.  
  146.     CD.BreakFlag = -1;
  147.     SendMessage(MW.hWnd, WM_SETFOCUS, 0, 0L);
  148.  
  149.     return TRUE;
  150. }
  151.  
  152. /* get data from resources */
  153. static void NEAR GetCurrentInstanceData(HANDLE hInstance)
  154. {
  155.  
  156.     LoadString(hInstance,IDS_APPNAME,(LPSTR)szAppName,sizeof(szAppName));
  157.     LoadString(hInstance,IDS_TERMNAME,(LPSTR)szTermName,sizeof(szTermName));
  158.     LoadString(hInstance,IDS_STATNAME,(LPSTR)szStatName,sizeof(szStatName));
  159.     LoadString(hInstance, IDS_OFFLINE, (LPSTR)szOffline,sizeof(szOffline));
  160.     LoadString(hInstance, IDS_ONLINE, (LPSTR)szOnline, sizeof(szOnline));
  161.     LoadString(hInstance, IDS_WINTITLE, (LPSTR)szWinTitle,sizeof(szWinTitle));
  162.     hAccel = LoadAccelerators(hInstance, (LPSTR)szAppName);
  163. }
  164.  
  165. /* get data from another running instance */
  166. static void NEAR GetPrevInstanceData(HANDLE hPrevInstance)
  167. {
  168.  
  169.     GetInstanceData(hPrevInstance, (NPSTR)&CD.hScreenFont, sizeof(HFONT));
  170.     GetInstanceData(hPrevInstance, (NPSTR)&TW.CharWidth, sizeof(short));
  171.     GetInstanceData(hPrevInstance, (NPSTR)&TW.CharHeight, sizeof(short));
  172.     GetInstanceData(hPrevInstance, (PSTR)szAppName, sizeof(szAppName));
  173.     GetInstanceData(hPrevInstance, (PSTR)szTermName, sizeof(szTermName));
  174.     GetInstanceData(hPrevInstance, (PSTR)szStatName, sizeof(szStatName));
  175.     GetInstanceData(hPrevInstance, (PSTR)szOffline, sizeof(szOffline));
  176.     GetInstanceData(hPrevInstance, (PSTR)szOnline, sizeof(szOnline));
  177.     GetInstanceData(hPrevInstance, (PSTR)szWinTitle, sizeof(szWinTitle));
  178.     szWinTitle[strlen(szWinTitle) - 5] = NUL;
  179.     GetInstanceData(hPrevInstance, (PSTR)&hAccel, sizeof(hAccel));
  180. }
  181.  
  182. /* register main window */
  183. static BOOL NEAR RegisterMainWindow(HANDLE hInstance)
  184. {
  185.  
  186.     HANDLE hTemp;
  187.     PWNDCLASS pWndClass;
  188.  
  189.     if (hTemp = LocalAlloc(LPTR,sizeof(WNDCLASS))) {
  190.         if (pWndClass = (PWNDCLASS)LocalLock(hTemp)) {
  191.         pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  192.         pWndClass->hIcon = NULL;
  193.         pWndClass->lpszMenuName = NULL;
  194.             pWndClass->lpszClassName = (LPSTR)szAppName;
  195.             pWndClass->hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
  196.             pWndClass->hInstance = hInstance;
  197.             pWndClass->style = CS_VREDRAW | CS_HREDRAW;
  198.             pWndClass->lpfnWndProc = MainWndProc;
  199.             pWndClass->cbClsExtra = 0;
  200.             pWndClass->cbWndExtra = 0;
  201.         if (RegisterClass((LPWNDCLASS)pWndClass)) {
  202.             LocalUnlock(hTemp);
  203.             LocalFree(hTemp);
  204.             return TRUE;
  205.         }
  206.     }
  207.     return FALSE;
  208.     }
  209.     return FALSE;
  210. }
  211.  
  212. /* register terminal emulator window */
  213. static BOOL NEAR RegisterTermWindow(HANDLE hInstance)
  214. {
  215.  
  216.     PWNDCLASS pWndClass;
  217.     HANDLE hTemp;
  218.  
  219.     if (hTemp = LocalAlloc(LPTR,sizeof(WNDCLASS))) {
  220.         if (pWndClass = (PWNDCLASS)LocalLock(hTemp)) {
  221.         pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  222.         pWndClass->hIcon = NULL;
  223.         pWndClass->lpszMenuName = NULL;
  224.         pWndClass->lpszClassName = (LPSTR)szTermName;
  225.         pWndClass->hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  226.         pWndClass->hInstance = hInstance;
  227.         pWndClass->style = CS_VREDRAW | CS_HREDRAW | CS_CLASSDC;
  228.         pWndClass->lpfnWndProc = TermWndProc;
  229.         pWndClass->cbClsExtra = 0;
  230.         pWndClass->cbWndExtra = sizeof(struct TermWndData *);
  231.         if (RegisterClass((LPWNDCLASS)pWndClass)) {
  232.         LocalUnlock(hTemp);
  233.             LocalFree(hTemp);
  234.             return TRUE;
  235.         }
  236.     }
  237.         return FALSE;
  238.      }
  239.      return FALSE;
  240. }
  241.  
  242. /* register emulator status window */
  243. static BOOL NEAR RegisterStatusWindow(HANDLE hInstance)
  244. {
  245.  
  246.     PWNDCLASS pWndClass;
  247.     HANDLE hTemp;
  248.  
  249.     if (hTemp = LocalAlloc(LPTR,sizeof(WNDCLASS))) {
  250.         if (pWndClass = (PWNDCLASS)LocalLock(hTemp)) {
  251.         pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW);
  252.         pWndClass->hIcon = NULL;
  253.         pWndClass->lpszMenuName = NULL;
  254.         pWndClass->lpszClassName = (LPSTR)szStatName;
  255.         pWndClass->hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  256.         pWndClass->hInstance = hInstance;
  257.         pWndClass->style = CS_VREDRAW | CS_HREDRAW | CS_CLASSDC;
  258.         pWndClass->lpfnWndProc = StatWndProc;
  259.         pWndClass->cbClsExtra = 0;
  260.         pWndClass->cbWndExtra = sizeof(struct TermWndData *);
  261.         if (RegisterClass((LPWNDCLASS)pWndClass)) {
  262.         LocalUnlock(hTemp);
  263.         LocalFree(hTemp);
  264.             return TRUE;
  265.         }
  266.     }
  267.     return FALSE;
  268.     }
  269.     return FALSE;
  270. }
  271.  
  272. /* create main window */
  273. static BOOL NEAR MakeAndShowMainWindow(HANDLE hInstance, short cmdShow)
  274. {
  275.  
  276.     char szDisplayName[8];
  277.  
  278.     HMENU hMenu;
  279.  
  280.     RECT scrnrect;
  281.     short left, top, right, bottom, displayheight, displaywidth;
  282.     HDC hIC;
  283.  
  284.     scrnrect.left = 0;
  285.     scrnrect.top = 0;
  286.     scrnrect.right = TW.CharWidth * columns;
  287.     scrnrect.bottom = TW.CharHeight * (lines + 1);
  288.  
  289.     AdjustWindowRect((LPRECT)&scrnrect, (LONG)WS_OVERLAPPEDWINDOW, TRUE);
  290.  
  291.     left = scrnrect.left;
  292.     top = scrnrect.top;
  293.     right = scrnrect.right - left + 1;
  294.     bottom = scrnrect.bottom - scrnrect.top + 1;
  295.  
  296.     LoadString(hInstance, IDS_DISPLAYNAME,
  297.              (LPSTR)szDisplayName,sizeof(szDisplayName));
  298.     hIC = CreateIC((LPSTR)szDisplayName,(LPSTR)NULL, (LPSTR)NULL, (LPSTR)NULL);
  299.     displayheight = GetDeviceCaps(hIC, VERTRES);
  300.     displaywidth = GetDeviceCaps(hIC, HORZRES);
  301.     DeleteDC(hIC);
  302.  
  303.     if (bottom > displayheight)
  304.     bottom = displayheight;
  305.  
  306.     if (right > displaywidth)
  307.     right = displaywidth;
  308.  
  309.     hMenu = LoadMenu(hInstance, (LPSTR)szAppName);
  310.  
  311.     MW.hWnd = CreateWindow((LPSTR)szAppName,
  312.                  (LPSTR)szWinTitle,
  313.                  WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  314.                  CW_USEDEFAULT,0,right,bottom,
  315.                  (HWND)NULL,
  316.                  (HMENU)hMenu,
  317.                  (HANDLE)hInstance,
  318.                  (LPSTR)NULL);
  319.  
  320.     if (MW.hWnd != NULL) {
  321.         ShowWindow(MW.hWnd, cmdShow);
  322.         UpdateWindow(MW.hWnd);
  323.         return TRUE;
  324.     }
  325.     return FALSE;
  326. }
  327.  
  328. /* create terminal emulation window */
  329. static BOOL NEAR MakeAndShowTermWindow(HANDLE hInstance)
  330. {
  331.  
  332.     short width, height;
  333.  
  334.     width = columns * TW.CharWidth;
  335.     height = lines * TW.CharHeight;
  336.  
  337.     TW.hWnd = CreateWindow((LPSTR)szTermName,
  338.                     (LPSTR)NULL,
  339.                 WS_CHILDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS,
  340.                 0,0,
  341.                 width,height,
  342.                 MW.hWnd,
  343.                     (short)0,
  344.                 (HANDLE)hInstance,
  345.                 (LPSTR)&TW);
  346.  
  347.     if (TW.hWnd && TW.hVidBuffer)
  348.         return TRUE;
  349.  
  350.     ShowMessage(MW.hWnd, IDS_CANNOTCREATETERM);
  351.     return FALSE;
  352. }
  353.  
  354. /* create terminal emulation status window */
  355. static BOOL NEAR MakeAndShowStatusWindow(HANDLE hInstance)
  356. {
  357.  
  358.     short statpos, statheight;
  359.  
  360.     SW.CharWidth = TW.CharWidth;
  361.     SW.CharHeight = TW.CharHeight;
  362.     
  363.     statpos = TW.Height;
  364.     statheight = TW.CharHeight;
  365.     CD.StatOverlayTerm = FALSE;
  366.  
  367.     if ((statpos + statheight) > MW.Height) {
  368.     statpos = MW.BottomTextLine + TW.CharHeight;
  369.     statheight = MW.Height - statpos;
  370.     }
  371.  
  372.     SW.hWnd = CreateWindow((LPSTR)szStatName,
  373.                      (LPSTR)NULL,
  374.                  WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_VISIBLE,
  375.                      0,statpos,
  376.                      TW.Width,statheight,
  377.              MW.hWnd,
  378.                      (short)1,
  379.                      hInstance,
  380.                      (LPSTR)&SW);
  381.  
  382.     if (SW.hWnd && SW.hVidBuffer) {
  383.     BringWindowToTop(SW.hWnd);
  384.     return TRUE;
  385.     }
  386.  
  387.     ShowMessage(MW.hWnd, IDS_CANNOTCREATESTATUS);
  388.     return FALSE;
  389. }
  390.  
  391. /* load up function key string ids */
  392. static void NEAR LoadSpecialKeys(HANDLE hInstance, int base, char *key[])
  393. {
  394.     int i;
  395.     char szKeyStr[20];
  396.     HANDLE temp;
  397.  
  398.     for (i = 0; i < 12; i++) {
  399.         LoadString(hInstance, base+i,(LPSTR)szKeyStr,sizeof(szKeyStr));
  400.     if (temp=LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,strlen(szKeyStr) + 1)) {
  401.             key[i] = LocalLock(temp);
  402.         strcpy(key[i], szKeyStr);
  403.     }
  404.     }
  405. }
  406.  
  407. /* read win.ini for default values */
  408. static BOOL NEAR GetDefaultSettings(HANDLE hInstance)
  409. {
  410. #define INITKEYSIZE    1024
  411. #define MAXCOMPORTS    2
  412.  
  413.     char szKeyStr[80];
  414.     char szMessageStr[80];
  415.     char szDefStr[80];
  416.     HANDLE hInitKeyStr;
  417.     int Initlen;
  418.     char *szInitKeyStr;
  419.     register BOOL WinIniModified = FALSE;
  420.     register int i;
  421.     int reply;
  422.     int *ptr, *ptr1;
  423.  
  424.     LoadSpecialKeys(hInstance, IDS_SPKEYID1, szFKey);
  425.     LoadSpecialKeys(hInstance, IDS_SSPKEYID1, szSFKey);
  426.     LoadSpecialKeys(hInstance, IDS_CSPKEYID1, szCFKey);
  427.     LoadSpecialKeys(hInstance, IDS_CSSPKEYID1, szCSFKey);
  428.  
  429.     hInitKeyStr = LocalAlloc(LPTR, INITKEYSIZE);
  430.     if ((szInitKeyStr = LocalLock(hInitKeyStr)) == NULL)
  431.     return FALSE;
  432.  
  433.     Initlen = GetProfileString(szAppName, (LPSTR)NULL, (LPSTR)"",
  434.                    szInitKeyStr, INITKEYSIZE);
  435.     if (Initlen == 0) {
  436.         LoadString(hInstance,IDS_ADDDEFAULTS,szMessageStr,sizeof(szMessageStr));
  437.         reply = MessageBox(MW.hWnd,szMessageStr,szAppName, 
  438.                MB_ICONQUESTION | MB_YESNO);
  439.     if (reply == IDNO)
  440.         return FALSE;
  441.     }
  442.  
  443.   /* default ports */
  444.     for (i = 0; i < MAXCOMPORTS; i++) {
  445.         LoadString(hInstance,IDS_FIRSTPORT+i,(LPSTR)szKeyStr,sizeof(szKeyStr));
  446.         if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
  447.             LoadString(hInstance,IDS_COM1 + i, szDefStr, sizeof(szDefStr));
  448.         WinIniModified = TRUE;
  449.         WriteProfileString(szAppName,szKeyStr,szDefStr);
  450.     }
  451.     }
  452.  
  453.     for (i = 0; i < MAXCOMPORTS; i++) {
  454.     LoadString(hInstance, IDS_COM1 + i, szKeyStr, sizeof(szKeyStr));
  455.         if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
  456.          LoadString(hInstance, IDS_COMMSTR, szDefStr, sizeof(szDefStr));
  457.         WinIniModified = TRUE;
  458.         WriteProfileString(szAppName,szKeyStr,szDefStr);
  459.     }
  460.     }
  461.  
  462.     S402.BlockCursor = FALSE;
  463.     S402.KeyClick = TRUE;
  464.     S402.WrapAround = TRUE;
  465.     S402.LFonCR = FALSE;
  466.     S402.CRonLF = FALSE;
  467.     S402.ANSIMode = FALSE;
  468.     S402.ShiftedKeypad = TRUE;
  469.     S402.FullDuplex = TRUE;
  470.  
  471.     ptr1 = &S402.BlockCursor;
  472.     ptr = &CD.BlockCursor;
  473.     for (i = 0; i < 8; i++) {
  474.         LoadString(hInstance,IDS_BLOCKCURSOR+i,szKeyStr,sizeof(szKeyStr));
  475.     if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
  476.         WinIniModified = TRUE;
  477.         WriteProfileString(szAppName,szKeyStr,itoa(*ptr1,szMessageStr,10));
  478.     }
  479.         *ptr1 = GetProfileInt((LPSTR)szAppName, (LPSTR)szKeyStr, *ptr1);
  480.         *ptr++ = *ptr1++;
  481.     }
  482.  
  483.     LoadString(hInstance,IDS_LINES,(LPSTR)szKeyStr,sizeof(szKeyStr));
  484.     if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
  485.     WinIniModified = TRUE;
  486.         WriteProfileString(szAppName,szKeyStr,itoa(H19LINES,szMessageStr,10));
  487.     }
  488.     lines = GetProfileInt((LPSTR)szAppName, (LPSTR)szKeyStr, H19LINES);
  489.     lines = min(lines, TERMMAXLINES);
  490.  
  491.     LoadString(hInstance,IDS_COLUMNS,(LPSTR)szKeyStr,sizeof(szKeyStr));
  492.     if (!SearchKey(szInitKeyStr, szKeyStr, Initlen)) {
  493.     WinIniModified = TRUE;
  494.         WriteProfileString(szAppName,szKeyStr,itoa(H19COLS,szMessageStr,10));
  495.     }
  496.     columns = GetProfileInt((LPSTR)szAppName, (LPSTR)szKeyStr, H19COLS);
  497.     columns = min(columns, TERMMAXCOLS);
  498.  
  499.     LocalUnlock(hInitKeyStr);
  500.     LocalFree(hInitKeyStr);
  501.  
  502.     if (WinIniModified)
  503.     BroadcastWinIniChange();
  504.  
  505.     return TRUE;
  506.  
  507. }
  508.  
  509. /* set up comm port */
  510. static BOOL NEAR OpenAndSetCommPort(HANDLE hInstance)
  511. {
  512.  
  513.     char defcom[6];
  514.     char modestr[20];
  515.     char commstr[30];
  516.     char keystring[20];
  517.  
  518.     LoadString(hInstance, IDS_FIRSTPORT, (LPSTR)keystring, sizeof(keystring));
  519.     LoadString(hInstance, IDS_COM1, (LPSTR)defcom, sizeof(defcom));
  520.     GetProfileString((LPSTR)szAppName,(LPSTR)keystring, (LPSTR)defcom,
  521.                 (LPSTR)commstr,sizeof(commstr));
  522.  
  523.     if ((cid = OpenComm((LPSTR)commstr,RXQUESIZE,TXQUESIZE)) < 0) {
  524.     LoadString(hInstance,IDS_SECONDPORT,(LPSTR)keystring,sizeof(keystring));
  525.         LoadString(hInstance, IDS_COM2, (LPSTR)defcom, sizeof(defcom));
  526.         GetProfileString((LPSTR)szAppName,(LPSTR)keystring, (LPSTR)defcom,
  527.                 (LPSTR)commstr,sizeof(commstr));
  528.     if ((cid = OpenComm((LPSTR)commstr,RXQUESIZE,TXQUESIZE)) < 0) {
  529.         ShowMessage(MW.hWnd, IDS_NOCOMOPEN);
  530.         return FALSE;
  531.     }
  532.     }
  533.  
  534.     strcat(szWinTitle, commstr);
  535.     SetWindowText(MW.hWnd, (LPSTR)szWinTitle);        
  536.  
  537.     if (GetCommState(cid, (DCB FAR *)&CommData) >= 0) {
  538.         GetProfileString((LPSTR)szAppName,(LPSTR)commstr,(LPSTR)NULL,
  539.                 (LPSTR)modestr,sizeof(modestr));
  540.     strcat(commstr, modestr);
  541.         if (BuildCommDCB((LPSTR)commstr, (DCB FAR *)&CommData) >= 0) {
  542.         S401.BaudRate = CommData.BaudRate;
  543.         S401.ByteSize = CommData.ByteSize;
  544.         S401.Parity = CommData.Parity;
  545.         S401.StopBits = CommData.StopBits;
  546.         CommData.XonLim = RXQUESIZE / 8;
  547.         CommData.XoffLim = RXQUESIZE / 8;
  548.         CommData.fNull = TRUE; 
  549.         CommData.XonChar = XON;
  550.         CommData.XoffChar = XOFF;
  551.         CommData.fOutX = TRUE; 
  552.         CommData.fInX = TRUE; 
  553.         if (SetCommState((DCB FAR *)&CommData) >=0)
  554.             return TRUE;
  555.     }
  556.     }
  557.     ShowMessage(MW.hWnd,IDS_NOCOMSET);
  558.     CloseComm(cid);
  559.     return FALSE;
  560. }
  561.  
  562. /* read special font information */
  563. static HFONT NEAR GetFontInfo(hInstance, width, height)
  564. HANDLE hInstance;
  565. short *width, *height;
  566. {
  567.  
  568.     TEXTMETRIC TM;
  569.     HDC hIC;
  570.     LOGFONT h19font;
  571.     HFONT hFont;
  572.     char szString[20];
  573.  
  574.     *width = *height = 0;
  575.  
  576.     h19font.lfHeight = 0;
  577.     h19font.lfWidth = 0;
  578.     h19font.lfEscapement = 0;
  579.     h19font.lfOrientation = 0;
  580.     h19font.lfWeight = 0;
  581.     h19font.lfItalic = 0;
  582.     h19font.lfUnderline = 0;
  583.     h19font.lfStrikeOut = 0;
  584.     h19font.lfCharSet = OEM_CHARSET;
  585.     h19font.lfOutPrecision = OUT_DEFAULT_PRECIS;
  586.     h19font.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  587.     h19font.lfQuality = DEFAULT_QUALITY;
  588.     h19font.lfPitchAndFamily = FIXED_PITCH | FF_MODERN;
  589.     LoadString(hInstance, IDS_TERMINAL,(LPSTR)szString,sizeof(szString));
  590.     strncpy(h19font.lfFaceName, szString, LF_FACESIZE-1);
  591.     hFont = CreateFontIndirect((LPLOGFONT)&h19font);
  592.     LoadString(hInstance, IDS_DISPLAYNAME,(LPSTR)szString,sizeof(szString));
  593.     hIC = CreateIC((LPSTR)szString,(LPSTR)NULL, (LPSTR)NULL, (LPSTR)NULL);
  594.     if ((hIC != NULL) && (hFont != NULL)) {
  595.         SelectObject(hIC, hFont);
  596.         GetTextMetrics(hIC, (TEXTMETRIC FAR *)&TM);
  597.         DeleteDC(hIC);
  598.         *width = TM.tmAveCharWidth;
  599.         *height = TM.tmHeight + TM.tmExternalLeading;
  600.     }
  601.     return ((HFONT)hFont);
  602. }
  603.  
  604. /* called when the main window is created */
  605. void MainWndCreate(HWND hWnd, LONG lParam)
  606. {
  607.  
  608.     HMENU hMenu;
  609.     char szAbout[10];
  610.  
  611.     hMenu = GetSystemMenu(hWnd, FALSE);
  612.  
  613.     ChangeMenu(hMenu, 0, (LPSTR)NULL, -1, MF_APPEND | MF_SEPARATOR);
  614.     LoadString(hInst, IDS_ABOUT, (LPSTR)szAbout,10);
  615.     ChangeMenu(hMenu,0, (LPSTR)szAbout, IDM_ABOUT, MF_APPEND | MF_STRING);
  616.  
  617. }
  618.  
  619. /* called when the terminal or stat window is created */
  620. void TermWndCreate(HWND hWnd, LONG lParam)
  621. {
  622.  
  623.     CREATESTRUCT FAR *pCS;
  624.     struct TermWndData *pTW;
  625.  
  626.     pCS = (CREATESTRUCT FAR *)lParam;
  627.     pTW = (struct TermWndData *)LOWORD(pCS->lpCreateParams);
  628.  
  629.     pTW->MaxCols = pCS->cx/pTW->CharWidth;
  630.     pTW->MaxLines = pCS->cy/pTW->CharHeight;
  631.     if (pTW->MaxLines < 1)
  632.     pTW->MaxLines = 1;
  633.     pTW->ScreenSize = pTW->MaxCols * pTW->MaxLines;
  634.     pTW->Width = pTW->MaxCols * pTW->CharWidth;
  635.     pTW->Height = pTW->MaxLines * pTW->CharHeight;    
  636.     SetWindowWord(hWnd, 0, (WORD)pTW);
  637.  
  638.     pTW->hVidBuffer = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, pTW->ScreenSize);
  639.     if (pTW->hVidBuffer != NULL) {
  640.     pTW->pVidBuffer = LocalLock(pTW->hVidBuffer);
  641.     pTW->oVidLastLine = pTW->MaxCols * (pTW->MaxLines - 1);
  642.         pTW->hDC = GetDC(hWnd);
  643.         if (!hPrevInst)
  644.         SelectObject(pTW->hDC, CD.hScreenFont);
  645.     pTW->TabLimit = max(pTW->MaxCols - DEF_TABSTOP,0);
  646.     memset(pTW->pVidBuffer, SP, pTW->ScreenSize);
  647.     pTW->oTopLine = pTW->oCurrentLine = pTW->CurLineOffset = 0;
  648.     pTW->oBottomLine = pTW->oVidLastLine;
  649.     pTW->Xpos = pTW->Ypos = 0;
  650.     }
  651. }
  652.