/
Crimson2/alias/
Crimson2/area.tmp/
Crimson2/area.tmp/AnomalySpaceDock/
Crimson2/area.tmp/AnomalyStation/
Crimson2/area.tmp/AntHill/
Crimson2/area.tmp/ArcticTerrarium/
Crimson2/area.tmp/BuilderCity/
Crimson2/area.tmp/Dungeon/
Crimson2/area.tmp/MiningDock/
Crimson2/area.tmp/PipeSystem/
Crimson2/area.tmp/RattArea/
Crimson2/area.tmp/RobotFactory/
Crimson2/area.tmp/SilverDale/
Crimson2/area.tmp/StarshipFearless/
Crimson2/area.tmp/StationConduits/
Crimson2/area.tmp/TerrariumAlpha/
Crimson2/area.tmp/TerrariumBeta/
Crimson2/area.tmp/TestArea/
Crimson2/area.tmp/Void/
Crimson2/area/
Crimson2/area/AnomalySpaceDock/
Crimson2/area/AnomalyStation/
Crimson2/area/MiningDock/
Crimson2/area/PipeSystem/
Crimson2/area/SilverDale/
Crimson2/area/StationConduits/
Crimson2/area/Void/
Crimson2/board/
Crimson2/clone/
Crimson2/lib/
Crimson2/mole/
Crimson2/mole/mole_src/HELP/
Crimson2/player/
Crimson2/util/
Crimson2/wldedit/
Crimson2/wldedit/res/
// terminal.c
// two-letter descriptor: tr
// ****************************************************************************
// Copyright (C) B. Cameron Lesiuk, 1999. All rights reserved.
// Permission to use/copy this code is granted for non-commercial use only.
// B. Cameron Lesiuk
// Victoria, BC, Canada
// wi961@freenet.victoria.bc.ca
// ****************************************************************************
//
// This module handles the text terminal for the MUD connection.
#include<windows.h>
#include<windowsx.h>
#include<ctl3d.h>
#include"molem.h"
#include"molerc.h"
#ifdef WIN32
#include"termbuf.h"
#include"ansiterm.h"
#include"main.h"
#endif
#include"terminal.h"
#include"moleprot.h"
#include"host.h"
#include"debug.h"
#include"enviromt.h"
#include"help.h"
#include"about.h"
#include"ctl3dl.h"

/* because otherwise this is a pain in the butt. */
LRESULT CALLBACK _export trAnsiTermAuxProc(ATTERM *p_Term,HWND p_hWnd, UINT p_message,WPARAM p_wParam, LPARAM p_lParam);


#define TR_PROFILE_STR "TerminalWindow"

#ifdef WIN32
ATTERM *g_trTerm; /* handle to our terminal */

BOOL trInitTerminalApplication(HINSTANCE p_hInst) {
  return atInitAnsiTermApplication(p_hInst);
}

BOOL trInitTerminal() {
  if (atInitAnsiTerm()) {
    g_trTerm=atAllocTerm(g_aahInst,g_aahWnd,80L,600L,80L,25L,"TerminalMOLE","MOLE Terminal");
    ((void*)(g_trTerm->aNotify))=((void*)(trNotifyFn));
		((void*)(g_trTerm->aAuxMsgHandler))=((void*)(trAnsiTermAuxProc));
		if (g_trTerm) {
      /* setup any default changes etc. */
      atLoadTermSettings(g_trTerm,TBNOTIFY_OPTIONS,NULL);
      atLoadTermSettings(g_trTerm,TBNOTIFY_FONT,NULL);
			atLoadTermSettings(g_trTerm,TBNOTIFY_MACROS,NULL);
      atAdjustTerm(g_trTerm,-1); /* shows/hides scrollbars, edit, etc. */

      /* now show it! */
      if (enRestoreYesNo(TR_PROFILE_STR,"ShowWindow",TRUE))
        atShowTerm(g_trTerm);
      else
        atHideTerm(g_trTerm);
			return TRUE;
		}
    atShutdownAnsiTerm();
  }
  return FALSE;
}

