/*
 * Dialog box support for Win100
 * 
 * Copyright (c) 1990, 1991 by
 * William S. Hall
 * 3665 Benton Street  #66
 * Santa Clara, CA 95051
 *
 */

#define NOBITMAP
#define NOBRUSH
#define NOKANJI
#define NOATOM
#define NOMINMAX
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
#include <stdio.h>
#include <direct.h>
#if defined(WIN2)
#include <winexp.h>
#endif
#ifdef COLUMBIA
#include "wktsmt.h"
#include "wkt100.h"
#include "wktdlg.h"
#else
#include "smterm.h"
#include "w600dg.h"
#include "win600.h"
#endif

typedef struct _FONTDAT {
    HWND hDlg;
    int action;
} FONTDAT;

static void NEAR InitModemBox(HWND hDlg);
// static int NEAR FindInitialPort(HWND hDlg, int index);
static int NEAR FindXoffLimit(WORD val);
static int FindParityIndex(BYTE parity, BYTE size);
static int NEAR FindBaudIndex(WORD rate);
static void NEAR SetModemBox(HWND hDlg);
static void NEAR SaveModemBoxParams(HWND hDlg);
static void NEAR SetDisplayBox(HWND hDlg);
static void NEAR InitDisplayBox(HWND hDlg);
static void NEAR SetGeneralBox(HWND hDlg);
static void NEAR InitGeneralBox(HWND hDlg);
static void NEAR InitMiniBox(HWND hDlg);
static void NEAR SetMiniBox(HWND hDlg);
static void NEAR InitCopyBox(HWND hDlg);
static void NEAR RangeCopyBox(HWND hDlg);
static void NEAR SetCopyBox(HWND hDlg);
static void NEAR StringOp(HWND hDlg, WORD param);
static void NEAR InitLogFileBox(HWND hDlg);
static BOOL NEAR SetLogFileBox(HWND hDlg);
static void NEAR InitKeyboardBox(HWND hDlg);
static void NEAR SetKeyboardBox(HWND hDlg);
static void NEAR InitFontsBoxProc(HWND hDlg);
short FAR PASCAL GetFixedFontInfo(LPLOGFONT lf,
			     LPTEXTMETRIC tm, short type, FONTDAT FAR *Data);
static void NEAR ScrollCopyBox(HWND hDlg, WORD wParam, LONG lParam);
static void NEAR SelectFontsBox(HWND hDlg);
static void NEAR SizeFontsBox(HWND hDlg);
static void NEAR SetFontsBox(HWND hDlg);
CBInsertString(HWND hDlg, int id, int index, char * buf);
CBSetCursel(HWND hDlg, int id, int index);
CBGetCursel(HWND hDlg, int id);
static void NEAR SaveInitData(int id, int val);

static char *format = "%2d %2d";
static char *black = "Black";
static char *dgray = "Dark Gray";
static char *lgray = "Light Gray";
static char *white = "White";

BOOL OpenDlgBox(HWND hWnd, FARPROC fpProc, WORD boxnum)
{

    FARPROC fp;
    BOOL result;

  /* make a proc instance for the about box window function */
    fp = MakeProcInstance(fpProc, hInst);
  /* create a modal dialog box */
    result = DialogBox(hInst, MAKEINTRESOURCE(boxnum),hWnd,fp);
    FreeProcInstance(fp);
    return result;

}