void trShutdownTerminal() {
  if (g_trTerm) {
    enSaveYesNo(TR_PROFILE_STR,"ShowWindow",atIsTermVisible(g_trTerm));
    atFreeTerm(g_trTerm);
    g_trTerm=NULL;
	}
  return;
}

void trClearTerminal() {
  if (g_trTerm) {
    atClearTerm(g_trTerm);
  }
  return;
}

void trSendTerminal(char *p_buf,unsigned long p_buflen) {
  atSendTerm(g_trTerm,((unsigned char*)(p_buf)),p_buflen);
	return;
}

void trShowTerminal() {
  atShowTerm(g_trTerm);
  mnMenuMainUpdate();
  return;
}

void trHideTerminal() {
  atHideTerm(g_trTerm);
  mnMenuMainUpdate();
	return;
}

BOOL trIsTerminalVisible() {
	return atIsTermVisible(g_trTerm);
}

int trReadTerminalInput(char *p_buf,int p_buflen) {
	return atReadTermInput(g_trTerm,(unsigned char*)(p_buf),(unsigned long)p_buflen);
}

void trNotifyFn(void *p_Term, int p_msg) {
	ATTERM *l_Term=(ATTERM*)p_Term;
	switch (p_msg) {
		case TBNOTIFY_USERINPUT:
			PostMessage(g_aahWnd,WM_USER_TERMINAL_INPUT,0,0L);
			break;
		case TBNOTIFY_OPTIONS:
		case TBNOTIFY_FONT:
		case TBNOTIFY_MACROS:
			atSaveTermSettings(l_Term,p_msg,NULL);
			break;
		case TBNOTIFY_OPTIONSHELP:
			WinHelp(g_aahWnd,g_aaHelpFile,HELP_CONTEXT,HP_AT_DIALOG_ATOPT_HELP);
			break;
		case TBNOTIFY_FONTHELP:
			WinHelp(g_aahWnd,g_aaHelpFile,HELP_CONTEXT,HP_COMMDLG_FONT_HELP);
			break;
		case TBNOTIFY_MACROSHELP:
			WinHelp(g_aahWnd,g_aaHelpFile,HELP_CONTEXT,HP_AT_DIALOG_ATFNKEY_HELP);
			break;
		default:
			dbPrint("WARNING: unhandled ansiterm Notify message");
			break;
	}
	return;
}

LRESULT CALLBACK _export trAnsiTermAuxProc(ATTERM *p_Term,HWND p_hWnd, UINT p_message,
											WPARAM p_wParam, LPARAM p_lParam) {
	switch (p_message) {
		case WM_SYSCOMMAND:
			switch(p_wParam) { /* Process Control Box / Max-Min function */
				case SC_CLOSE:
//					aaWrapup(); /* call wrapup procedure */
					trHideTerminal();
					return(0L);
				default:
					break;
			}
			break;
		case WM_COMMAND:
			{
			switch (GET_WM_COMMAND_ID(p_wParam,p_lParam)) /* Process menu selection event */
				{
				case TBNOTIFY_MENUCLOSE: /* blah blah blah FIX THIS PLEASE!!!!!! */
				case CM_ANSICLOSE:
					trHideTerminal();
					break;
				case CM_MAINFILEEXIT:
					aaWrapup();
					return(0L);
				case CM_MAINHELPCONTENTS:
					WinHelp(g_aahWnd,g_aaHelpFile,HELP_CONTENTS,0L);
					return 0L;
				case CM_MAINHELPSEARCH:
					WinHelp(g_aahWnd,g_aaHelpFile,HELP_FORCEFILE,0L);
					WinHelp(g_aahWnd,g_aaHelpFile,HELP_COMMAND,(DWORD)"Search()");
					return 0L;
				case CM_MAINHELPHOWTOUSE:
					WinHelp(g_aahWnd,NULL,HELP_HELPONHELP,0L);
					return 0L;
				case CM_MAINHELPABOUT:
					DialogBox(g_aahInst,MAKEINTRESOURCE(DIALOG_ABOUT),g_aahWnd,abDialogAboutProc);
					return(0L);
				default:
					break;
				}
			}
			break;
		default:
			break;
		}
	return (DefWindowProc(p_hWnd, p_message, p_wParam, p_lParam));
}

#else /* WIN32 */

/* definitions */
#define TR_ROWS 20 /* number of rows on terminal */

char g_trBuf[85];
int g_trBufPos;
HWND g_trhWnd;

#pragma argsused
BOOL trInitTerminalApplication(HINSTANCE p_hInst) {
	return TRUE;
}

BOOL trInitTerminal() {
  g_trBufPos=0;
  g_trhWnd=CreateDialog(g_aahInst,MAKEINTRESOURCE(DIALOG_TERMINAL),
    g_aahWnd,trDialogTerminalProc);
  aaAddToDialogPool(g_trhWnd);
  if (!g_trhWnd) {
    return FALSE;
  }
  return TRUE;
}

void trShutdownTerminal() {
  if (g_trhWnd) {
    enSaveWindowPlacement(TR_PROFILE_STR,g_trhWnd);
    aaDestroyWindow(g_trhWnd);
    g_trhWnd=NULL;
  }
  return;
}

void trClearTerminal() {
  int l_i;
  if (g_trhWnd) {
    g_trBufPos=0;
    for (l_i=0;l_i<TR_ROWS;l_i++)
      SendDlgItemMessage(g_trhWnd,IDC_TERMINALSCREEN,LB_DELETESTRING,0,0L);
  }
  return;
}

void trSendTerminal(char *p_buf,unsigned long p_buflen) {
  int l_i,l_curlines;
  BOOL l_newline;
  HWND l_hWnd;
  char l_CRLFcheck;

  if (!p_buf) return;

//  dbPrint("Here at the terminal, we got this:");
//  dbPrintNum(p_buf,p_buflen);

  l_hWnd=GetDlgItem(g_trhWnd,IDC_TERMINALSCREEN);
  l_curlines=(int)SendMessage(l_hWnd,LB_GETCOUNT,0,0L);
  l_CRLFcheck=0x00;
  for (l_i=0;l_i<p_buflen;l_i++) {
    l_newline=FALSE;
    if ((p_buf[l_i]==0x0D)||(p_buf[l_i]==0x0A)) {
      if ((l_CRLFcheck) &&(p_buf[l_i]!=l_CRLFcheck)) {
        /* this is a CRLF combo - ignore second dohickey */
        l_CRLFcheck=0x00; /* clear CRLF check flag */
      } else {
        l_newline=TRUE;
        l_CRLFcheck=p_buf[l_i];
      }
    } else {
      l_CRLFcheck=0x00;
      if ((p_buf[l_i]>=32)&&(p_buf[l_i]<127)) {
        g_trBuf[g_trBufPos]=p_buf[l_i];
        g_trBufPos++;
        if (g_trBufPos>=80)
          l_newline=TRUE;
      } else {
        /* ignore character */
      }
    }
    if (l_newline) {
//      dbPrint("Newline to the terminal!");
      g_trBuf[g_trBufPos]=0; /* terminate string */
//      dbPrint(g_trBuf);
      /* delete last line - for replacement */
      if (l_curlines>0)
        SendMessage(l_hWnd,LB_DELETESTRING,l_curlines-1,0L);
      /* append this completed line */
      SendMessage(l_hWnd,LB_ADDSTRING,0,(LPARAM)(LPCSTR)g_trBuf);
      g_trBuf[0]=0;
      g_trBufPos=0;
      /* and append a new (empty) line */
      SendMessage(l_hWnd,LB_ADDSTRING,0,(LPARAM)(LPCSTR)g_trBuf);
      /* delete first line - for scroll */
      if (l_curlines>=TR_ROWS)
        SendMessage(l_hWnd,LB_DELETESTRING,0,0L);
      l_curlines=(int)SendMessage(l_hWnd,LB_GETCOUNT,0,0L);
    }
  }
  /* and now update our last line */
  /* delete last line - for replacement */
  g_trBuf[g_trBufPos]=0; /* terminate string */
  if (l_curlines>0)
    SendMessage(l_hWnd,LB_DELETESTRING,l_curlines-1,0L);
  /* append this completed line */
  SendMessage(l_hWnd,LB_ADDSTRING,0,(LPARAM)(LPCSTR)g_trBuf);
  return;
}