/* This is the window proc for the about box when it is displayed */
BOOL FAR PASCAL AboutBoxProc(HWND hDlg,unsigned message,
			     WORD wParam,LONG lParam)
{

    switch (message) {

      /* nothing to initialize */
	case WM_INITDIALOG:
	    break;

      /* this dialog box has only an OK button */
	case WM_COMMAND:
	    switch (wParam) {
		case IDOK:
		case IDCANCEL:
		/* destroy the dialog box */
		    EndDialog(hDlg,TRUE);
		    break;
		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

BOOL FAR PASCAL FontsBoxProc(HWND hDlg,unsigned message,
			     WORD wParam,LONG lParam)
{

    switch (message) {

	case WM_INITDIALOG:
	    InitFontsBoxProc(hDlg);
	    break;

	case WM_COMMAND:
	    switch (wParam) {
/*
		case IDD_SAVE:
		    if (IsDlgButtonChecked(hDlg, wParam))
			CheckDlgButton(hDlg, wParam, FALSE);
		    else
			CheckDlgButton(hDlg, wParam, TRUE);
	  	    break;
*/

		case IDD_FONTFACE:
		    SelectFontsBox(hDlg);
		    break;

		case IDD_NORMALFONT:
		case IDD_SMALLFONT:
		    SizeFontsBox(hDlg);
		    break;

		case IDOK:
		    SetFontsBox(hDlg);
		    EndDialog(hDlg,TRUE);
		    break;

		case IDCANCEL:
		    EndDialog(hDlg,FALSE);
		    break;

		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

short FAR PASCAL GetFixedFontInfo(LPLOGFONT lf, LPTEXTMETRIC tm,
				  short type, FONTDAT FAR *pfd)
{

    HWND hdlg = pfd->hDlg;
    WORD boxid = pfd->action;
    char buf[20];

    switch(boxid) {
	case IDD_FONTFACE:
	    if ((lf->lfPitchAndFamily & FIXED_PITCH) && 
		(lf->lfWeight == FW_NORMAL) && 
		(lf->lfItalic == 0) &&
		(lf->lfStrikeOut == 0) &&
		(lf->lfUnderline == 0) &&
		(lf->lfCharSet == ANSI_CHARSET))
		SendDlgItemMessage(hdlg,boxid,LB_ADDSTRING,0,
				   (LONG)(LPSTR)lf->lfFaceName);
	    break;

	case IDD_NORMALFONT:
	    if ((lf->lfPitchAndFamily & FIXED_PITCH) && 
		(lf->lfWeight == FW_NORMAL) && 
		(lf->lfItalic == 0) &&
		(lf->lfStrikeOut == 0) &&
		(lf->lfUnderline == 0) &&
		(lf->lfCharSet == ANSI_CHARSET)) {
	        sprintf(buf, format, lf->lfWidth, lf->lfHeight);
	        SendDlgItemMessage(hdlg, boxid,
				   LB_INSERTSTRING, -1, (LONG)(LPSTR)buf);
	        SendDlgItemMessage(hdlg, boxid + 1,
				   LB_INSERTSTRING,-1,(LONG)(LPSTR)buf);
	    }
	    break;

    }
    return TRUE;
}

static void NEAR SizeFontsBox(HWND hDlg)
{
    WORD index, index1;
    HWND hctl = GetDlgItem(hDlg, IDOK);

    index = (WORD)SendDlgItemMessage(hDlg,IDD_NORMALFONT,LB_GETCURSEL,0,0L);
    index1 = (WORD)SendDlgItemMessage(hDlg,IDD_SMALLFONT,LB_GETCURSEL,0,0L);
    if ((index == LB_ERR) || (index1 == LB_ERR))
        EnableWindow(hctl, FALSE);
    else
	EnableWindow(hctl, TRUE);

}

static void NEAR SelectFontsBox(HWND hDlg)
{
    FARPROC fp;
    HDC hDC;
    char curfont[LF_FACESIZE];
    WORD index, index1;
    FONTDAT fd;

    index = (WORD)SendDlgItemMessage(hDlg, IDD_FONTFACE, LB_GETCURSEL, 0, 0L);
    if (index != LB_ERR) {
	SendDlgItemMessage(hDlg, IDD_FONTFACE, LB_GETTEXT, index,
						(LONG)(LPSTR)curfont);
	SendDlgItemMessage(hDlg, IDD_SMALLFONT, WM_SETREDRAW, 0, 0L);
	SendDlgItemMessage(hDlg, IDD_NORMALFONT, WM_SETREDRAW, 0, 0L);
	SendDlgItemMessage(hDlg, IDD_NORMALFONT, LB_RESETCONTENT, 0, 0L);
	SendDlgItemMessage(hDlg, IDD_SMALLFONT, LB_RESETCONTENT, 0, 0L);
        hDC = GetDC(hDlg);
        fp = MakeProcInstance((FARPROC)GetFixedFontInfo, hInst);
	fd.hDlg = hDlg;
	fd.action = IDD_NORMALFONT;
        EnumFonts(hDC, curfont, fp, (LPSTR)&fd);
        FreeProcInstance(fp);
        ReleaseDC(hDlg, hDC);
	SendDlgItemMessage(hDlg, IDD_SMALLFONT, WM_SETREDRAW, TRUE, 0L);
	SendDlgItemMessage(hDlg, IDD_NORMALFONT, WM_SETREDRAW, TRUE, 0L);
	InvalidateRect(GetDlgItem(hDlg,IDD_SMALLFONT), NULL, TRUE);
	InvalidateRect(GetDlgItem(hDlg,IDD_NORMALFONT), NULL, TRUE);
    }
    index = (WORD)SendDlgItemMessage(hDlg,IDD_NORMALFONT,LB_GETCURSEL,0,0L);
    index1 = (WORD)SendDlgItemMessage(hDlg,IDD_SMALLFONT,LB_GETCURSEL,0,0L);
    if ((index == LB_ERR) || (index1 == LB_ERR))
        EnableWindow(GetDlgItem(hDlg, IDOK), FALSE);
}

static void NEAR SetFontsBox(HWND hDlg)
{
    WORD index, index1, index2;
    char curfont[LF_FACESIZE];
    char nfont[10], sfont[10];
    short nfontwidth, nfontheight;
    short sfontwidth, sfontheight;
    char szKeyStr[80];
    SETFONT sf;

    index = (WORD)SendDlgItemMessage(hDlg, IDD_FONTFACE, LB_GETCURSEL, 0, 0L);
    index1 = (WORD)SendDlgItemMessage(hDlg,IDD_NORMALFONT,LB_GETCURSEL, 0, 0L);
    index2 = (WORD)SendDlgItemMessage(hDlg,IDD_SMALLFONT,LB_GETCURSEL,0,0L);
    if ((index != LB_ERR) && (index1 != LB_ERR) && (index2 != LB_ERR)) {
	SendDlgItemMessage(hDlg, IDD_FONTFACE, LB_GETTEXT, index,
						(LONG)(LPSTR)curfont);
	SendDlgItemMessage(hDlg, IDD_NORMALFONT, LB_GETTEXT, index1,
						(LONG)(LPSTR)nfont);
	SendDlgItemMessage(hDlg, IDD_SMALLFONT, LB_GETTEXT, index2,
						(LONG)(LPSTR)sfont);
	sscanf(nfont, format, &nfontwidth, &nfontheight);
	sscanf(sfont, format, &sfontwidth, &sfontheight);

	sf.nwidth = nfontwidth;
	sf.nheight = nfontheight;
	sf.swidth = sfontwidth;
	sf.sheight = sfontheight;
	strcpy(sf.FaceName, curfont);
	
	SendMessage(hWndActive,SMT_COMMAND,SM_SETFONT,
		    (LONG)(SETFONT FAR *)&sf);

	if (IsDlgButtonChecked(hDlg, IDD_SAVE)) {
            LoadString(hInst,IDS_FONTFACE,(LPSTR)szKeyStr,sizeof(szKeyStr));
            WritePrivateProfileString(szAppName,szKeyStr,curfont,szIniName);
	    SaveInitData(IDS_NORMALWIDTH, nfontwidth);
	    SaveInitData(IDS_NORMALHEIGHT, nfontheight);
	    SaveInitData(IDS_SMALLWIDTH, sfontwidth);
	    SaveInitData(IDS_SMALLHEIGHT, sfontheight);
	}
    }
}

static void NEAR InitFontsBoxProc(HWND hDlg)
{
    FARPROC fp;
    HDC hDC;
    char curfont[LF_FACESIZE];
    long len;
    FONTDAT fd;
    
    CheckDlgButton(hDlg, IDD_SAVE, FALSE);
//    EnableWindow(GetDlgItem(hDlg, IDD_SAVE), FALSE);

    hDC = GetDC(hDlg);
    fp = MakeProcInstance((FARPROC)GetFixedFontInfo, hInst);
    fd.hDlg = hDlg;
    fd.action = IDD_FONTFACE;
    EnumFonts(hDC, NULL, fp, (LPSTR)&fd);
    SendDlgItemMessage(hDlg,IDD_FONTFACE,LB_ADDSTRING,0,(LONG)(LPSTR)"System");
				   
    len = SendMessage(hWndText,SMT_GETATTRIBUTE,SM_FONTFACE,
		      (LONG)(LPSTR)curfont);

    if (len) {
        SendDlgItemMessage(hDlg,IDD_FONTFACE,LB_SELECTSTRING, -1,
					 (LONG)(LPSTR)curfont);
	fd.action = IDD_NORMALFONT;
        EnumFonts(hDC, curfont, fp, (LPSTR)&fd);
	len = SendMessage(hWndText, SMT_GETATTRIBUTE, SM_NORMALFONT, 0L);
	sprintf(curfont, format, LOWORD(len), HIWORD(len));
        SendDlgItemMessage(hDlg,IDD_NORMALFONT,LB_SELECTSTRING, -1,
					 (LONG)(LPSTR)curfont);
	len = SendMessage(hWndText, SMT_GETATTRIBUTE, SM_SMALLFONT, 0L);
	sprintf(curfont, format, LOWORD(len), HIWORD(len));
        SendDlgItemMessage(hDlg,IDD_SMALLFONT,LB_SELECTSTRING, -1,
					 (LONG)(LPSTR)curfont);
    }
    FreeProcInstance(fp);
    ReleaseDC(hDlg, hDC);
}

BOOL FAR PASCAL LogFileBoxProc(HWND hDlg,unsigned message,
			       WORD wParam,LONG lParam)
{
    int count;

    switch (message) {

	case WM_INITDIALOG:
	    InitLogFileBox(hDlg);
	    break;

	case WM_COMMAND:
	    switch (wParam) {
		case IDD_GETFILE:
		    if (HIWORD(lParam) == EN_CHANGE) {
		        count = (int)SendDlgItemMessage(hDlg,
				     wParam,WM_GETTEXTLENGTH,0,0L);
		        EnableWindow(GetDlgItem(hDlg, IDOK), count);
		    }
		    break;

		case IDOK:
		    if (SetLogFileBox(hDlg))
		        EndDialog(hDlg,TRUE);
		    break;

		case IDCANCEL:
		    EndDialog(hDlg,FALSE);
		    break;

		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

static char namebuf[14];

static BOOL NEAR SetLogFileBox(HWND hDlg)
{
    char buf[132];
    int hfile;
    int reply;
    WORD style;

    GetDlgItemText(hDlg, IDD_GETFILE, buf, sizeof(buf));
  
    if ((hfile = OpenFile(buf, &ofLogFile, OF_EXIST)) > 0) {
	if (strpbrk(buf, ":\\")) {	// path specified
	    reply = ShowMessage(hDlg,IDS_FILEEXISTS, 
				MB_YESNOCANCEL | MB_ICONQUESTION);
	    if (reply == IDCANCEL)
		return FALSE;
	    style = reply == IDNO ? OF_WRITE | OF_CREATE : OF_WRITE;
	}
	else {		// not a path
//            reply = GetDlgItemText(hDlg,IDD_LOGFILEPATH,buf,sizeof(buf));
            getcwd(buf, sizeof(buf));
	    if (buf[reply - 1] == '\\')
		buf[reply - 1] = 0;
	    strcat(buf, strrchr(ofLogFile.szPathName,'\\'));
	    if (strcmp(buf, ofLogFile.szPathName)) //file not in this directory
		style = OF_WRITE | OF_CREATE;
	    else {	    // yes, in this directory, so append or clear ?
	        reply = ShowMessage(hDlg,IDS_FILEEXISTS, 
				    MB_YESNOCANCEL | MB_ICONQUESTION);
	        if (reply == IDCANCEL)
		    return FALSE;
	        style = reply == IDNO ? OF_WRITE | OF_CREATE : OF_WRITE;
	    }
	}
    }
    else
        style = OF_WRITE | OF_CREATE;

    hLogFile = OpenFile(buf, &ofLogFile, style);
    if (hLogFile > 0) {
	lseek(hLogFile, 0L, SEEK_END);
	strcpy(namebuf, strrchr(ofLogFile.szPathName,'\\') + 1);
	return TRUE;
    }
    ShowMessage(hDlg, IDS_OPENFILEERROR, MB_OK | MB_ICONASTERISK);
    return FALSE;
}

static void NEAR InitLogFileBox(HWND hDlg)
{

    static namelen = 0;
    HWND hctl;
    LONG style;

    hctl = GetDlgItem(hDlg, IDD_GETFILE);
    style = GetWindowLong(hctl, GWL_STYLE);
    style |= ES_OEMCONVERT;
    SetWindowLong(hctl, GWL_STYLE, style);

// set limits
    SendDlgItemMessage(hDlg,IDD_GETFILE,EM_LIMITTEXT,128,0L);
// show current directory
    DlgDirList(hDlg, (LPSTR)0, 0, IDD_LOGFILEPATH, 0);
// get default name
    if (namelen == 0)
        namelen = LoadString(hInst,IDS_LOGFILENAME,namebuf,sizeof(namebuf));
// set the name
    SetDlgItemText(hDlg, IDD_GETFILE, namebuf);
}

static short Start, End;

BOOL FAR PASCAL CopyBoxProc(HWND hDlg,unsigned message,WORD wParam,LONG lParam)
{

    switch (message) {

	case WM_VSCROLL:
	    ScrollCopyBox(hDlg, wParam, lParam);
	    break;

	case WM_INITDIALOG:
	    InitCopyBox(hDlg);
	    break;

	case WM_COMMAND:
	    switch (wParam) {
		case IDD_STARTLINE:
		case IDD_ENDLINE:
		    if (HIWORD(lParam) == EN_CHANGE)
			RangeCopyBox(hDlg);
		    break;

		case IDOK:
		    SetCopyBox(hDlg);
		    EndDialog(hDlg, TRUE);
		    SendMessage(hWndText, SMT_INVERT, 0,
				MAKELONG(Start - 1,End - 1));
		    Start = End = 0;
		    break;

		case IDCANCEL:
		    EndDialog(hDlg,FALSE);
		    SendMessage(hWndText, SMT_INVERT, 0,
						MAKELONG(Start - 1,End - 1));
		    Start = End = 0;
		    break;

		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

static void NEAR ScrollCopyBox(HWND hDlg, WORD wParam, LONG lParam)
{
    BOOL change = FALSE;

    int size = LOWORD(SendMessage(hWndText,SMT_GETATTRIBUTE,SM_SCREENSIZE,0L));
    int startline = GetDlgItemInt(hDlg, IDD_STARTLINE, NULL, FALSE);
    int endline = GetDlgItemInt(hDlg, IDD_ENDLINE, NULL, FALSE);

    if (HIWORD(lParam) == GetDlgItem(hDlg, IDD_STARTSCROLL)) {
	SetFocus(GetDlgItem(hDlg,IDD_STARTLINE));
        switch(wParam) {
  	    case SB_LINEUP:
		if (startline > 1) {
		    startline -= 1;
		    change = TRUE;
		}
	        break;

	    case SB_LINEDOWN:
		if (startline < endline) {
		    startline += 1;
		    change = TRUE;
		}
	        break;
        }
    }
    else {
	SetFocus(GetDlgItem(hDlg,IDD_ENDLINE));
        switch(wParam) {
  	    case SB_LINEUP:
		if (endline > startline) {
		    endline -= 1;
		    change = TRUE;
		}
	        break;

	    case SB_LINEDOWN:
		if (endline < size) {
		    endline += 1;
		    change = TRUE;
		}
	        break;
        }
    }
    if (change) {
        SetDlgItemInt(hDlg, IDD_STARTLINE, startline, FALSE);
        SetDlgItemInt(hDlg, IDD_ENDLINE, endline, FALSE);
    }
}

static void NEAR RangeCopyBox(HWND hDlg)
{
    int size = LOWORD(SendMessage(hWndText,SMT_GETATTRIBUTE,SM_SCREENSIZE,0L));
    int startline = GetDlgItemInt(hDlg, IDD_STARTLINE, NULL, FALSE);
    int endline = GetDlgItemInt(hDlg, IDD_ENDLINE, NULL, FALSE);
    BOOL enable = (startline >= 1) && (endline <= size)
		  && (startline <= endline);
    EnableWindow(GetDlgItem(hDlg, IDOK), enable);

    if (enable) {
	if (startline > Start)
	    SendMessage(hWndText,SMT_INVERT,0,MAKELONG(Start-1,startline-2));
	else if (startline < Start)
	    SendMessage(hWndText,SMT_INVERT,0,MAKELONG(startline-1,Start-2));
	if (endline > End)
	    SendMessage(hWndText,SMT_INVERT,0,MAKELONG(End,endline-1));
	else if (endline < End)
	    SendMessage(hWndText,SMT_INVERT,0,MAKELONG(endline,End-1));
	Start = startline;
	End = endline;
    }
}

static void NEAR SetCopyBox(HWND hDlg)
{
    HANDLE hText;
    LPSTR pText;

    BYTE startline = (BYTE)GetDlgItemInt(hDlg, IDD_STARTLINE, NULL, FALSE);
    BYTE endline = (BYTE)GetDlgItemInt(hDlg, IDD_ENDLINE, NULL, FALSE);
    long size = SendMessage(hWndText,SMT_GETATTRIBUTE,SM_SCREENSIZE,0L);
    long alloc = (LONG)(16 + (HIWORD(size) + 2) * LOWORD(size));
    WORD wParam = 256 * (endline - 1) + startline - 1;

    if (hText = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, alloc)) {
        if (pText = GlobalLock(hText)) {
	    SendMessage(hWndText,SMT_COPYLINES, wParam, (LONG)pText);
	    GlobalUnlock(hText);
	    if (OpenClipboard(MWnd.hWnd)) {
	        EmptyClipboard();
	        SetClipboardData(CF_TEXT, hText);
	        CloseClipboard();
	    }
	    else
	        GlobalFree(hText);
        }
	else
	    GlobalFree(hText);
    }
}

static void NEAR InitCopyBox(HWND hDlg)
{

    long size = SendMessage(hWndText, SMT_GETATTRIBUTE, SM_SCREENSIZE, 0L);
    int maxrows = LOWORD(size);

    Start = 1;
    End = maxrows;

    SendMessage(hWndText,SMT_INVERT,0, MAKELONG(Start - 1, End - 1));

    SetDlgItemInt(hDlg, IDD_STARTLINE, 1, FALSE);
    SetDlgItemInt(hDlg, IDD_ENDLINE, maxrows, FALSE);
}

BOOL FAR PASCAL MiniBoxProc(HWND hDlg,unsigned message,WORD wParam,LONG lParam)
{

    switch (message) {

	case WM_INITDIALOG:
	    InitMiniBox(hDlg);
	    break;

      /* this dialog box has only an OK button */
	case WM_COMMAND:
	    switch (wParam) {

		case IDOK:
		    SetMiniBox(hDlg);
		    EndDialog(hDlg,TRUE);
		    break;

		case IDCANCEL:
		    EndDialog(hDlg,TRUE);
		    break;

		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

static void NEAR InitMiniBox(HWND hDlg)
{
    register int val;
    char buf[80];

    val = (LineState & LINE_ON ? 0 : 1);
    CheckRadioButton(hDlg, IDD_LINE, IDD_LOCAL, IDD_LINE + val);

    val = MWnd.Reverse ? 1 : 0;
    CheckRadioButton(hDlg, IDD_NORMAL, IDD_REVERSE, IDD_NORMAL + val);

    for (val = IDS_JUMP; val <= IDS_SMOOTH8; val++) {
	LoadString(hInst, val, buf, sizeof(buf));
	CBInsertString(hDlg, IDD_SCROLL, -1, buf);
    }
    val = (BOOL)SendMessage(hWndText, SMT_GETATTRIBUTE, SM_SMOOTHSCROLL, 0L);
    if (val) {
        val = (BOOL)SendMessage(hWndText,SMT_GETATTRIBUTE,SM_SCROLLUNITS,0L);
	CBSetCursel(hDlg,IDD_SCROLL,
		    val == 1 ? 1: val == 2 ? 2: val == 4 ? 3: 4);
    }
    else
	CBSetCursel(hDlg, IDD_SCROLL, 0);

    val = HIWORD(SendMessage(hWndText, SMT_GETATTRIBUTE, SM_SCREENSIZE, 0L));
    val = (val == 80 ? 0 : 1);
    CheckRadioButton(hDlg, IDD_80COL, IDD_132COL, IDD_80COL + val);
    
    CheckDlgButton(hDlg, IDD_SAVE, FALSE);

}

static void NEAR SetMiniBox(HWND hDlg)
{

    int val;
    register int i;
    register BOOL save = IsDlgButtonChecked(hDlg, IDD_SAVE);

    for (i = IDD_LINE; i < IDD_LOCAL; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    if (i == IDD_LINE) {
	LineState = LINE_ON + LocalEcho;
	DoMessage = DoPeekMessage;
    } else {
	LineState = LOCAL_ON;
	DoMessage = DoGetMessage;
    }
    if (save) {
	Initdata.LocalMode = (LineState == LOCAL_ON ? TRUE : FALSE);
	SaveInitData(IDS_LOCALMODE, Initdata.LocalMode);
    }

    for (i = IDD_NORMAL; i < IDD_REVERSE; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    val = MWnd.Reverse;
    MWnd.Reverse = i - IDD_NORMAL;
    if (val != MWnd.Reverse)
        InvertScreen(MWnd.Reverse); /* does this take care of graph window? */
    if (save) {
	Initdata.ReverseVideo = MWnd.Reverse;
	SaveInitData(IDS_REVERSEVIDEO, Initdata.ReverseVideo);
    }

    val = CBGetCursel(hDlg, IDD_SCROLL);    
    SendMessage(hWndText, SMT_SETATTRIBUTE, SM_SMOOTHSCROLL,
		val ? (LONG)TRUE : (LONG)FALSE);
    if (val)
	SendMessage(hWndText, SMT_SETATTRIBUTE, SM_SCROLLUNITS,
		    val == 1 ? 1: val == 2 ? 2 : val == 3 ? 4 : 8);

    if (save) {
	Initdata.SmoothScroll = val ? TRUE : FALSE;
	SaveInitData(IDS_SMOOTHSCROLL, Initdata.SmoothScroll);
	Initdata.ScrollUnits = val == 1 ? 1: val == 2 ? 2 : val == 3 ? 4 : 8;
	SaveInitData(IDS_SCROLLUNITS, Initdata.ScrollUnits);
    }

    for (i = IDD_80COL; i < IDD_132COL; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    val = (i == IDD_80COL ? 80 : 132);
    if (val != (int)HIWORD(SendMessage(hWndText,SMT_GETATTRIBUTE,
				       SM_SCREENSIZE,0L)))
        SetCols(val);
    if (save) {
	Initdata.TermCols = val;
	SaveInitData(IDS_COLS, val);
    }
    if (save)
	BroadcastWinIniChange();    
}

BOOL FAR PASCAL ModemBoxProc(HWND hDlg,unsigned message,
			     WORD wParam,LONG lParam)
{

    switch (message) {

	case WM_INITDIALOG:
	    InitModemBox(hDlg);
	    break;	    

	case WM_COMMAND:
	    switch (wParam) {

		case IDD_SAVE:
		    if (IsDlgButtonChecked(hDlg, wParam)) {
		        EnableWindow(GetDlgItem(hDlg, IDD_DEFPORT), FALSE);
			SendDlgItemMessage(hDlg, IDD_DEFPORT,
					   CB_SHOWDROPDOWN, FALSE, 0L);
			CheckDlgButton(hDlg, wParam, FALSE);
		    }
		    else {
		        EnableWindow(GetDlgItem(hDlg, IDD_DEFPORT), TRUE);
			SendDlgItemMessage(hDlg, IDD_DEFPORT,
					   CB_SHOWDROPDOWN, TRUE, 0L);
			CheckDlgButton(hDlg, wParam, TRUE);
		    }
		    break;

		case IDOK:
		    SetModemBox(hDlg);
		    EndDialog(hDlg,TRUE);
		    break;

		case IDCANCEL:
		    EndDialog(hDlg, FALSE);
		    break;
		    
		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

static void NEAR SetModemBox(HWND hDlg)
{
    register int i;
    WORD oldbaud = CommData.BaudRate;
    BYTE oldparity = CommData.Parity;
    BYTE oldbytesize = CommData.ByteSize;
    BYTE oldstopbits = CommData.StopBits;
    BYTE oldparitycheck = CommData.fParity;
    BYTE oldxonxoff = CommData.fOutX & CommData.fInX;
    WORD oldxofflim = CommData.XoffLim;
    BYTE oldport = CommData.Id;
    BYTE newport;
    int result;

  // read selected port
    newport = (BYTE)CBGetCursel(hDlg, IDD_PORT);
    if (newport != oldport) {
	char comstr[10];
	char wintitle[50];
	LoadString(hInst,IDS_COM1 + newport, comstr, sizeof(comstr));
	result = OpenComm(comstr, DEFRXQUE, DEFTXQUE);
	if (result >= 0) {
	    CloseComm(cid);
	    cid = result;
	    CommData.Id = (BYTE)cid;
	    LoadString(hInst, IDS_TITLE, wintitle, sizeof(wintitle));
	    strcat(wintitle, comstr);
	    SetWindowText(MWnd.hWnd, wintitle);	    
	}
	else {
	    ShowMessage(hDlg, result, MB_OK | MB_ICONASTERISK);
	    return;
	}
    }

  // set local echo
    LocalEcho = (IsDlgButtonChecked(hDlg, IDD_LOCALECHO) ? 1 : 0);
    if (LineState != LOCAL_ON)
	LineState = LINE_ON + LocalEcho;

  // read the baud rate selected
    for (i = IDD_110BAUD; i < IDD_19200BAUD; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    CommData.BaudRate = BaudRateTable[i - IDD_110BAUD];

  // read parity/wordsize
    for (i = IDD_8BITNONE; i < IDD_7BITSPACE; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    CommData.ByteSize = ParityTable[i - IDD_8BITNONE].ByteSize;
    CommData.Parity = ParityTable[i - IDD_8BITNONE].Parity;

  // read parity check enabled
    CommData.fParity = (BYTE)(IsDlgButtonChecked(hDlg, IDD_PARCHECK) ? 1 : 0);
    CommData.fPeChar = CommData.fParity;

  // read stopbits
    for (i = IDD_ONESTOPBIT; i < IDD_TWOSTOPBITS; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    CommData.StopBits = (BYTE)(i == IDD_ONESTOPBIT ? ONESTOPBIT : TWOSTOPBITS);

  // read flow control
    CommData.fOutX = (BYTE)(IsDlgButtonChecked(hDlg,
			    IDD_XONXOFF) ? TRUE : FALSE);
    CommData.fInX = CommData.fOutX;

  // read xofflimit
    for (i = IDD_XOFF64; i < IDD_XOFF768; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    CommData.XoffLim = DEFRXQUE - XoffSizeTable[i - IDD_XOFF64];

  // set the state of the comm DCB
    result = SetCommState((DCB FAR *)&CommData);
    if (result == 0) {
	if (IsDlgButtonChecked(hDlg, IDD_SAVE))
	    SaveModemBoxParams(hDlg);
    }
    else {
	CommData.BaudRate = oldbaud;
	CommData.Parity = oldparity;
	CommData.ByteSize = oldbytesize;
	CommData.StopBits = oldstopbits;
	CommData.fParity = CommData.fPeChar = oldparitycheck;
	CommData.fOutX = CommData.fInX = oldxonxoff;
	CommData.XoffLim = oldxofflim;
	SetCommState((DCB FAR *)&CommData);
	ShowMessage(hDlg, result, MB_OK | MB_ICONASTERISK);
    }    
}

static void NEAR SaveModemBoxParams(HWND hDlg)
{

    char szKeyStr[80];
    char szValStr[80];
    int i, v[MAXCOMPORTS];
    int defport;

    defport = CBGetCursel(hDlg, IDD_DEFPORT);
    switch(defport) {
	case 0:
	    v[0] = IDS_COM1; v[1] = IDS_COM2; v[2] = IDS_COM3; v[3] = IDS_COM4;
	    break;
	case 1:
	    v[0] = IDS_COM2; v[1] = IDS_COM1; v[2] = IDS_COM3; v[3] = IDS_COM4;
	    break;
	case 2:
	    v[0] = IDS_COM3; v[1] = IDS_COM1; v[2] = IDS_COM2; v[3] = IDS_COM4;
	    break;
	case 3:
	    v[0] = IDS_COM4; v[1] = IDS_COM1; v[2] = IDS_COM2; v[3] = IDS_COM3;
	    break;
    }
    for (i = 0; i < MAXCOMPORTS; i++) {
        LoadString(hInst,IDS_FIRSTPORT + i,szKeyStr,sizeof(szKeyStr));
        LoadString(hInst,v[i],szValStr,sizeof(szValStr));
        strcpy(Initdata.portname[i], szValStr);
        WritePrivateProfileString(szAppName,szKeyStr,szValStr,szIniName);
    }

    Initdata.LocalEcho = LocalEcho;
    SaveInitData(IDS_LOCALECHO, Initdata.LocalEcho);

    Initdata.BaudRate = CommData.BaudRate;
    SaveInitData(IDS_BAUD, Initdata.BaudRate);

    Initdata.Parity = CommData.Parity;
    SaveInitData(IDS_PARITY, Initdata.Parity);

    Initdata.ByteSize = CommData.ByteSize;
    SaveInitData(IDS_BYTESIZE, Initdata.ByteSize);

    Initdata.StopBits = (BYTE)(CommData.StopBits == ONESTOPBIT ? 1 : 2);
    SaveInitData(IDS_STOPBITS, Initdata.StopBits);
    
    Initdata.fParity = CommData.fParity;
    SaveInitData(IDS_PARCHECK, Initdata.fParity);

    Initdata.XonXoff = CommData.fOutX & CommData.fInX;
    SaveInitData(IDS_XONXOFF, Initdata.XonXoff);

    Initdata.XoffLim = DEFRXQUE - CommData.XoffLim;
    SaveInitData(IDS_XOFFLIM, Initdata.XoffLim);
        
    BroadcastWinIniChange();
}

static void NEAR InitModemBox(HWND hDlg)
{

    char buf[80];
    register int i;

  // set baud rate
    int index;
    index = FindBaudIndex(CommData.BaudRate);
    CheckRadioButton(hDlg, IDD_110BAUD, IDD_19200BAUD, IDD_110BAUD + index);

  // set parity
    index = FindParityIndex(CommData.Parity, CommData.ByteSize);
    CheckRadioButton(hDlg, IDD_8BITNONE, IDD_7BITSPACE, IDD_8BITNONE + index);

  // set parity flag
    CheckDlgButton(hDlg, IDD_PARCHECK, CommData.fParity);

  // set stop bits
    if (CommData.StopBits == ONESTOPBIT)
	index = 0;
    else 
	index = 1;
    CheckRadioButton(hDlg,IDD_ONESTOPBIT,IDD_TWOSTOPBITS,IDD_ONESTOPBIT+index);

  // set xonxoff
    index = CommData.fOutX & CommData.fInX;
    CheckDlgButton(hDlg, IDD_XONXOFF, index);

 // set xofflimit
    index = FindXoffLimit(DEFRXQUE - CommData.XoffLim);
    CheckRadioButton(hDlg, IDD_XOFF64, IDD_XOFF768, IDD_XOFF64 + index);
    
  // set port and initial port
    for (i = 0; i < MAXCOMPORTS; i++) {
	LoadString(hInst, IDS_COM1 + i, buf, sizeof(buf));
	CBInsertString(hDlg, IDD_PORT, i, buf);
	CBInsertString(hDlg, IDD_DEFPORT, i, buf);
	if (strcmp(Initdata.portname[0], buf) == 0)
	    CBSetCursel(hDlg, IDD_DEFPORT, i);
    }
    CBSetCursel(hDlg, IDD_PORT, CommData.Id);

  // set local echo
    CheckDlgButton(hDlg, IDD_LOCALECHO, LocalEcho);

  // set save
    CheckDlgButton(hDlg, IDD_SAVE, FALSE);

  // disable default port choices
    EnableWindow(GetDlgItem(hDlg, IDD_DEFPORT), FALSE);
       
}

/*
static int NEAR FindInitialPort(HWND hDlg, int index)
{
    int i;
    char buf[10];

    for (i = 0; i < MAXCOMPORTS; i++) {
	LoadString(hInst, IDS_COM1+i, buf, sizeof(buf));
	if (strcmp(Initdata.portname[index], buf) == 0)
	    break;	
    }
    return i;
}
*/

static int NEAR FindXoffLimit(WORD val)
{
    int i;
    for (i = 0; i < XOFFLIMSIZE; i++)
	if (val == XoffSizeTable[i])
	    break;
    return i;
}

static int FindParityIndex(BYTE parity, BYTE size)
{
    int i;
    for (i = 0; i < PARITYTABLESIZE; i++)
	if ((parity == ParityTable[i].Parity) && 
					(size == ParityTable[i].ByteSize))
	    break;
    return i;

}

static int NEAR FindBaudIndex(WORD rate)
{
    int i;
    for (i = 0; i < BAUDRATETABLESIZE; i++)
	if (rate == BaudRateTable[i])
	    break;
    return i;
}

BOOL FAR PASCAL DisplayBoxProc(HWND hDlg,unsigned message,
			       WORD wParam,LONG lParam)
{

    switch (message) {

      /* nothing to initialize */
	case WM_INITDIALOG:
	    InitDisplayBox(hDlg);
	    break;	    

      /* this dialog box has only an OK button */
	case WM_COMMAND:
	    switch (wParam) {

		case IDOK:
		    SetDisplayBox(hDlg);
		    EndDialog(hDlg,TRUE);
		    break;

		case IDCANCEL:
		    EndDialog(hDlg, FALSE);
		    break;
		    
		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

static void NEAR InitDisplayBox(HWND hDlg)
{
    register int val;

    CheckDlgButton(hDlg, IDD_AUTOWRAP, MWnd.Wrap);

    CheckDlgButton(hDlg, IDD_AUTOLFCR, MWnd.LFCR);

    val = (BOOL)SendMessage(hWndActive, SMT_GETATTRIBUTE, SM_MARGINBELL, 0L);
    CheckDlgButton(hDlg, IDD_MARGINBELL, val);

    val = MWnd.Cursor;
    CheckRadioButton(hDlg,IDD_CURSOROFF,IDD_CURSORON,IDD_CURSOROFF + val);

    val = MWnd.CursorType;
    CheckRadioButton(hDlg,IDD_CURSORULINE,IDD_CURSORBLOCK,IDD_CURSORULINE+val);

    CheckDlgButton(hDlg, IDD_CONTROLREP, MWnd.ControlRep);

    CheckDlgButton(hDlg, IDD_SAVE, FALSE);
}

static void NEAR SetDisplayBox(HWND hDlg)
{
    WORD val;
    register int i;
    register BOOL save = IsDlgButtonChecked(hDlg, IDD_SAVE);

    val = (IsDlgButtonChecked(hDlg, IDD_AUTOWRAP) ? 1 : 0);
    SendMessage(hWndActive, SMT_SETATTRIBUTE, SM_AUTOWRAP, (LONG)val);
    MWnd.Wrap = val;
    if (save) {
	Initdata.Wrap = val;
	SaveInitData(IDS_WRAP, val);
    }

    val = (IsDlgButtonChecked(hDlg, IDD_CONTROLREP) ? 1 : 0);
    MWnd.ControlRep = val;
    if (val) {
	if (curproto.atype == 52)
	    vt52SetState(-1);
	else
	    vt100SetState(-1);
        SendMessage(hWndActive, SMT_SETATTRIBUTE, SM_AUTOWRAP, (LONG)TRUE);
    }
    else {
	if (curproto.atype == 52)
	    vt52SetState(0);
	else
	    vt100SetState(0);
        SendMessage(hWndActive,SMT_SETATTRIBUTE,SM_AUTOWRAP,(LONG)MWnd.Wrap);
    }
    if (save) {
	Initdata.ControlRep = val;
	SaveInitData(IDS_CONTROLREP, val);
    }

    val = (IsDlgButtonChecked(hDlg, IDD_AUTOLFCR) ? 1 : 0);
    MWnd.LFCR = val;
    if (save) {
	Initdata.LFCR = val;
	SaveInitData(IDS_AUTOLFCR, val);
    }

    val = (IsDlgButtonChecked(hDlg, IDD_MARGINBELL) ? 1 : 0);
    SendMessage(hWndActive, SMT_SETATTRIBUTE, SM_MARGINBELL, (LONG)val);
    if (save) {
	Initdata.MarginBell = val;
	SaveInitData(IDS_MARGINBELL, val);
    }

    for (i = IDD_CURSOROFF; i < IDD_CURSORON; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    MWnd.Cursor = i - IDD_CURSOROFF;
    if (save) {
	Initdata.Cursor = MWnd.Cursor;
	SaveInitData(IDS_CURSOR, Initdata.Cursor);
    }

    for (i = IDD_CURSORULINE; i < IDD_CURSORBLOCK; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    MWnd.CursorType = i - IDD_CURSORULINE;
    if (save) {
	Initdata.CursorType = MWnd.CursorType;
	SaveInitData(IDS_CURSORTYPE, Initdata.CursorType);
    }

    if (save)
	BroadcastWinIniChange();

}

BOOL FAR PASCAL GeneralBoxProc(HWND hDlg,unsigned message,
			       WORD wParam,LONG lParam)
{

    switch (message) {

	case WM_INITDIALOG:
	    InitGeneralBox(hDlg);
	    break;	    

	case WM_COMMAND:
	    switch (wParam) {
		case IDD_SCREENCOLOR:
		    if (HIWORD(lParam) == CBN_SELCHANGE) {
			int scrcolor, textcolor;
			scrcolor = (int)SendDlgItemMessage(hDlg,
				 	IDD_SCREENCOLOR,
					CB_GETCURSEL, 0, 0L);
			textcolor = (int)SendDlgItemMessage(hDlg,IDD_TEXTCOLOR,
					CB_GETCURSEL, 0, 0L);
			if (scrcolor == textcolor) {
			    int mask;
			    if (MWnd.PelSize == 1)
				mask = 1;
			    else
				mask = COLORTABLESIZE - 1;
			    SendDlgItemMessage(hDlg,IDD_TEXTCOLOR,CB_SETCURSEL,
					~textcolor & mask, 0L);
			}
		    }
		    break;

		case IDD_TEXTCOLOR:
		    if (HIWORD(lParam) == CBN_SELCHANGE) {
			int scrcolor, textcolor;
			scrcolor = (int)SendDlgItemMessage(hDlg,
					IDD_SCREENCOLOR,
					CB_GETCURSEL, 0, 0L);
			textcolor = (int)SendDlgItemMessage(hDlg,IDD_TEXTCOLOR,
					CB_GETCURSEL, 0, 0L);
			if (scrcolor == textcolor) {
			    int mask;
			    if (MWnd.PelSize == 1)
				mask = 1;
			    else
				mask = COLORTABLESIZE - 1;
			    SendDlgItemMessage(hDlg,IDD_SCREENCOLOR,
				CB_SETCURSEL, ~scrcolor & mask, 0L);
			}
		    }
		    break;

		case IDD_VT52:
		    CheckRadioButton(hDlg, IDD_7BITS, IDD_8BITS, IDD_7BITS);
		    EnableWindow(GetDlgItem(hDlg, IDD_8BITS), FALSE);
		    break;

		case IDD_VT100:
		    EnableWindow(GetDlgItem(hDlg, IDD_8BITS), TRUE);
		    break;

		case IDOK:
		    SetGeneralBox(hDlg);
		    EndDialog(hDlg,TRUE);
		    break;

		case IDCANCEL:
		    EndDialog(hDlg, FALSE);
		    break;
		    
		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

static void NEAR InitGeneralBox(HWND hDlg)
{
    register int val;
    register int i;
    char buf[80];

    for (i = 0; i < COLORTABLESIZE; i++) {
	if ((MWnd.PelSize == 1) && (i > 0) && (i < COLORTABLESIZE - 1))
	    continue;
	LoadString(hInst, IDS_BLACK + i, buf, sizeof(buf));
	SendDlgItemMessage(hDlg, IDD_SCREENCOLOR, CB_INSERTSTRING, -1,
			   (LONG)(LPSTR)buf);
	SendDlgItemMessage(hDlg, IDD_TEXTCOLOR, CB_INSERTSTRING, -1,
			   (LONG)(LPSTR)buf);
    }
    val = MWnd.BGColor;
    if (MWnd.PelSize == 1)
	val = MWnd.BGColor ? 1 : 0;
    SendDlgItemMessage(hDlg, IDD_SCREENCOLOR, CB_SETCURSEL, val, 0L);
    val = MWnd.TextColor;
    if (MWnd.PelSize == 1)
	val = MWnd.TextColor ? 1 : 0;
    SendDlgItemMessage(hDlg, IDD_TEXTCOLOR, CB_SETCURSEL, val, 0L);

    val = curproto.atype == 52 ? 0 : 1;
    CheckRadioButton(hDlg, IDD_VT52, IDD_VT100, IDD_VT52 + val);

    val = curproto.mask == 0x7f ? 0 : 1;
    CheckRadioButton(hDlg, IDD_7BITS, IDD_8BITS, IDD_7BITS + val);

    val = MWnd.WarningBell;
    CheckDlgButton(hDlg, IDD_WARNINGBELL, val);

}

static void NEAR SetGeneralBox(HWND hDlg)
{

    register int i;
    int val;
    register BOOL save = IsDlgButtonChecked(hDlg, IDD_SAVE);

    val = (IsDlgButtonChecked(hDlg, IDD_WARNINGBELL) ? 1 : 0);
    MWnd.WarningBell = val;
    if (save) {
	Initdata.WarningBell = val;
	SaveInitData(IDS_WARNINGBELL, val);
    }

    for (i = IDD_VT52; i < IDD_VT100; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    SetAlphaParams(i == IDD_VT52 ? 52 : 100);
    if (save) {
	Initdata.AlphaEmulation = curproto.atype;
	SaveInitData(IDS_TERMTYPE, Initdata.AlphaEmulation);
    }

    for (i = IDD_7BITS; i < IDD_8BITS; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    curproto.mask = (BYTE)(i == IDD_7BITS ? 0x7f : 0xff);
    if (save) {
	Initdata.EWidth = i == IDD_7BITS ? 7 : 8;
	SaveInitData(IDS_EMULATIONWIDTH, Initdata.EWidth);
    }

    MWnd.BGColor = (int)SendDlgItemMessage(hDlg, IDD_SCREENCOLOR, CB_GETCURSEL,
					   0, 0L);
    MWnd.TextColor = (int)SendDlgItemMessage(hDlg, IDD_TEXTCOLOR, CB_GETCURSEL,
					     0, 0L);
    if (MWnd.PelSize == 1) {
	MWnd.BGColor = MWnd.BGColor ? COLORTABLESIZE - 1 : 0;
	MWnd.TextColor = MWnd.TextColor ? COLORTABLESIZE - 1 : 0;
    }

    if (save) {
	Initdata.TextColor = MWnd.TextColor;
	SaveInitData(IDS_TEXTCOLOR, Initdata.TextColor);
	Initdata.BGColor = MWnd.BGColor;
	SaveInitData(IDS_BGCOLOR, Initdata.BGColor);
    }
    InvertScreen(MWnd.Reverse);

    if (save)
	BroadcastWinIniChange();
}

/* dialog box function to edit function key strings */
BOOL FAR PASCAL EditFunctionKeys(HWND hDlg,unsigned message,
				 WORD wParam,LONG lParam)
{

    register int i;

    switch (message) {
	case WM_INITDIALOG:
	    CheckRadioButton(hDlg, IDD_F1, IDD_F12, IDD_F6);
	    CheckRadioButton(hDlg,IDD_UNSHIFTED,IDD_CTRLSHIFT,IDD_UNSHIFTED);
	    for (i = IDD_F1; i <= IDD_F12; i++) {
		if ((i <= IDD_F5) || (i == IDD_F10))
		    EnableWindow(GetDlgItem(hDlg, i), FALSE);
		else
		    EnableWindow(GetDlgItem(hDlg, i), TRUE);
	    }
    	    SendDlgItemMessage(hDlg,IDD_STRINGEDIT,EM_LIMITTEXT,80,0L);
	    StringOp(hDlg, IDOK+1);
	    break;

	case WM_COMMAND:
	    switch (wParam) {
		case IDD_F1:
		case IDD_F2:
		case IDD_F3:
		case IDD_F4:
		case IDD_F5:
		case IDD_F6:
		case IDD_F7:
		case IDD_F8:
		case IDD_F9:
		case IDD_F10:
		case IDD_F11:
		case IDD_F12:
		    CheckRadioButton(hDlg, IDD_F1, IDD_F12, wParam);
		    StringOp(hDlg, wParam);
		    break;

		case IDD_UNSHIFTED:
		    CheckRadioButton(hDlg, IDD_F1, IDD_F12, IDD_F6);
		    CheckRadioButton(hDlg,IDD_UNSHIFTED,IDD_CTRLSHIFT,wParam);
		    for (i = IDD_F1; i <= IDD_F12; i++) {
			if ((i <= IDD_F5) || (i == IDD_F10))
			    EnableWindow(GetDlgItem(hDlg, i), FALSE);
			else
			    EnableWindow(GetDlgItem(hDlg, i), TRUE);
		    }
		    StringOp(hDlg, wParam);
		    break;

		case IDD_SHIFT:
		case IDD_CONTROL:
		case IDD_CTRLSHIFT:
		    CheckRadioButton(hDlg, IDD_F1, IDD_F12, IDD_F1);
		    CheckRadioButton(hDlg,IDD_UNSHIFTED,IDD_CTRLSHIFT,wParam);
		    for (i = IDD_F1; i <= IDD_F12; i++) {
			if ((i == IDD_F5) || (i == IDD_F10))
			    EnableWindow(GetDlgItem(hDlg, i), FALSE);
			else
			    EnableWindow(GetDlgItem(hDlg, i), TRUE);
		    }
		    if (wParam == IDD_CTRLSHIFT)
			EnableWindow(GetDlgItem(hDlg, IDD_F5), TRUE);
		    StringOp(hDlg, wParam);
		    break;
/*
		case IDD_STRINGEDIT:
		    if (HIWORD(lParam) == EN_CHANGE) {
		        i = (int)SendDlgItemMessage(hDlg,wParam,
						    WM_GETTEXTLENGTH,0,0L);
		        EnableWindow(GetDlgItem(hDlg, IDOK), i);
		    }
		    break;
*/
		case IDOK:
		    StringOp(hDlg, wParam);
		    break;

		case IDCANCEL:
		    EndDialog(hDlg, FALSE);
		    break;

		default:
		    return FALSE;
	    }
	    break;

	default:
	    return FALSE;
    }
    return TRUE;
}

/* support function for function key edit dialog box */
static void NEAR StringOp(HWND hDlg, WORD param)
{

    register int index, i;
    char fstring[80];
    char *ptr;

    index = 0;
    for (i = IDD_F1; i <= IDD_F12; i++)
	if (SendDlgItemMessage(hDlg,i,BM_GETCHECK,0,0L)) {
	    index = i - IDD_F1;
	    break;
	}
    
    for (i = IDD_UNSHIFTED; i <= IDD_CTRLSHIFT; i++)
	if (SendDlgItemMessage(hDlg,i,BM_GETCHECK,0,0L)) {
	    switch (i) {
		default:
		case IDD_UNSHIFTED:
		    ptr = szFKey[index];
		    break;
		case IDD_SHIFT:
		    ptr = szSFKey[index];
		    break;
		case IDD_CONTROL:
		    ptr = szCFKey[index];
		    break;
		case IDD_CTRLSHIFT:
		    ptr = szCSFKey[index];
		    break;
	    }
	    break;
    }
    if (param == IDOK) {
	SetFocus(GetDlgItem(hDlg,IDOK));
        GetDlgItemText(hDlg, IDD_STRINGEDIT, (LPSTR)fstring, 80);
        WritePrivateProfileString(szAppName,ptr,fstring,szIniName);
	BroadcastWinIniChange();
        SetDlgItemText(hDlg,IDD_STRINGEDIT,(LPSTR)fstring);	    
	SetFocus(GetDlgItem(hDlg,IDD_STRINGEDIT));
    }
    else {
        GetPrivateProfileString((LPSTR)szAppName,(LPSTR)ptr,
				(LPSTR)"",(LPSTR)fstring,80, szIniName);
        SetDlgItemText(hDlg,IDD_STRINGEDIT,(LPSTR)fstring);	    
        SendDlgItemMessage(hDlg,IDD_STRINGEDIT,EM_SETSEL,0,MAKELONG(0,32767));
    }
}

BOOL FAR PASCAL KeyboardBoxProc(HWND hDlg,unsigned message,
				WORD wParam,LONG lParam)
{

    switch (message) {

	case WM_INITDIALOG:
	    InitKeyboardBox(hDlg);
	    break;

	case WM_COMMAND:
	    switch (wParam) {
		case IDD_KEYPADNUMERIC:
		case IDD_KEYPADAPPL:
		    CheckRadioButton(hDlg,IDD_KEYPADNUMERIC,
					IDD_KEYPADAPPL,wParam);
		    break;

		case IDD_CURKEYSNORMAL:
		case IDD_CURKEYSAPPL:
		    CheckRadioButton(hDlg,IDD_CURKEYSNORMAL,
					IDD_CURKEYSAPPL,wParam);
		    break;

		case IDD_BKSPNORMAL:
		case IDD_BKSPDELETE:
		    CheckRadioButton(hDlg,IDD_BKSPNORMAL,
				     IDD_BKSPDELETE,wParam);
		    break;

		case IDD_AUTOANSWER:
		case IDD_BREAKKEY:
		case IDD_SAVE:
		    if (IsDlgButtonChecked(hDlg, wParam))
			CheckDlgButton(hDlg, wParam, FALSE);
		    else
			CheckDlgButton(hDlg, wParam, TRUE);
	  	    break;

		case IDOK:
		    SetKeyboardBox(hDlg);
		    EndDialog(hDlg,TRUE);
		    break;

		case IDCANCEL:
		    EndDialog(hDlg,FALSE);
		    break;

		default:
		    return FALSE;		/* we did not process */
	    }
	    break;
	    
	default:
	    return FALSE;
    }
    return TRUE;		/* we processed message */
}

static void NEAR InitKeyboardBox(HWND hDlg)
{
    register int val;
    char buf[80];
    char key[20];

    val = MWnd.ApplMode + IDD_KEYPADNUMERIC;
    CheckRadioButton(hDlg,IDD_KEYPADNUMERIC,IDD_KEYPADAPPL, val);

    val = IDD_CURKEYSNORMAL + MWnd.CurKeyMode;
    CheckRadioButton(hDlg,IDD_CURKEYSNORMAL,IDD_CURKEYSAPPL, val);

    val = IDD_BKSPNORMAL + MWnd.DeleteKey;
    CheckRadioButton(hDlg,IDD_BKSPNORMAL,IDD_BKSPDELETE, val);

    CheckDlgButton(hDlg, IDD_BREAKKEY, MWnd.BreakEnabled);

    CheckDlgButton(hDlg, IDD_AUTOANSWER, MWnd.AutoAnswer);

    SendDlgItemMessage(hDlg,IDD_ANSWERBACK,EM_LIMITTEXT,80,0L);
    LoadString(hInst,IDS_ANSWERBACKKEY,(LPSTR)key,sizeof(key));
    GetPrivateProfileString((LPSTR)szAppName,(LPSTR)key,
			    (LPSTR)"",buf, sizeof(buf),szIniName);
    SetDlgItemText(hDlg, IDD_ANSWERBACK, buf);

}

static void NEAR SetKeyboardBox(HWND hDlg)
{
    register int i, val;
    BOOL save = IsDlgButtonChecked(hDlg, IDD_SAVE);

    char szKeyStr[80];
    char szValStr[80];

    for (i = IDD_KEYPADNUMERIC; i < IDD_KEYPADAPPL; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    MWnd.ApplMode = i - IDD_KEYPADNUMERIC;
    if (save) {
	Initdata.AltKeypad = MWnd.ApplMode;
	SaveInitData(IDS_ALTKEYPAD, Initdata.AltKeypad);
    }

    for (i = IDD_CURKEYSNORMAL; i < IDD_CURKEYSAPPL; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    MWnd.CurKeyMode = i - IDD_CURKEYSNORMAL;
    if (save) {
	Initdata.CursorKeys = MWnd.CurKeyMode;
	SaveInitData(IDS_CURSORKEYS, Initdata.CursorKeys);
    }

    for (i = IDD_BKSPNORMAL; i < IDD_BKSPDELETE; i++)
	if (SendDlgItemMessage(hDlg, i, BM_GETCHECK, 0, 0L))
	    break;
    MWnd.DeleteKey = i - IDD_BKSPNORMAL;
    if (save) {
	Initdata.DeleteKey = MWnd.DeleteKey;
	SaveInitData(IDS_DELETEKEY, Initdata.DeleteKey);
    }

    val = (IsDlgButtonChecked(hDlg, IDD_BREAKKEY) ? 1 : 0);
    MWnd.BreakEnabled = val;
    if (save) {
	Initdata.BreakEnabled = val;
	SaveInitData(IDS_BREAKKEYENABLED, val);
    }

    val = (IsDlgButtonChecked(hDlg, IDD_AUTOANSWER) ? 1 : 0);
    MWnd.AutoAnswer = val;
    if (save) {
	Initdata.AutoAnswer = val;
	SaveInitData(IDS_AUTOANSWER, val);
    }

    LoadString(hInst,IDS_ANSWERBACKKEY,(LPSTR)szKeyStr,sizeof(szKeyStr));
    GetDlgItemText(hDlg, IDD_ANSWERBACK, (LPSTR)szValStr, sizeof(szValStr));
    WritePrivateProfileString(szAppName, szKeyStr, szValStr, szIniName);

    BroadcastWinIniChange();
}

CBInsertString(HWND hDlg, int id, int index, char * buf)
{
    return (int)SendDlgItemMessage(hDlg, (unsigned)id, CB_INSERTSTRING,
			      (WORD)index, (LONG)(LPSTR)buf);
}

CBSetCursel(HWND hDlg, int id, int index)
{
    return (int)SendDlgItemMessage(hDlg,(unsigned)id,
				   CB_SETCURSEL,(WORD)index,0L);
}

CBGetCursel(HWND hDlg, int id)
{
    return (int)SendDlgItemMessage(hDlg,(unsigned)id,CB_GETCURSEL,0,0L);
}

static void NEAR SaveInitData(int id, int val)
{
    char szKeyStr[80];
    char buf[40];

    LoadString(hInst, id, szKeyStr, sizeof(szKeyStr));
    WritePrivateProfileString(szAppName,szKeyStr,itoa(val,buf,10),szIniName);

}