void trShowTerminal() {
  if (g_trhWnd) {
    ShowWindow(g_trhWnd,SW_SHOWMAXIMIZED);
  }
  return;
}

void trHideTerminal() {
  if (g_trhWnd) {
    ShowWindow(g_trhWnd,SW_HIDE);
  }
  return;
}

BOOL trIsTerminalVisible() {
  return IsWindowVisible(g_trhWnd);
}

int trReadTerminalInput(char *p_buf,int p_buflen) {
  int l_i;

//  dbPrint("Fetching terminal input:");
  if (g_trhWnd && p_buf) {
    l_i=GetDlgItemText(g_trhWnd,IDC_TERMINALCOMMAND,p_buf,p_buflen-1);
    /* first, append a CR to the end */
//    p_buf[l_i]='\r';
//    l_i++;
//    dbPrintNum(p_buf,l_i);
    /* now clear and re-enable windows and return buffer */
    SetDlgItemText(g_trhWnd,IDC_TERMINALCOMMAND,"");    /* blank out line */
//    EnableWindow(GetDlgItem(g_trhWnd,IDC_TERMINALSEND),TRUE);
    EnableWindow(GetDlgItem(g_trhWnd,IDC_TERMINALCOMMAND),TRUE);
    SetFocus(GetDlgItem(g_trhWnd,IDC_TERMINALCOMMAND));
  } else {
    l_i=0;
  }
  return l_i;
}

#pragma argsused
BOOL CALLBACK _export trDialogTerminalProc(HWND p_hWnd, UINT p_message,
											WPARAM p_wParam, LPARAM p_lParam)
	{
  switch (p_message)
		{
    case WM_INITDIALOG:
      {
      RECT l_rect;
      WINDOWPLACEMENT *l_placement;

      Ctl3dSubclassDlgEx(p_hWnd,CTL3D_ALL);
      GetWindowRect(p_hWnd,&l_rect);
      l_placement=enRestoreWindowPlacement(TR_PROFILE_STR,l_rect.left,l_rect.top,0,0);
      /* keep size the same -- it's a dialog box */
      l_placement->rcNormalPosition.bottom=l_placement->rcNormalPosition.top+
        (l_rect.bottom-l_rect.top);
      l_placement->rcNormalPosition.right=l_placement->rcNormalPosition.left+
        (l_rect.right-l_rect.left);
      SetWindowPlacement(p_hWnd,l_placement);
      }
      return TRUE;
		case WM_SYSCOMMAND:
			switch(p_wParam) /* Process Control Box / Max-Min function */
				{
				case SC_CLOSE:
          trHideTerminal();
					return TRUE;
				default:
					break;
				}
      break;
    case WM_COMMAND:

      switch (GET_WM_COMMAND_ID(p_wParam,p_lParam))
        {
        case IDC_TERMINALCOMMAND:
          if (GET_WM_COMMAND_CMD(p_wParam,p_lParam)!=EN_VSCROLL)
            break;
//        case IDC_TERMINALSEND:
          if (g_hoConnectedToHost) {
            /* Note that this could interrupt another process. We don't want
             * to interrupt anything so let's send a message to our main
             * window and let it read us and send to the socket. We'll
             * disable the window until it's been successfully read */
//            EnableWindow(GetDlgItem(p_wParam,IDC_TERMINALSEND),FALSE);
            EnableWindow(GetDlgItem(p_wParam,IDC_TERMINALCOMMAND),FALSE);
            PostMessage(g_aahWnd,WM_USER_TERMINAL_INPUT,0,0L);
          }
          return TRUE;
        case IDC_TERMINALSCREEN:
          if (GET_WM_COMMAND_CMD(p_wParam,p_lParam)==LBN_SELCHANGE) {
            SendDlgItemMessage(p_hWnd,IDC_TERMINALSCREEN,LB_SETCURSEL,-1,0);
            SetFocus(GetDlgItem(g_trhWnd,IDC_TERMINALCOMMAND));
          }
          return TRUE;
        default:
          break;
        }
    default:
      break;
		}
	return d3DlgMessageCheck(p_hWnd,p_message,p_wParam,p_lParam);
  }

#endif /* WIN32 */