--- /dev/null
+/*
+ * Implements Kerberos 4 authentication
+ */
+
+#include <time.h>
+#include <string.h>
+#ifdef KRB4
+ #include "kerberos.h"
+#endif
+#include "telnet.h"
+#include "telopts.h"
+
+#ifdef KRB5
+ #include "krb5.h"
+ #include "des_int.h"
+ #include "com_err.h"
+ #include "los-proto.h"
+#endif
+
+/*
+ * Contants
+ */
+ #define IS 0
+ #define SEND 1
+ #define REPLY 2
+ #define NAME 3
+
+ #define AUTH_NULL 0
+ #define KERBEROS_V4 1
+ #define KERBEROS_V5 2
+ #define SPX 3
+ #define RSA 6
+ #define LOKI 10
+
+ #define AUTH 0
+ #define K4_REJECT 1
+ #define K4_ACCEPT 2
+ #define K4_CHALLENGE 3
+ #define K4_RESPONSE 4
+
+ #define K5_REJECT 1
+ #define K5_ACCEPT 2
+ #define K5_RESPONSE 3
+
+ #define AUTH_WHO_MASK 1
+ #define AUTH_CLIENT_TO_SERVER 0
+ #define AUTH_SERVER_TO_CLIENT 1
+
+ #define AUTH_HOW_MASK 2
+ #define AUTH_HOW_ONE_WAY 0
+ #define AUTH_HOW_MUTUAL 2
+
+ #ifndef KSUCCESS
+ #define KSUCCESS 0
+ #define KFAILURE 255
+ #endif
+/*
+ * Globals
+ */
+ #ifdef KRB4
+ static CREDENTIALS cred;
+ #define KRB_SERVICE_NAME "rcmd"
+ #define KERBEROS_VERSION KERBEROS_V4
+ #endif
+ #ifdef KRB5
+ static krb5_data auth;
+ static int auth_how;
+ #define KRB_SERVICE_NAME "host"
+ #define KERBEROS_VERSION KERBEROS_V5
+ #endif
+
+ BOOL encrypt_enable;
+
+/*+
+ * Function: Enable or disable the encryption process.
+ *
+ * Parameters:
+ * enable - TRUE to enable, FALSE to disable.
+ */
+static void auth_encrypt_enable(
+ BOOL enable)
+{
+ encrypt_enable = enable;
+
+} /* auth_encrypt_enable */
+
+
+/*+
+ * Function: Abort the authentication process
+ *
+ * Parameters:
+ * ks - kstream to send abort message to.
+ */
+static void auth_abort(
+ kstream ks,
+ char *errmsg,
+ long r)
+{
+ char buf[9];
+
+ wsprintf(buf, "%c%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS, AUTH_NULL, AUTH_NULL, IAC, SE);
+ TelnetSend(ks, (LPSTR)buf, 8, 0);
+
+ if (errmsg != NULL) {
+ strcpy(strTmp, errmsg);
+
+ if (r != KSUCCESS) {
+ strcat(strTmp, "\n");
+ #ifdef KRB4
+ lstrcat(strTmp, krb_get_err_text(r));
+ #endif
+ #ifdef KRB5
+ lstrcat (strTmp, error_message(r));
+ #endif
+ }
+
+ MessageBox(HWND_DESKTOP, strTmp, "Kerberos authentication failed!", MB_OK | MB_ICONEXCLAMATION);
+ }
+
+} /* auth_abort */
+
+
+/*+
+ * Function: Copy data to buffer, doubling IAC character if present.
+ *
+ * Parameters:
+ * kstream - kstream to send abort message to.
+ */
+static int copy_for_net(
+ unsigned char *to,
+ unsigned char *from,
+ int c)
+{
+ int n;
+
+ n = c;
+
+ while (c-- > 0) {
+ if ((*to++ = *from++) == IAC) {
+ n++;
+ *to++ = IAC;
+ }
+ }
+
+ return n;
+
+} /* copy_for_net */
+
+
+/*+
+ * Function: Parse authentication send command
+ *
+ * Parameters:
+ * ks - kstream to send abort message to.
+ *
+ * parsedat - the sub-command data.
+ *
+ * end_sub - index of the character in the 'parsedat' array which
+ * is the last byte in a sub-negotiation
+ *
+ * Returns: Kerberos error code.
+ */
+static int auth_send(
+ kstream ks,
+ unsigned char *parsedat,
+ int end_sub)
+{
+ char buf[512];
+ char *pname;
+ int plen;
+ int r;
+ int i;
+ #ifdef KRB4
+ KTEXT_ST auth;
+ char instance[INST_SZ];
+ char *realm;
+ #endif /* KRB4 */
+ #ifdef KRB5
+ extern int kerberos5_send (int how);
+ #endif /* KRB5 */
+
+ auth_how = -1;
+
+ for (i = 2; i+1 <= end_sub; i += 2) {
+ if (parsedat[i] == KERBEROS_VERSION)
+ if ((parsedat[i+1] & AUTH_WHO_MASK) == AUTH_CLIENT_TO_SERVER) {
+ auth_how = parsedat[i+1] & AUTH_HOW_MASK;
+ break;
+ }
+ }
+
+ if (auth_how == -1) {
+ auth_abort(ks, NULL, 0);
+ return KFAILURE;
+ }
+
+ #ifdef KRB4
+ memset(instance, 0, sizeof(instance));
+
+ if (realm = krb_get_phost(szHostName))
+ lstrcpy(instance, realm);
+
+ realm = krb_realmofhost(szHostName);
+
+ if (!realm) {
+ strcpy(buf, "Can't find realm for host \"");
+ strcat(buf, szHostName);
+ strcat(buf, "\"");
+ auth_abort(ks, buf, 0);
+ return KFAILURE;
+ }
+
+ r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0);
+
+ if (r == 0)
+ r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred);
+
+ if (r) {
+ strcpy(buf, "Can't get \"");
+ strcat(buf, KRB_SERVICE_NAME);
+ if (instance[0] != 0) {
+ strcat(buf, ".");
+ lstrcat(buf, instance);
+ }
+ strcat(buf, "@");
+ lstrcat(buf, realm);
+ strcat(buf, "\" ticket");
+ auth_abort(ks, buf, r);
+ return r;
+ }
+
+ if (szUserName[0])
+ pname = szUserName;
+ else
+ pname = cred.pname;
+ plen = strlen (szUserName);
+
+ #endif /* KRB4 */
+
+ #ifdef KRB5
+ r = kerberos5_send (auth_how);
+ if (! r)
+ return KFAILURE;
+
+ plen = strlen (szUserName); /* Set in kerberos_5 if needed */
+ pname = szUserName;
+
+ #endif /* KRB5 */
+
+ wsprintf(buf, "%c%c%c%c", IAC, SB, AUTHENTICATION, NAME);
+ memcpy (&buf[4], pname, plen);
+ wsprintf(&buf[plen + 4], "%c%c", IAC, SE);
+ TelnetSend(ks, (LPSTR)buf, lstrlen(pname)+6, 0);
+
+ wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS,
+ KERBEROS_VERSION, auth_how | AUTH_CLIENT_TO_SERVER, AUTH);
+
+ #if KRB4
+ auth.length = copy_for_net(&buf[7], auth.dat, auth.length);
+ #endif /* KRB4 */
+ #if KRB5
+ auth.length = copy_for_net(&buf[7], auth.data, auth.length);
+ #endif /* KRB5 */
+
+ wsprintf(&buf[auth.length+7], "%c%c", IAC, SE);
+
+ TelnetSend(ks, (LPSTR)buf, auth.length+9, 0);
+
+ return KSUCCESS;
+
+} /* auth_send */
+
+/*+
+ * Function: Parse authentication reply command
+ *
+ * Parameters:
+ * ks - kstream to send abort message to.
+ *
+ * parsedat - the sub-command data.
+ *
+ * end_sub - index of the character in the 'parsedat' array which
+ * is the last byte in a sub-negotiation
+ *
+ * Returns: Kerberos error code.
+ */
+#ifdef KRB5
+static int auth_reply(
+ kstream ks,
+ unsigned char *parsedat,
+ int end_sub)
+{
+ extern int kerberos5_reply (int how, unsigned char *data, int cnt);
+ int n;
+
+ n = kerberos5_reply (0, parsedat, end_sub);
+
+ return n;
+}
+#endif /* KRB5 */
+#ifdef KRB4
+static int auth_reply(
+ kstream ks,
+ unsigned char *parsedat,
+ int end_sub)
+{
+ time_t t;
+ int x;
+ char buf[512];
+ int i;
+ des_cblock session_key;
+ des_key_schedule sched;
+ static des_cblock challenge;
+
+ if (end_sub < 4)
+ return KFAILURE;
+
+ if (parsedat[2] != KERBEROS_V4)
+ return KFAILURE;
+
+ if (parsedat[4] == K4_REJECT) {
+ buf[0] = 0;
+
+ for (i = 5; i <= end_sub; i++) {
+ if (parsedat[i] == IAC)
+ break;
+ buf[i-5] = parsedat[i];
+ buf[i-4] = 0;
+ }
+
+ if (!buf[0])
+ strcpy(buf, "Authentication rejected by remote machine!");
+ MessageBox(HWND_DESKTOP, buf, NULL, MB_OK | MB_ICONEXCLAMATION);
+
+ return KFAILURE;
+ }
+
+ if (parsedat[4] == K4_ACCEPT) {
+ if ((parsedat[3] & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY)
+ return KSUCCESS;
+
+ if ((parsedat[3] & AUTH_HOW_MASK) != AUTH_HOW_MUTUAL)
+ return KFAILURE;
+
+ des_key_sched(cred.session, sched);
+
+ t = time(NULL);
+ memcpy(challenge, &t, 4);
+ memcpy(&challenge[4], &t, 4);
+ des_ecb_encrypt(&challenge, &session_key, sched, 1);
+
+ /*
+ * Increment the challenge by 1, and encrypt it for
+ * later comparison.
+ */
+ for (i = 7; i >= 0; --i) {
+ x = (unsigned int)challenge[i] + 1;
+ challenge[i] = x; /* ignore overflow */
+ if (x < 256) /* if no overflow, all done */
+ break;
+ }
+
+ des_ecb_encrypt(&challenge, &challenge, sched, 1);
+
+ wsprintf(buf, "%c%c%c%c%c%c%c", IAC, SB, AUTHENTICATION, IS,
+ KERBEROS_V4, AUTH_CLIENT_TO_SERVER|AUTH_HOW_MUTUAL, K4_CHALLENGE);
+ memcpy(&buf[7], session_key, 8);
+ wsprintf(&buf[15], "%c%c", IAC, SE);
+ TelnetSend(ks, (LPSTR)buf, 17, 0);
+
+ return KSUCCESS;
+ }
+
+ if (parsedat[4] == K4_RESPONSE) {
+ if (end_sub < 12)
+ return KFAILURE;
+
+ if (memcmp(&parsedat[5], challenge, sizeof(challenge)) != 0) {
+ MessageBox(HWND_DESKTOP, "Remote machine is being impersonated!",
+ NULL, MB_OK | MB_ICONEXCLAMATION);
+
+ return KFAILURE;
+ }
+
+ return KSUCCESS;
+ }
+
+ return KFAILURE;
+
+} /* auth_reply */
+
+#endif /* KRB4 */
+/*+
+ * Function: Parse the athorization sub-options and reply.
+ *
+ * Parameters:
+ * ks - kstream to send abort message to.
+ *
+ * parsedat - sub-option string to parse.
+ *
+ * end_sub - last charcter position in parsedat.
+ */
+void auth_parse(
+ kstream ks,
+ unsigned char *parsedat,
+ int end_sub)
+{
+ if (parsedat[1] == SEND)
+ auth_send(ks, parsedat, end_sub);
+
+ if (parsedat[1] == REPLY)
+ auth_reply(ks, parsedat, end_sub);
+
+} /* auth_parse */
+
+
+/*+
+ * Function: Initialization routine called kstream encryption system.
+ *
+ * Parameters:
+ * str - kstream to send abort message to.
+ *
+ * data - user data.
+ */
+int INTERFACE auth_init(
+ kstream str,
+ kstream_ptr data)
+{
+ return 0;
+
+} /* auth_init */
+
+
+/*+
+ * Function: Destroy routine called kstream encryption system.
+ *
+ * Parameters:
+ * str - kstream to send abort message to.
+ *
+ * data - user data.
+ */
+void INTERFACE auth_destroy(
+ kstream str)
+{
+} /* auth_destroy */
+
+
+/*+
+ * Function: Callback to encrypt a block of characters
+ *
+ * Parameters:
+ * out - return as pointer to converted buffer.
+ *
+ * in - the buffer to convert
+ *
+ * str - the stream being encrypted
+ *
+ * Returns: number of characters converted.
+ */
+int INTERFACE auth_encrypt(
+ struct kstream_data_block *out,
+ struct kstream_data_block *in,
+ kstream str)
+{
+ out->ptr = in->ptr;
+
+ out->length = in->length;
+
+ return(out->length);
+
+} /* auth_encrypt */
+
+
+/*+
+ * Function: Callback to decrypt a block of characters
+ *
+ * Parameters:
+ * out - return as pointer to converted buffer.
+ *
+ * in - the buffer to convert
+ *
+ * str - the stream being encrypted
+ *
+ * Returns: number of characters converted.
+ */
+int INTERFACE auth_decrypt(
+ struct kstream_data_block *out,
+ struct kstream_data_block *in,
+ kstream str)
+{
+ out->ptr = in->ptr;
+
+ out->length = in->length;
+
+ return(out->length);
+
+} /* auth_decrypt */
+
+/*+*/
+#ifdef KRB5
+
+/*
+**
+** Code lifted from telnet sample code in the appl directory.
+**
+*/
+
+krb5_auth_context *auth_context;
+krb5_flags krb5_kdc_default_options = KDC_OPT_RENEWABLE_OK;
+
+/* 0 on failure, 1 on success */
+int
+kerberos5_send (int how)
+{
+ krb5_error_code r;
+ krb5_ccache ccache;
+ krb5_creds cred;
+ krb5_creds * new_cred;
+ extern krb5_flags krb5_kdc_default_options;
+ krb5_flags ap_opts;
+ int len;
+
+ if (r = krb5_cc_default(k5_context, &ccache)) {
+ com_err (NULL, r, "while authorizing.");
+ return(0);
+ }
+
+ memset((char *)&cred, 0, sizeof(cred));
+ if (r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME,
+ KRB5_NT_SRV_HST, &cred.server)) {
+ com_err (NULL, r, "while authorizing.");
+ return(0);
+ }
+
+ if (r = krb5_cc_get_principal(k5_context, ccache, &cred.client)) {
+ com_err (NULL, r, "while authorizing.");
+ krb5_free_cred_contents(k5_context, &cred);
+ return(0);
+ }
+ if (szUserName[0] == '\0') { /* Get user name now */
+ len = krb5_princ_component(k5_context, cred.client, 0)->length;
+ memcpy (szUserName,
+ krb5_princ_component(k5_context, cred.client, 0)->data,
+ len);
+ szUserName[len] = '\0';
+ }
+
+
+ if (r = krb5_get_credentials(k5_context, krb5_kdc_default_options,
+ ccache, &cred, &new_cred)) {
+ com_err (NULL, r, "while authorizing.");
+ krb5_free_cred_contents(k5_context, &cred);
+ return(0);
+ }
+
+ ap_opts = 0;
+ if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
+ ap_opts = AP_OPTS_MUTUAL_REQUIRED;
+
+ r = krb5_mk_req_extended(k5_context, &auth_context, ap_opts,
+ NULL, new_cred, &auth);
+
+ krb5_free_cred_contents(k5_context, &cred);
+ krb5_free_creds(k5_context, new_cred);
+
+ if (r) {
+ com_err (NULL, r, "while authorizing.");
+ return(0);
+ }
+
+ return(1);
+}
+/*+*/
+int
+kerberos5_reply (int how, unsigned char *data, int cnt) {
+ static int mutual_complete = 0;
+
+ data += 4; /* Point to status byte */
+
+ switch (*data++) {
+ case K5_REJECT:
+ if (cnt > 0)
+ wsprintf (strTmp,
+ "Kerberos V5 refuses authentication because %.*s",
+ cnt, data);
+ else
+ wsprintf (strTmp, "Kerberos V5 refuses authentication");
+ MessageBox (HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION);
+
+ return KFAILURE;
+
+ case K5_ACCEPT:
+ if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && !mutual_complete) {
+ wsprintf(strTmp, "Kerberos V5 accepted you, "
+ "but didn't provide mutual authentication");
+ MessageBox (HWND_DESKTOP, strTmp, "", MB_OK | MB_ICONEXCLAMATION);
+ return KSUCCESS;
+ }
+
+ return KSUCCESS;
+ break;
+
+ case K5_RESPONSE:
+ if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
+ /* the rest of the reply should contain a krb_ap_rep */
+ krb5_ap_rep_enc_part *reply;
+ krb5_data inbuf;
+ krb5_error_code r;
+
+ inbuf.length = cnt;
+ inbuf.data = (char *)data;
+
+ if (r = krb5_rd_rep (k5_context, auth_context, &inbuf, &reply)) {
+ com_err (NULL, r, "while authorizing.");
+ return KFAILURE;
+ }
+ krb5_free_ap_rep_enc_part(k5_context, reply);
+
+ mutual_complete = 1;
+ }
+ return KSUCCESS;
+
+ default:
+ return KSUCCESS; // Unknown code
+ }
+}
+#endif /* KRB5 */
--- /dev/null
+/*
+ * Implements Kerberos 4 authentication and ecryption
+ */
+
+void auth_parse(
+ kstream ks,
+ unsigned char *parsedat,
+ int end_sub);
+
+int INTERFACE auth_init(
+ kstream str,
+ kstream_ptr data);
+
+void INTERFACE auth_destroy(
+ kstream str);
+
+int INTERFACE auth_encrypt(
+ struct kstream_data_block *out,
+ struct kstream_data_block *in,
+ kstream str);
+
+int INTERFACE auth_decrypt(
+ struct kstream_data_block *out,
+ struct kstream_data_block *in,
+ kstream str);
--- /dev/null
+Mon Mar 27 20:18:41 1995 Keith Vetter (keithv@fusion.com)
+
+ * Initial release based upon the K4 version.
+ * K4 streams layer is replaced with no-ops in k5stream.c
+ * only one-way authentication tested since a telnet daemon which
+ does mutual is not available.
+ * connect port is hard-wired to 13131 for now since that is the
+ port of the only available K5 telnet daemon (tsx-11.mit.edu)
--- /dev/null
+#define IDM_ABOUT 100
+#define IDM_SHOWCONSOLE 700
+
+#define IDM_OPENTELNETDLG 200
+#define TEL_CONNECT_NAME 201
+#define TEL_USEDEFAULTS 202
+#define TEL_MANUALCONFIGURE 203
+#define TEL_OK 204
+#define TEL_CANCEL 206
+#define CON_SESSIONNAME 302
+#define CON_WINDOWTITLE 304
+#define CON_COLUMNS132 305
+#define CON_COLUMNS80 306
+#define CON_BACKSPACE 307
+#define CON_DELETE 308
+#define CON_CRLF 309
+#define CON_CRNUL 310
+#define CON_BUFFERS 311
+#define CON_SENDS 312
+#define CON_OK 320
+#define CON_USEDEFAULTS 321
+#define CONFIGDLG 300
+#define CON_SCRLBCK 317
+#define CON_NUMLINES 318
+#define PRINTQUEUE 400
+#define IDM_PRINTQUEUE 500
+#define TEL_PUSH1 601
+#define TEL_PUSH2 602
+#define TEL_PUSH3 603
+#define TEL_PUSH4 604
+#define TEL_PUSH5 605
--- /dev/null
+#include <windows.h>
+#include <commdlg.h>
+#include <ctype.h>
+#include "screen.h"
+
+char *cInvertedArray;
+int bMouseDown=FALSE;
+int iLocStart,iLocEnd,bSelection;
+
+void Edit_LbuttonDown(HWND hWnd,LPARAM lParam) {
+ SCREEN *fpScr;
+ HGLOBAL hgScr;
+ HMENU hMenu;
+ int iTmp,iXlocStart,iYlocStart;
+ HDC hDC;
+
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+
+ hDC=GetDC(hWnd);
+ for (iTmp=0; iTmp < fpScr->width*fpScr->height; iTmp++) {
+ if (cInvertedArray[iTmp]) {
+ PatBlt(hDC,(iTmp%fpScr->width)*fpScr->cxChar,(int)(iTmp/fpScr->width)*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp]=0;
+ }
+ }
+ bSelection=FALSE;
+ hMenu=GetMenu(hWnd);
+ EnableMenuItem(hMenu,IDM_COPY,MF_GRAYED);
+ ReleaseDC(hWnd,hDC);
+ iXlocStart=(int)LOWORD(lParam)/fpScr->cxChar;
+ if (iXlocStart >= fpScr->width)
+ iXlocStart = fpScr->width - 1;
+ iYlocStart=(int)HIWORD(lParam)/fpScr->cyChar;
+ if (iYlocStart >= fpScr->height)
+ iYlocStart = fpScr->height - 1;
+ iLocStart=iXlocStart+(iYlocStart*fpScr->width);
+ bMouseDown=TRUE;
+ GlobalUnlock(hgScr);
+}
+
+void Edit_LbuttonUp(HWND hWnd, LPARAM lParam) {
+ SCREEN *fpScr;
+ HGLOBAL hgScr;
+ int iTmp,iTmp2;
+ HMENU hMenu;
+
+ bMouseDown=FALSE;
+ if (bSelection) return;
+ bSelection=TRUE;
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+ iTmp=(int)LOWORD(lParam)/fpScr->cxChar;
+ if (iTmp >= fpScr->width)
+ iTmp = fpScr->width - 1;
+ iTmp2=(int)HIWORD(lParam)/fpScr->cyChar;
+ if (iTmp2 >= fpScr->height)
+ iTmp2 = fpScr->height - 1;
+ GlobalUnlock(hgScr);
+ iLocEnd=iTmp+(iTmp2*fpScr->width);
+ if (iLocEnd==iLocStart) {
+ bSelection=FALSE;
+ } else {
+ hMenu=GetMenu(hWnd);
+ EnableMenuItem(hMenu,IDM_COPY,MF_ENABLED);
+ }
+}
+
+void Edit_MouseMove(HWND hWnd, LPARAM lParam){
+ SCREEN *fpScr;
+ HGLOBAL hgScr;
+ int iTmp,iTmp2,iXlocCurr,iYlocCurr,iLocCurr,iX,iX2,iY,iY2;
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ HDC hDC;
+
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+ hDC = GetDC(hWnd);
+ iXlocCurr=(int)LOWORD(lParam)/fpScr->cxChar;
+ if (iXlocCurr >= fpScr->width)
+ iXlocCurr = fpScr->width - 1;
+ iYlocCurr=(int)HIWORD(lParam)/fpScr->cyChar;
+ if (iYlocCurr >= fpScr->height)
+ iYlocCurr = fpScr->height - 1;
+ iLocCurr=iXlocCurr+(iYlocCurr*fpScr->width);
+ if (iLocCurr > iLocStart) {
+ for (iTmp=0; iTmp < iLocStart; iTmp++) {
+ if (cInvertedArray[iTmp]) {
+ PatBlt(hDC,(iTmp%fpScr->width)*fpScr->cxChar,(int)(iTmp/fpScr->width)*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp]=0;
+ }
+ }
+ iX=(iLocStart%fpScr->width);
+ iY=(int)(iLocStart/fpScr->width);
+ iX2=(iLocCurr%fpScr->width);
+ iY2=(int)(iLocCurr/fpScr->width);
+ if (iY==iY2) {
+ hgScrLine=GetScreenLineFromY(fpScr,iY);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ for (iTmp2= iX; iTmp2 < iX2; iTmp2++) {
+ if ((!cInvertedArray[iTmp2+(fpScr->width*iY)])&& fpScrLine->text[iTmp2]) {
+ PatBlt(hDC,(iTmp2)*fpScr->cxChar,iY*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(fpScr->width*iY)]=fpScrLine->text[iTmp2];
+ }
+ }
+ LINE_MEM_UNLOCK(hgScrLine);
+ }
+ else {
+ hgScrLine=GetScreenLineFromY(fpScr,iY);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ for (iTmp2= iX; iTmp2 < fpScr->width; iTmp2++) {
+ if ((!cInvertedArray[iTmp2+(fpScr->width*iY)])&& fpScrLine->text[iTmp2]) {
+ PatBlt(hDC,(iTmp2)*fpScr->cxChar,iY*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(fpScr->width*iY)]=fpScrLine->text[iTmp2];
+ }
+ }
+ for (iTmp=iY+1; iTmp < iY2; iTmp++) {
+ hgScrLine=GetScreenLineFromY(fpScr,iTmp);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ for (iTmp2= 0; iTmp2 < fpScr->width; iTmp2++) {
+ if ((!cInvertedArray[iTmp2+(fpScr->width*iTmp)])&& fpScrLine->text[iTmp2]) {
+ PatBlt(hDC,(iTmp2)*fpScr->cxChar,iTmp*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(fpScr->width*iTmp)]=fpScrLine->text[iTmp2];
+ }
+ }
+ LINE_MEM_UNLOCK(hgScrLine);
+ }
+ if (!(iY2==iY)) {
+ hgScrLine=GetScreenLineFromY(fpScr,iY2);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ for (iTmp2= 0; iTmp2 < iX2; iTmp2++) {
+ if ((!cInvertedArray[iTmp2+(fpScr->width*iY2)])&& fpScrLine->text[iTmp2]) {
+ PatBlt(hDC,(iTmp2)*fpScr->cxChar,iY2*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(fpScr->width*iY2)]=fpScrLine->text[iTmp2];
+ }
+ }
+ LINE_MEM_UNLOCK(hgScrLine);
+ }
+
+ }
+ for (iTmp=iLocCurr; iTmp < fpScr->width*fpScr->height; iTmp++) {
+ if (cInvertedArray[iTmp]) {
+ PatBlt(hDC,(iTmp%fpScr->width)*fpScr->cxChar,(int)(iTmp/fpScr->width)*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp]=0;
+ }
+ }
+ } else { /* going backwards */
+ for (iTmp=0; iTmp < iLocCurr; iTmp++) {
+ if (cInvertedArray[iTmp]) {
+ PatBlt(hDC,(iTmp%fpScr->width)*fpScr->cxChar,(int)(iTmp/fpScr->width)*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp]=0;
+ }
+ }
+ iX=(iLocCurr%fpScr->width);
+ iY=(int)(iLocCurr/fpScr->width);
+ iX2=(iLocStart%fpScr->width);
+ iY2=(int)(iLocStart/fpScr->width);
+ if (iY==iY2) {
+ hgScrLine=GetScreenLineFromY(fpScr,iY);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ for (iTmp2= iX; iTmp2 < iX2; iTmp2++) {
+ if ((!cInvertedArray[iTmp2+(fpScr->width*iY)])&& fpScrLine->text[iTmp2]) {
+ PatBlt(hDC,(iTmp2)*fpScr->cxChar,iY*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(fpScr->width*iY)]=fpScrLine->text[iTmp2];
+ }
+ }
+ LINE_MEM_UNLOCK(hgScrLine);
+ }
+ else {
+ hgScrLine=GetScreenLineFromY(fpScr,iY);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ for (iTmp2= iX; iTmp2 < fpScr->width; iTmp2++) {
+ if ((!cInvertedArray[iTmp2+(fpScr->width*iY)])&& fpScrLine->text[iTmp2]) {
+ PatBlt(hDC,(iTmp2)*fpScr->cxChar,iY*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(fpScr->width*iY)]=fpScrLine->text[iTmp2];
+ }
+ }
+ for (iTmp=iY+1; iTmp < iY2; iTmp++) {
+ hgScrLine=GetScreenLineFromY(fpScr,iTmp);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ for (iTmp2= 0; iTmp2 < fpScr->width; iTmp2++) {
+ if ((!cInvertedArray[iTmp2+(fpScr->width*iTmp)])&& fpScrLine->text[iTmp2]) {
+ PatBlt(hDC,(iTmp2)*fpScr->cxChar,iTmp*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(fpScr->width*iTmp)]=fpScrLine->text[iTmp2];
+ }
+ }
+ LINE_MEM_UNLOCK(hgScrLine);
+ }
+ if (!(iY2==iY)) {
+ hgScrLine=GetScreenLineFromY(fpScr,iY2);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ for (iTmp2= 0; iTmp2 < iX2; iTmp2++) {
+ if ((!cInvertedArray[iTmp2+(fpScr->width*iY2)])&& fpScrLine->text[iTmp2]) {
+ PatBlt(hDC,(iTmp2)*fpScr->cxChar,iY2*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(fpScr->width*iY2)]=fpScrLine->text[iTmp2];
+ }
+ }
+ LINE_MEM_UNLOCK(hgScrLine);
+ }
+
+ }
+ for (iTmp=iLocStart; iTmp < fpScr->width*fpScr->height; iTmp++) {
+ if (cInvertedArray[iTmp]) {
+ PatBlt(hDC,(iTmp%fpScr->width)*fpScr->cxChar,(int)(iTmp/fpScr->width)*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp]=0;
+ }
+ }
+
+ }
+ ReleaseDC(hWnd,hDC);
+ GlobalUnlock(hgScr);
+}
+
+void Edit_ClearSelection(SCREEN *fpScr) {
+ int iTmp;
+ HDC hDC;
+ HMENU hMenu;
+
+ hDC=GetDC(fpScr->hWnd);
+ for (iTmp=0; iTmp < fpScr->width*fpScr->height; iTmp++) {
+ if (cInvertedArray[iTmp]) {
+ PatBlt(hDC,(iTmp%fpScr->width)*fpScr->cxChar,(int)(iTmp/fpScr->width)*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp]=0;
+ }
+ }
+ bSelection=FALSE;
+ hMenu=GetMenu(fpScr->hWnd);
+ EnableMenuItem(hMenu,IDM_COPY,MF_GRAYED);
+ ReleaseDC(fpScr->hWnd,hDC);
+}
+
+void Edit_Copy(HWND hWnd) {
+ int iTmp,iIdx;
+ HGLOBAL hCutBuffer;
+ LPSTR lpCutBuffer;
+ SCREEN *fpScr;
+ HGLOBAL hgScr;
+
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+
+ hCutBuffer= GlobalAlloc(GHND,(DWORD)(fpScr->width*fpScr->height+1));
+ lpCutBuffer= GlobalLock(hCutBuffer);
+
+ if (iLocStart > iLocEnd) { /* swap variables */
+ iTmp=iLocStart;
+ iLocStart=iLocEnd;
+ iLocEnd=iLocStart;
+ }
+ iTmp=iLocStart;
+ iIdx=0;
+ while (iTmp < iLocEnd) {
+ if (!cInvertedArray[iTmp]) {
+ lpCutBuffer[iIdx++]='\r';
+ lpCutBuffer[iIdx++]='\n';
+ iTmp= (((int)(iTmp/fpScr->width))+1)*fpScr->width;
+ continue;
+ }
+ lpCutBuffer[iIdx++]=cInvertedArray[iTmp++];
+ }
+ lpCutBuffer[iIdx]=0;
+ GlobalUnlock(hCutBuffer);
+ OpenClipboard(hWnd);
+ EmptyClipboard();
+ SetClipboardData(CF_TEXT,hCutBuffer);
+ CloseClipboard();
+}
+
+void Edit_Paste(HWND hWnd) {
+ HGLOBAL hClipMemory;
+ static HGLOBAL hMyClipBuffer;
+ LPSTR lpClipMemory,lpMyClipBuffer;
+ HGLOBAL hgScr;
+ SCREEN *fpScr;
+
+ if (hMyClipBuffer) GlobalFree(hMyClipBuffer);
+ OpenClipboard(hWnd);
+ hClipMemory = GetClipboardData(CF_TEXT);
+ hMyClipBuffer = GlobalAlloc(GHND,GlobalSize(hClipMemory));
+ lpMyClipBuffer= GlobalLock(hMyClipBuffer);
+ lpClipMemory= GlobalLock(hClipMemory);
+
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+
+ lstrcpy(lpMyClipBuffer,lpClipMemory);
+// OutputDebugString(lpMyClipBuffer);
+ PostMessage(fpScr->hwndTel,WM_MYSCREENBLOCK,(WPARAM)hMyClipBuffer,
+ (HSCREEN)hgScr);
+ CloseClipboard();
+ GlobalUnlock(hClipMemory);
+ GlobalUnlock(hMyClipBuffer);
+}
+
+void Edit_LbuttonDblclk(HWND hWnd,LPARAM lParam) {
+ HDC hDC;
+ SCREEN *fpScr;
+ HGLOBAL hgScr;
+ int iTmp,iTmp2,iXlocStart,iYloc;
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+
+ hDC=GetDC(hWnd);
+ for (iTmp=0; iTmp < fpScr->width*fpScr->height; iTmp++) {
+ if (cInvertedArray[iTmp]) {
+ PatBlt(hDC,(iTmp%fpScr->width)*fpScr->cxChar,(int)(iTmp/fpScr->width)*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp]=0;
+ }
+ }
+ bSelection=FALSE;
+ iXlocStart=(int)LOWORD(lParam)/fpScr->cxChar;
+ if (iXlocStart >= fpScr->width)
+ iXlocStart = fpScr->width - 1;
+ iYloc=(int)HIWORD(lParam)/fpScr->cyChar;
+ if (iYloc >= fpScr->height)
+ iYloc = fpScr->height - 1;
+ iLocStart=iXlocStart+(iYloc*fpScr->width);
+
+ hgScrLine=GetScreenLineFromY(fpScr,iYloc);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+
+ iTmp=iXlocStart;
+ while (isalnum((int)fpScrLine->text[iTmp])) {
+ PatBlt(hDC,iTmp*fpScr->cxChar,iYloc*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp+(iYloc*fpScr->width)]=fpScrLine->text[iTmp];
+ iTmp++;
+ }
+ iTmp2=iXlocStart-1;
+ while (isalnum((int)fpScrLine->text[iTmp2])) {
+ PatBlt(hDC,iTmp2*fpScr->cxChar,iYloc*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp2+(iYloc*fpScr->width)]=fpScrLine->text[iTmp2];
+ iTmp2--;
+ }
+ iLocStart=(iTmp2+1)+(iYloc*fpScr->width);
+ iLocEnd=(iTmp)+(iYloc*fpScr->width);
+
+ bSelection=TRUE;
+ ReleaseDC(hWnd,hDC);
+ LINE_MEM_UNLOCK(hgScrLine);
+ GlobalUnlock(hgScr);
+}
+
+void Edit_TripleClick(HWND hWnd,LPARAM lParam) {
+ HDC hDC;
+ SCREEN *fpScr;
+ HGLOBAL hgScr;
+ int iTmp,iYloc;
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+
+// OutputDebugString("Triple Click \r\n");
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+
+ hDC=GetDC(hWnd);
+ for (iTmp=0; iTmp < fpScr->width*fpScr->height; iTmp++) {
+ if (cInvertedArray[iTmp]) {
+ PatBlt(hDC,(iTmp%fpScr->width)*fpScr->cxChar,(int)(iTmp/fpScr->width)*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp]=0;
+ }
+ }
+ bSelection=FALSE;
+ iYloc=(int)HIWORD(lParam)/fpScr->cyChar;
+ if (iYloc >= fpScr->height)
+ iYloc = fpScr->height - 1;
+ iLocStart=(iYloc*fpScr->width);
+
+ hgScrLine=GetScreenLineFromY(fpScr,iYloc);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+
+ for (iTmp=0; iTmp<fpScr->width; iTmp++) {
+ if (fpScrLine->text[iTmp]) {
+ PatBlt(hDC,iTmp*fpScr->cxChar,iYloc*fpScr->cyChar,
+ fpScr->cxChar,fpScr->cyChar,DSTINVERT);
+ cInvertedArray[iTmp+(iYloc*fpScr->width)]=fpScrLine->text[iTmp];
+ } else break;
+ }
+ iLocEnd=(iTmp+(iYloc*fpScr->width));
+
+ bSelection=TRUE;
+ ReleaseDC(hWnd,hDC);
+ LINE_MEM_UNLOCK(hgScrLine);
+ GlobalUnlock(hgScr);
+}
--- /dev/null
+#include "windows.h"
+#include "screen.h"
+
+/**********************************************************************
+* Function : ScreenEmChar
+* Purpose : Send a character to the virtual screen with no translantion
+* Parameters :
+ fpScr - pointer top screen
+* c - character to send to the virtual screen
+* Returns : none
+* Calls :
+* Called by : ScreenEm()
+**********************************************************************/
+static int ScreenEmChar(SCREEN *fpScr,unsigned char c)
+{
+ int sx;
+ int insert,
+ ocount,
+ attrib,
+ extra,
+ offend;
+ char *acurrent, /* pointer to the attributes for characters drawn */
+ *current, /* pointer to the place to put characters */
+ *start;
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+
+ hgScrLine=GetScreenLineFromY(fpScr,fpScr->y);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL) return (-1);
+
+ current=start=&fpScrLine->text[fpScr->x];
+ acurrent=&fpScrLine->attrib[fpScr->x];
+
+ attrib=fpScr->attrib;
+ insert=fpScr->IRM; /* boolean */
+ ocount=fpScr->x;
+ offend=0;
+ extra=0;
+ sx=fpScr->x;
+ if(fpScr->x>fpScr->width) {
+ if(fpScr->DECAWM) { /* check for line wrapping on */
+ fpScr->x=0;
+ ScreenIndex(fpScr);
+ } /* end if */
+ else /* no line wrapping */
+ fpScr->x=fpScr->width;
+ current=start=&fpScrLine->text[fpScr->x];
+ acurrent=&fpScrLine->attrib[fpScr->x];
+ ocount=fpScr->x;
+ sx=fpScr->x;
+ } /* end if */
+ if(insert)
+ ScreenInsChar(fpScr,1);
+ *current=c;
+ *acurrent=(char)attrib;
+ if(fpScr->x<fpScr->width) {
+ acurrent++;
+ current++;
+ fpScr->x++;
+ } /* end if */
+ else {
+ if(fpScr->DECAWM) {
+ fpScr->x++;
+ offend=1;
+ } /* end if */
+ else {
+ fpScr->x=fpScr->width;
+ extra=1;
+ } /* end else */
+ } /* end else */
+ if(insert)
+ ScreenInsString(fpScr,fpScr->x-ocount+offend+extra,start); /* actually just decides which RS to use */
+ else
+ ScreenDraw(fpScr,sx,fpScr->y,fpScr->attrib,fpScr->x-ocount+offend+extra,start);
+ LINE_MEM_UNLOCK(hgScrLine);
+} /* end ScreenEmChar() */
+
+void ScreenEm(LPSTR c,int len,HSCREEN hsScr)
+{
+ HSCREENLINE hgScrLine;
+ SCREEN *fpScr;
+ SCREENLINE *fpScrLine;
+ int escflg; /* vt100 escape level */
+ RECT rc;
+ unsigned int ic;
+ char stat[20];
+ int i;
+
+ fpScr=(SCREEN *) GlobalLock(hsScr);
+ if (fpScr==NULL) {
+ OutputDebugString("Screen is hosed.\r\n");
+ return;
+ }
+
+ if (fpScr->screen_bottom != fpScr->buffer_bottom) {
+ ScreenUnscroll(fpScr);
+ InvalidateRect(fpScr->hWnd,NULL,TRUE);
+ SetScrollPos(fpScr->hWnd,SB_VERT,fpScr->numlines,TRUE);
+ }
+
+ ScreenCursorOff(fpScr);
+ escflg=fpScr->escflg;
+
+#ifdef UM
+/* @UM */
+ if(fpScr->localprint && (len>0)) { /* see if printer needs anything */
+ pcount=send_localprint(c,len);
+ len-=pcount;
+ c+=pcount;
+ } /* end if */
+/* @UM */
+#endif
+
+ while(len>0) {
+ while((*c<32) && (escflg==0) && (len>0)) { /* look at first character in the vt100 string, if it is a non-printable ascii code */
+ switch(*c) {
+
+ case 0x1b: /* ESC found (begin vt100 control sequence) */
+ escflg++;
+ break;
+
+ case -1: /* IAC from telnet session */
+ escflg=6;
+ break;
+
+#ifdef CISB
+ case 0x05: /* CTRL-E found (answerback) */
+ bp_ENQ();
+ break;
+
+#endif
+ case 0x07: /* CTRL-G found (bell) */
+ ScreenBell(fpScr);
+ break;
+
+ case 0x08: /* CTRL-H found (backspace) */
+ ScreenBackspace(fpScr);
+ break;
+
+ case 0x09: /* CTRL-I found (tab) */
+ ScreenTab(fpScr); /* Later change for versatile tabbing */
+ break;
+
+ case 0x0a: /* CTRL-J found (line feed) */
+ case 0x0b: /* CTRL-K found (treat as line feed) */
+ case 0x0c: /* CTRL-L found (treat as line feed) */
+ ScreenIndex(fpScr);
+ break;
+ case 0x0d: /* CTRL-M found (carriage feed) */
+ ScreenCarriageFeed(fpScr);
+ break;
+
+#ifdef LATER
+ case 0x0e: /* CTRL-N found (invoke Graphics (G1) character set) */
+ if(fpScr->G1)
+ fpScr->attrib=VSgraph(fpScr->attrib);
+ else
+ fpScr->attrib=VSnotgraph(fpScr->attrib);
+ fpScr->charset=1;
+ break;
+
+ case 0x0f: /* CTRL-O found (invoke 'normal' (G0) character set) */
+ if(fpScr->G0)
+ fpScr->attrib=VSgraph(fpScr->attrib);
+ else
+ fpScr->attrib=VSnotgraph(fpScr->attrib);
+ fpScr->charset=0;
+ break;
+#endif
+#ifdef CISB
+ case 0x10: /* CTRL-P found (undocumented in vt100) */
+ bp_DLE( c, len);
+ len=0;
+ break;
+#endif
+
+#ifdef NOT_USED
+ case 0x11: /* CTRL-Q found (XON) (unused presently) */
+ case 0x13: /* CTRL-S found (XOFF) (unused presently) */
+ case 0x18: /* CTRL-X found (CAN) (unused presently) */
+ case 0x1a: /* CTRL-Z found (SUB) (unused presently) */
+ break;
+#endif
+ } /* end switch */
+ c++; /* advance to the next character in the string */
+ len--; /* decrement the counter */
+ } /* end while */
+
+ if(escflg==0) { /* check for normal character to print */
+ while((len>0) && (*c>=32)) { /* print out printable ascii chars, if we haven't found an ESCAPE char */
+ int sx;
+ int insert,
+ ocount,
+ attrib,
+ extra,
+ offend;
+ char *acurrent, /* pointer to the attributes for characters drawn */
+ *current, /* pointer to the place to put characters */
+ *start;
+
+ hgScrLine=GetScreenLineFromY(fpScr,fpScr->y);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL) return;
+
+ current=start=&fpScrLine->text[fpScr->x];
+ acurrent=&fpScrLine->attrib[fpScr->x];
+ attrib=fpScr->attrib;
+ insert=fpScr->IRM; /* boolean */
+ ocount=fpScr->x;
+ offend=0;
+ extra=0;
+ sx=fpScr->x;
+ if(fpScr->x>fpScr->width) {
+ if(fpScr->DECAWM) { /* check for line wrapping on */
+ fpScr->x=0;
+ ScreenIndex(fpScr);
+ } /* end if */
+ else /* no line wrapping */
+ fpScr->x=fpScr->width;
+ current=start=&fpScrLine->text[fpScr->x];
+ acurrent=&fpScrLine->attrib[fpScr->x];
+ ocount=fpScr->x;
+ sx=fpScr->x;
+ } /* end if */
+ while((len>0) && (*c>=32) && (offend==0)) {
+ if(insert)
+ ScreenInsChar(fpScr,1);
+ *current=*c;
+ *acurrent=(char)attrib;
+ c++;
+ len--;
+ if(fpScr->x<fpScr->width) {
+ acurrent++;
+ current++;
+ fpScr->x++;
+ } /* end if */
+ else {
+ if(fpScr->DECAWM) {
+ fpScr->x++;
+ offend=1;
+ } /* end if */
+ else {
+ fpScr->x=fpScr->width;
+ extra=1;
+ } /* end else */
+ } /* end else */
+ } /* end while */
+ if (insert)
+ ScreenInsString(fpScr,fpScr->x-ocount+offend+extra,start); /* actually just decides which RS to use */
+ else
+ ScreenDraw(fpScr,sx,fpScr->y,fpScr->attrib,fpScr->x-ocount+offend+extra,start);
+ } /* end while */
+ } /* end if */
+
+ while((len>0) && (escflg==1)) { /* ESC character was found */
+ switch(*c) {
+ case 0x08: /* CTRL-H found (backspace) */
+ ScreenBackspace(fpScr);
+ break;
+
+ case '[': /* mostly cursor movement options, and DEC private stuff following */
+// OutputDebugString("[");
+ ScreenApClear(fpScr);
+ escflg=2;
+ break;
+
+ case '#': /* various screen adjustments */
+// OutputDebugString("#");
+ escflg=3;
+ break;
+
+ case '(': /* G0 character set options */
+// OutputDebugString("(");
+ escflg=4;
+ break;
+
+ case ')': /* G1 character set options */
+// OutputDebugString(")");
+ escflg=5;
+ break;
+
+ case '>': /* keypad numeric mode (DECKPAM) */
+// OutputDebugString(">");
+ fpScr->DECPAM=0;
+ escflg=0;
+ break;
+
+ case '=': /* keypad application mode (DECKPAM) */
+// OutputDebugString("=");
+ fpScr->DECPAM=1;
+ escflg=0;
+ break;
+
+ case '7': /* save cursor (DECSC) */
+// OutputDebugString("7!");
+ ScreenSaveCursor(fpScr);
+ escflg=0;
+ break;
+
+ case '8': /* restore cursor (DECRC) */
+// OutputDebugString("8!");
+ ScreenRestoreCursor(fpScr);
+ escflg=0;
+ break;
+#ifdef LATER
+ case 'c': /* reset to initial state (RIS) */
+ ScreenReset(fpScr);
+ escflg=0;
+ break;
+#endif
+ case 'D': /* index (move down one line) (IND) */
+ ScreenIndex(fpScr);
+ escflg=0;
+ break;
+
+ case 'E': /* next line (move down one line and to first column) (NEL) */
+// OutputDebugString("E!");
+ fpScr->x=0;
+ ScreenIndex(fpScr);
+ escflg=0;
+ break;
+
+ case 'H': /* horizontal tab set (HTS) */
+// OutputDebugString("H!");
+ fpScr->tabs[fpScr->x]='x';
+ escflg=0;
+ break;
+
+#ifdef CISB
+ case 'I': /* undoumented in vt100 */
+ bp_ESC_I();
+ break;
+
+#endif
+
+ case 'M': /* reverse index (move up one line) (RI) */
+// OutputDebugString("M!");
+ ScreenRevIndex(fpScr);
+ escflg=0;
+ break;
+
+ case 'Z': /* identify terminal (DECID) */
+ OutputDebugString("Screen Send Ident- Not implemented! \r\n");
+// ScreenSendIdent(fpScr);
+
+ escflg=0;
+ break;
+
+ default:
+ ScreenEmChar(fpScr,0x1b); /* put the ESC character into the Screen */
+ ScreenEmChar(fpScr,*c); /* put the next character into the Screen */
+ escflg=0;
+ break;
+
+ } /* end switch */
+ c++;
+ len--;
+ } /* end while */
+ while((escflg==2) && (len>0)) { /* '[' handling */
+ switch(*c) {
+ case 0x08: /* backspace */
+ ScreenBackspace(fpScr);
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': /* numeric parameters */
+ if(fpScr->parms[fpScr->parmptr]<0)
+ fpScr->parms[fpScr->parmptr]=0;
+ fpScr->parms[fpScr->parmptr]*=10;
+ fpScr->parms[fpScr->parmptr]+=*c-'0';
+ break;
+
+ case '?': /* vt100 mode change */
+ fpScr->parms[fpScr->parmptr++]=(-2);
+ break;
+
+ case ';': /* parameter divider */
+ fpScr->parmptr++;
+ break;
+
+ case 'A': /* cursor up (CUU) */
+// OutputDebugString("A");
+ rc.left=((fpScr->x)*(fpScr->cxChar));
+ rc.right=(((fpScr->x)+1)*(fpScr->cxChar));
+ rc.top=((fpScr->cyChar)*(fpScr->y));
+ rc.bottom=((fpScr->cyChar)*((fpScr->y)+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+// OutputDebugString("[2A]");
+ if(fpScr->parms[0]<1)
+ fpScr->y--;
+ else
+ fpScr->y-=fpScr->parms[0];
+ if(fpScr->y<fpScr->top)
+ fpScr->y=fpScr->top;
+ ScreenRange(fpScr);
+ escflg=0;
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+ break;
+
+ case 'B': /* cursor down (CUD) */
+// OutputDebugString("B");
+ rc.left=((fpScr->x)*(fpScr->cxChar));
+ rc.right=(((fpScr->x)+1)*(fpScr->cxChar));
+ rc.top=((fpScr->cyChar)*(fpScr->y));
+ rc.bottom=((fpScr->cyChar)*((fpScr->y)+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+// OutputDebugString("[2B]");
+ if(fpScr->parms[0]<1)
+ fpScr->y++;
+ else
+ fpScr->y+=fpScr->parms[0];
+ if(fpScr->y>fpScr->bottom)
+ fpScr->y=fpScr->bottom;
+ ScreenRange(fpScr);
+ escflg=0;
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+ break;
+
+ case 'C': /* cursor forward (right) (CUF) */
+// OutputDebugString("C");
+ rc.left=((fpScr->x)*(fpScr->cxChar));
+ rc.right=(((fpScr->x)+1)*(fpScr->cxChar));
+ rc.top=((fpScr->cyChar)*(fpScr->y));
+ rc.bottom=((fpScr->cyChar)*((fpScr->y)+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+// OutputDebugString("[2C]");
+ if(fpScr->parms[0]<1)
+ fpScr->x++;
+ else
+ fpScr->x+=fpScr->parms[0];
+ ScreenRange(fpScr);
+ if(fpScr->x>fpScr->width)
+ fpScr->x=fpScr->width;
+ escflg=0;
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+ break;
+
+ case 'D': /* cursor backward (left) (CUB) */
+// OutputDebugString("D");
+ rc.left=((fpScr->x)*(fpScr->cxChar));
+ rc.right=(((fpScr->x)+1)*(fpScr->cxChar));
+ rc.top=((fpScr->cyChar)*(fpScr->y));
+ rc.bottom=((fpScr->cyChar)*((fpScr->y)+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+// OutputDebugString("[2D]");
+ if(fpScr->parms[0]<1)
+ fpScr->x--;
+ else
+ fpScr->x-=fpScr->parms[0];
+ ScreenRange(fpScr);
+ escflg=0;
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+ break;
+
+ case 'f': /* horizontal & vertical position (HVP) */
+ case 'H': /* cursor position (CUP) */
+// OutputDebugString("fH");
+ rc.left=((fpScr->x)*(fpScr->cxChar));
+ rc.right=(((fpScr->x)+1)*(fpScr->cxChar));
+ rc.top=((fpScr->cyChar)*(fpScr->y));
+ rc.bottom=((fpScr->cyChar)*((fpScr->y)+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+// OutputDebugString("[2H]");
+ fpScr->x=fpScr->parms[1]-1;
+ fpScr->y=fpScr->parms[0]-1;
+ ScreenRange(fpScr); /* make certain the cursor position is valid */
+ escflg=0;
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+ break;
+
+ case 'J': /* erase in display (ED) */
+// OutputDebugString("J");
+ switch(fpScr->parms[0]) {
+ case -1:
+ case 0: /* erase from active position to end of screen */
+ ScreenEraseToEndOfScreen(fpScr);
+ break;
+ case 1: /* erase from start of screen to active position */
+ OutputDebugString("[Screen Erase to Position- Not Implemented!]\r\n");
+// ScreenEraseToPosition(fpScr);
+ break;
+
+ case 2: /* erase whole screen */
+// OutputDebugString("2");
+ ScreenEraseScreen(fpScr);
+ break;
+
+ default:
+ break;
+ } /* end switch */
+ escflg=0;
+ break;
+
+ case 'K': /* erase in line (EL) */
+// OutputDebugString("K");
+ switch(fpScr->parms[0]) {
+ case -1:
+ case 0: /* erase to end of line */
+// OutputDebugString("0");
+ ScreenEraseToEOL(fpScr);
+ break;
+
+ case 1: /* erase to beginning of line */
+// OutputDebugString("1");
+ ScreenEraseToBOL(fpScr);
+ break;
+
+ case 2: /* erase whole line */
+// OutputDebugString("2");
+ ScreenEraseLine(fpScr,-1);
+ break;
+
+ default:
+ break;
+ } /* end switch */
+ escflg=0;
+ break;
+
+ case 'L': /* insert n lines preceding current line (IL) */
+// OutputDebugString("L");
+ if(fpScr->parms[0]<1)
+ fpScr->parms[0]=1;
+ ScreenInsLines(fpScr,fpScr->parms[0],-1);
+ escflg=0;
+ break;
+
+ case 'M': /* delete n lines from current position downward (DL) */
+// OutputDebugString("M");
+ if(fpScr->parms[0]<1)
+ fpScr->parms[0]=1;
+ ScreenDelLines(fpScr,fpScr->parms[0],-1);
+ escflg=0;
+ break;
+
+ case 'P': /* delete n chars from cursor to the left (DCH) */
+// OutputDebugString("P");
+ if(fpScr->parms[0]<1)
+ fpScr->parms[0]=1;
+ ScreenDelChars(fpScr,fpScr->parms[0]);
+ escflg=0;
+ break;
+
+#ifdef NOT_NEEDED
+ case 'R': /* receive cursor position status from host */
+ break;
+#endif
+#ifdef LATER
+ case 'c': /* device attributes (DA) */
+ ScreenSendIdent();
+ escflg=0;
+ break;
+#endif
+ case 'g': /* tabulation clear (TBC) */
+// OutputDebugString("g");
+ if(fpScr->parms[0]==3) /* clear all tabs */
+ ScreenTabClear(fpScr);
+ else
+ if(fpScr->parms[0]<=0) /* clear tab stop at active position */
+ fpScr->tabs[fpScr->x]=' ';
+ escflg=0;
+ break;
+
+ case 'h': /* set mode (SM) */
+// OutputDebugString("h");
+// ScreenSetOption(fpScr,1);
+ escflg=0;
+ break;
+
+
+ case 'i': /* toggle printer */
+// if(fpScr->parms[fpScr->parmptr]==5)
+// fpScr->localprint=1;
+// else if(fpScr->parms[fpScr->parmptr]==4)
+// fpScr->localprint=0;
+ escflg=0;
+ break;
+
+ case 'l': /* reset mode (RM) */
+// OutputDebugString("l");
+// ScreenSetOption(fpScr,0);
+ escflg=0;
+ break;
+
+ case 'm': /* select graphics rendition (SGR) */
+// OutputDebugString("m");
+ {
+ int temp=0;
+
+ while(temp<=fpScr->parmptr) {
+ if(fpScr->parms[temp]<1)
+ fpScr->attrib&=128;
+ else
+ fpScr->attrib|=(1<<(fpScr->parms[temp]-1));
+ temp++;
+ } /* end while */
+ } /* end case */
+ escflg=0;
+ break;
+
+ case 'n': /* device status report (DSR) */
+ switch(fpScr->parms[0]) {
+#ifdef NOT_SUPPORTED
+ case 0: /* response from vt100; ready, no malfunctions */
+ case 3: /* response from vt100; malfunction, retry */
+#endif
+ case 5: /* send status */
+ case 6: /* send active position */
+ wsprintf(stat, "\033[%d;%dR", fpScr->y, fpScr->x);
+ for (i = 0; stat[i]; i++)
+ SendMessage(fpScr->hwndTel,WM_MYSCREENCHAR,stat[i],hsScr);
+ break;
+ } /* end switch */
+ escflg=0;
+ break;
+
+ case 'q': /* load LEDs (unsupported) (DECLL) */
+ escflg=0;
+ break;
+
+ case 'r': /* set top & bottom margins (DECSTBM) */
+ if(fpScr->parms[0]<0)
+ fpScr->top=0;
+ else
+ fpScr->top=fpScr->parms[0]-1;
+ if(fpScr->parms[1]<0)
+ fpScr->bottom=fpScr->height-1;
+ else
+ fpScr->bottom=fpScr->parms[1]-1;
+ if(fpScr->top<0)
+ fpScr->top=0;
+ if(fpScr->top>fpScr->height-1)
+ fpScr->top=fpScr->height-1;
+ if(fpScr->bottom<1)
+ fpScr->bottom=fpScr->height;
+ if(fpScr->bottom>=fpScr->height)
+ fpScr->bottom=fpScr->height-1;
+ if(fpScr->top>=fpScr->bottom) { /* check for valid scrolling region */
+ if(fpScr->bottom>=1) /* assume the bottom value has precedence, unless it is as the top of the screen */
+ fpScr->top=fpScr->bottom-1;
+ else /* totally psychotic case, bottom of screen set to the very top line, move the bottom to below the top */
+ fpScr->bottom=fpScr->top+1;
+ } /* end if */
+ fpScr->x=0;
+ fpScr->y=0;
+#ifdef NOT_SUPPORTED
+ if (fpScr->DECORG)
+ fpScr->y=fpScr->top; /* origin mode relative */
+#endif
+ escflg=0;
+ break;
+
+#ifdef NOT_SUPPORTED
+ case 'x': /* request/report terminal parameters (DECREQTPARM/DECREPTPARM) */
+ case 'y': /* invoke confidence test (DECTST) */
+ break;
+#endif
+ default: /* Dag blasted strays... */
+ escflg=0;
+ break;
+
+ } /* end switch */
+ c++;
+ len--;
+
+#ifdef NOT
+/* @UM */
+ if(fpScr->localprint && (len>0)) { /* see if printer needs anything */
+ pcount=send_localprint(c,len);
+ len-=pcount;
+ c+=pcount;
+ } /* end if */
+/* @UM */
+#endif
+ } /* end while */
+ while((escflg==3) && (len>0)) { /* # Handling */
+ switch(*c) {
+ case 0x08: /* backspace */
+ ScreenBackspace(fpScr);
+ break;
+
+#ifdef NOT_SUPPORTED
+ case '3': /* top half of double line (DECDHL) */
+ case '4': /* bottom half of double line (DECDHL) */
+ case '5': /* single width line (DECSWL) */
+ case '6': /* double width line (DECDWL) */
+ break;
+#endif
+ case '8': /* screen alignment display (DECALN) */
+ ScreenAlign(fpScr);
+// OutputDebugString("8");
+ escflg=0;
+ break;
+ default:
+ escflg=0;
+ break;
+
+ } /* end switch */
+ c++;
+ len--;
+ } /* end while */
+ while((escflg==4) && (len>0)) { /* ( Handling (GO character set) */
+ switch(*c) {
+ case 0x08: /* backspace */
+ ScreenBackspace(fpScr);
+ break;
+
+#ifdef LATER
+ case 'A': /* united kingdom character set (unsupported) */
+ case 'B': /* ASCII character set */
+ case '1': /* choose standard graphics (same as ASCII) */
+ fpScr->G0=0;
+ if(!fpScr->charset)
+ fpScr->attrib=ScreenNotGraph(fpScr->attrib);
+ escflg=0;
+ break;
+
+ case '0': /* choose special graphics set */
+ case '2': /* alternate character set (special graphics) */
+ fpScr->G0=1;
+ if(!fpScr->charset)
+ fpScr->attrib=ScreenGraph(fpScr->attrib);
+ escflg=0;
+ break;
+#endif
+ default:
+ escflg=0;
+ break;
+ } /* end switch */
+ c++;
+ len--;
+ } /* end while */
+ while((escflg==5) && (len>0)) { /* ) Handling (G1 handling) */
+ switch(*c) {
+ case 0x08: /* backspace */
+ ScreenBackspace(fpScr);
+ break;
+
+#ifdef LATER
+ case 'A': /* united kingdom character set (unsupported) */
+ case 'B': /* ASCII character set */
+ case '1': /* choose standard graphics (same as ASCII) */
+ fpScr->G1=0;
+ if(fpScr->charset)
+ fpScr->attrib=ScreenNotGraph(fpScr->attrib);
+ escflg=0;
+ break;
+
+ case '0': /* choose special graphics set */
+ case '2': /* alternate character set (special graphics) */
+ fpScr->G1=1;
+ if(fpScr->charset)
+ fpScr->attrib=ScreenGraph(fpScr->attrib);
+ escflg=0;
+ break;
+#endif
+ default:
+ escflg=0;
+ break;
+ } /* end switch */
+ c++;
+ len--;
+ } /* end while */
+
+ while((escflg>=6) && (escflg<=10) && (len>0)) { /* Handling IAC */
+ ic = (unsigned char) *c;
+ switch (escflg) {
+
+ case 6: /* Handling IAC xx */
+ if (ic == 255) /* if IAC */
+ escflg=0;
+ else if (ic == 250) /* if SB */
+ escflg=7;
+ else
+ escflg=9;
+ break;
+
+ case 7: /* Handling IAC SB xx */
+ if (ic == 255) /* if IAC */
+ escflg=8;
+ break;
+
+ case 8: /* Handling IAC SB IAC xx */
+ if (ic == 255) /* if IAC IAC */
+ escflg=7;
+ else if (ic == 240) /* if IAC SE */
+ escflg=0;
+ break;
+
+ case 9: /* IAC xx xx */
+ escflg=0;
+ break;
+ }
+ c++; /* advance to the next character in the string */
+ len--; /* decrement the counter */
+ }
+
+ if((escflg>2 && escflg<6) && (len>0)) {
+ escflg=0;
+ c++;
+ len--;
+ } /* end if */
+ } /* end while */
+ fpScr->escflg=escflg;
+ ScreenCursorOn(fpScr);
+ GlobalUnlock(hsScr);
+} /* end ScreenEm() */
--- /dev/null
+#include <windows.h>
+#include <commdlg.h>
+#include "screen.h"
+#include "ini.h"
+
+LOGFONT lf;
+HFONT hFont;
+char szStyle[LF_FACESIZE];
+
+void ProcessFontChange(HWND hWnd) {
+ static DWORD dwFontColor; /* Color of font if one has been selected */
+ CHOOSEFONT cf;
+ HDC hDC;
+ SCREEN *fpScr;
+ HGLOBAL hgScr;
+ TEXTMETRIC tm;
+ char buf[16];
+
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+
+ cf.lStructSize = sizeof(cf);
+ cf.hwndOwner = hWnd;
+ cf.lpLogFont = (LPLOGFONT)&(fpScr->lf);
+ cf.lpszStyle = szStyle;
+ cf.Flags = CF_INITTOLOGFONTSTRUCT; // | CF_USESTYLE;
+ cf.Flags |= CF_SCREENFONTS;
+// cf.Flags |= CF_ANSIONLY;
+ cf.Flags |= CF_FORCEFONTEXIST;
+ cf.Flags |= CF_FIXEDPITCHONLY;
+ cf.Flags |= CF_NOSIMULATIONS;
+
+ if (ChooseFont(&cf)) {
+ if (fpScr->ghSelectedFont) DeleteObject(fpScr->ghSelectedFont);
+
+ fpScr->ghSelectedFont = CreateFontIndirect((LPLOGFONT)&(fpScr->lf));
+ fpScr->lf.lfUnderline=TRUE;
+ fpScr->ghSelectedULFont= CreateFontIndirect((LPLOGFONT)&(fpScr->lf));
+ fpScr->lf.lfUnderline=FALSE;
+ hDC=GetDC(hWnd);
+ SelectObject(hDC,fpScr->ghSelectedFont);
+ GetTextMetrics(hDC,(LPTEXTMETRIC)&tm);
+
+ fpScr->cxChar = tm.tmAveCharWidth;
+ fpScr->cyChar = tm.tmHeight+ tm.tmExternalLeading;
+ ReleaseDC(hWnd,hDC);
+ SetWindowPos(hWnd,NULL,0,0, fpScr->cxChar * fpScr->width +
+ FRAME_WIDTH, fpScr->cyChar * fpScr->height +
+ FRAME_HEIGHT, SWP_NOMOVE|SWP_NOZORDER);
+
+ dwFontColor=RGB(255, 255, 255);
+ InvalidateRect(hWnd, NULL, TRUE);
+ }
+
+ WritePrivateProfileString(INI_FONT,"FaceName",fpScr->lf.lfFaceName,TELNET_INI);
+ wsprintf(buf,"%d",(int)fpScr->lf.lfHeight);
+ WritePrivateProfileString(INI_FONT,"Height",buf,TELNET_INI);
+ wsprintf(buf,"%d",(int)fpScr->lf.lfWidth);
+ WritePrivateProfileString(INI_FONT,"Width",buf,TELNET_INI);
+ wsprintf(buf,"%d",(int)fpScr->lf.lfEscapement);
+ WritePrivateProfileString(INI_FONT,"Escapement",buf,TELNET_INI);
+ wsprintf(buf,"%d",(int)fpScr->lf.lfCharSet);
+ WritePrivateProfileString(INI_FONT,"CharSet",buf,TELNET_INI);
+ wsprintf(buf,"%d",(int)fpScr->lf.lfPitchAndFamily);
+ WritePrivateProfileString(INI_FONT,"PitchAndFamily",buf,TELNET_INI);
+
+ GlobalUnlock(hgScr);
+ return;
+}
+
+void NEAR InitializeStruct(WORD wCommDlgType, LPSTR lpStruct, HWND hWnd)
+{
+ LPCHOOSEFONT lpFontChunk;
+
+ switch (wCommDlgType)
+ {
+ case IDC_FONT:
+
+ lpFontChunk = (LPCHOOSEFONT)lpStruct;
+
+ lpFontChunk->lStructSize = sizeof(CHOOSEFONT);
+ lpFontChunk->hwndOwner = hWnd;
+
+//The hDC field will be initialized when we return--this avoids passing
+//the hDC in or getting the DC twice.
+//The LOGFONT field will also be initialized when we get back.
+// lpFontChunk->hDC = hDC;
+// lpFontChunk->lpLogFont = &lf;
+
+ lpFontChunk->Flags = CF_SCREENFONTS | CF_FIXEDPITCHONLY |
+ CF_INITTOLOGFONTSTRUCT | CF_APPLY;
+ lpFontChunk->rgbColors = RGB(0, 0, 255);
+ lpFontChunk->lCustData = 0L;
+ lpFontChunk->lpfnHook = NULL;
+ lpFontChunk->lpTemplateName = (LPSTR)NULL;
+ lpFontChunk->hInstance = (HANDLE)NULL;
+ lpFontChunk->lpszStyle = (LPSTR)NULL;
+ lpFontChunk->nFontType = SCREEN_FONTTYPE;
+ lpFontChunk->nSizeMin = 0;
+ lpFontChunk->nSizeMax = 0;
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+LPSTR NEAR AllocAndLockMem(HANDLE *hChunk, WORD wSize) {
+ LPSTR lpChunk;
+
+ *hChunk = GlobalAlloc(GMEM_FIXED, wSize);
+ if (*hChunk) {
+ lpChunk = GlobalLock(*hChunk);
+ if (!lpChunk) {
+ GlobalFree(*hChunk);
+ ReportError(IDC_LOCKFAIL);
+ lpChunk=NULL;
+ }
+ } else {
+ ReportError(IDC_ALLOCFAIL);
+ lpChunk=NULL;
+ }
+ return(lpChunk);
+}
+
+
--- /dev/null
+/* Defines INI file vocabulary */
+#define TELNET_INI "kerberos.ini"
+
+ #define INI_TELNET "Telnet"
+ #define INI_FONT "Font"
+ #define INI_WIDTH "Width"
+ #define INI_HEIGHT "Height"
+ #define INI_POSITION "Position"
+ #define INI_BACKSPACE "Backspace"
+ #define INI_BACKSPACE_BS "BS"
+ #define INI_BACKSPACE_DEL "DEL"
+
+ #define INI_HOSTS "Telnet Hosts"
+ #define INI_HOST "Host"
+ #define INI_HOST_BS "BS"
+ #define INI_HOST_DEL "DEL"
--- /dev/null
+#include <windows.h>
+#include <string.h>
+#include "screen.h"
+#define ScreenClearAttrib 0
+
+HSCREENLINE GetScreenLineFromY(SCREEN *fpScr,int y)
+{
+ HSCREENLINE hgScrLine,hgScrLineTmp;
+ SCREENLINE *fpScrLine;
+ int idx;
+
+ hgScrLine=fpScr->screen_top;
+ for (idx=0; idx<fpScr->height; idx++) {
+ if (idx==y) return(hgScrLine);
+ fpScrLine=LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL) return (NULL);
+ hgScrLineTmp=fpScrLine->next;
+ LINE_MEM_UNLOCK(hgScrLine);
+ hgScrLine=hgScrLineTmp;
+ }
+ return(NULL);
+}
+
+HSCREENLINE ScreenClearLine(SCREEN *fpScr,HSCREENLINE hgScrLine)
+{
+ SCREENLINE *fpScrLine;
+
+ fpScrLine=LINE_MEM_LOCK(hgScrLine);
+ memset(fpScrLine->attrib, ScreenClearAttrib, fpScr->width);
+ memset(fpScrLine->text, ' ', fpScr->width);
+ LINE_MEM_UNLOCK(hgScrLine);
+ return(hgScrLine);
+}
+
+void ScreenUnscroll(SCREEN *fpScr)
+{
+ int idx;
+ HSCREENLINE hgScrLine,hgScrLineTmp;
+ SCREENLINE *fpScrLine;
+
+ if (fpScr->screen_bottom == fpScr->buffer_bottom)
+ return;
+
+ fpScr->screen_bottom=fpScr->buffer_bottom;
+ hgScrLine=fpScr->screen_bottom;
+ for (idx = 1; idx < fpScr->height; idx++) {
+ fpScrLine=LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL)
+ return;
+ hgScrLineTmp=fpScrLine->prev;
+ LINE_MEM_UNLOCK(hgScrLine);
+ hgScrLine=hgScrLineTmp;
+ }
+ fpScr->screen_top=hgScrLine;
+}
+
+void ScreenCursorOn(SCREEN *fpScr)
+{
+ int y;
+ int nlines;
+
+ if (fpScr->screen_bottom != fpScr->buffer_bottom)
+ nlines = fpScr->numlines - GetScrollPos(fpScr->hWnd, SB_VERT);
+ else
+ nlines = 0;
+
+ y = fpScr->y + nlines;
+ SetCaretPos(fpScr->x * fpScr->cxChar, (y+1) * fpScr->cyChar);
+ ShowCaret(fpScr->hWnd);
+}
+
+void ScreenCursorOff(SCREEN *fpScr)
+{
+ HideCaret(fpScr->hWnd);
+}
+
+void ScreenELO(SCREEN *fpScr,int s)
+{
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ RECT rc;
+
+/* fpScrrapnow(&i,&j); */
+ if(s<0)
+ s=fpScr->y;
+
+ hgScrLine=GetScreenLineFromY(fpScr,s);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ memset(fpScrLine->attrib, ScreenClearAttrib, fpScr->width);
+ memset(fpScrLine->text, ' ', fpScr->width);
+ LINE_MEM_UNLOCK(hgScrLine);
+ rc.left=0;
+ rc.right=(fpScr->width*fpScr->cxChar);
+ rc.top=(fpScr->cyChar*s);
+ rc.bottom=(fpScr->cyChar*(s+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+}
+
+void ScreenEraseScreen(SCREEN *fpScr)
+{
+ int i;
+ int x1=0,y1=0;
+ int x2=fpScr->width,y2=fpScr->height;
+ int n=(-1);
+
+ for(i=0; i<fpScr->height; i++)
+ ScreenELO(fpScr,i);
+ InvalidateRect(fpScr->hWnd,NULL,TRUE);
+ UpdateWindow(fpScr->hWnd);
+}
+
+void ScreenTabClear(SCREEN *fpScr)
+{
+ int x=0;
+
+ while(x<=fpScr->width) {
+ fpScr->tabs[x]=' ';
+ x++;
+ } /* end while */
+}
+
+void ScreenTabInit(SCREEN *fpScr)
+{
+ int x=0;
+
+ ScreenTabClear(fpScr);
+
+ while(x<=fpScr->width) {
+ fpScr->tabs[x]='x';
+ x+=8;
+ } /* end while */
+ fpScr->tabs[fpScr->width]='x';
+}
+
+void ScreenReset(SCREEN *fpScr)
+{
+ fpScr->top=0;
+ fpScr->bottom=fpScr->height-1;
+ fpScr->parmptr=0;
+ fpScr->escflg=0;
+ fpScr->DECAWM=1;
+ fpScr->DECCKM=0;
+ fpScr->DECPAM=0;
+/* fpScr->DECORG=0; */
+/* fpScr->Pattrib=-1; */
+ fpScr->IRM=0;
+ fpScr->attrib=0;
+ fpScr->x=0;
+ fpScr->y=0;
+// fpScr->charset=0;
+ ScreenEraseScreen(fpScr);
+ ScreenTabInit(fpScr);
+// set_vtwrap(fpScrn,fpScr->DECAWM); /* QAK - 7/27/90: added because resetting the virtual screen's wrapping flag doesn't reset telnet window's wrapping */
+}
+
+
+void ScreenListMove(HSCREENLINE hTD,HSCREENLINE hBD,HSCREENLINE hTI,HSCREENLINE hBI)
+{
+ HSCREENLINE hTmpLine;
+ SCREENLINE *TD,*BD,*TI,*BI,*tmpLine;
+
+// OutputDebugString("ScreenListMove");
+ TD= (SCREENLINE *)GlobalLock(hTD);
+ BD= (SCREENLINE *)GlobalLock(hBD);
+ TI= (SCREENLINE *)GlobalLock(hTI);
+ BI= (SCREENLINE *)GlobalLock(hBI);
+
+ if(TD->prev!=NULL) {
+ hTmpLine=TD->prev;
+ tmpLine=(SCREENLINE *)GlobalLock(hTmpLine);
+ tmpLine->next=BD->next; /* Maintain circularity */
+ GlobalUnlock(hTmpLine);
+ }
+ if(BD->next!=NULL) {
+ hTmpLine=BD->next;
+ tmpLine=(SCREENLINE *)GlobalLock(hTmpLine);
+ tmpLine->prev=TD->prev;
+ GlobalUnlock(hTmpLine);
+ }
+ TD->prev=hTI; /* Place the node in its new home */
+ BD->next=hBI;
+ if(TI!=NULL)
+ TI->next=hTD; /* Ditto prev->prev */
+ if(BI!=NULL)
+ BI->prev=hBD;
+
+ GlobalUnlock(hTD);
+ GlobalUnlock(hBD);
+ GlobalUnlock(hTI);
+ GlobalUnlock(hBI);
+}
+
+
+void ScreenDelLines(SCREEN *fpScr, int n, int s)
+{
+ HSCREENLINE hBI,hTI,hTD,hBD;
+ SCREENLINE *TI;
+ SCREENLINE *BD;
+ HSCREENLINE hLine;
+ SCREENLINE *fpLine;
+ HSCREENLINE hTemp;
+ int idx;
+ RECT rc;
+ HDC hDC;
+
+ if (s < 0)
+ s = fpScr->y;
+
+ if (s + n - 1 > fpScr->bottom)
+ n = fpScr->bottom - s + 1;
+
+ hTD = GetScreenLineFromY(fpScr, s);
+ hBD = GetScreenLineFromY(fpScr, s + n - 1);
+ hTI = GetScreenLineFromY(fpScr, fpScr->bottom);
+ TI= LINE_MEM_LOCK(hTI);
+ hBI = TI->next;
+ LINE_MEM_UNLOCK(hTI);
+
+ /*
+ Adjust the top of the screen and buffer if they will move.
+ */
+ if (hTD == fpScr->screen_top) {
+ BD = LINE_MEM_LOCK(hBD);
+ if (fpScr->screen_top == fpScr->buffer_top)
+ fpScr->buffer_top = BD->next;
+ fpScr->screen_top = BD->next;
+ LINE_MEM_UNLOCK(hBD);
+ }
+
+ /*
+ Adjust the bottom of the screen and buffer if they will move.
+ */
+ if (hTI == fpScr->screen_bottom) {
+ if (fpScr->screen_bottom == fpScr->buffer_bottom)
+ fpScr->buffer_bottom = hBD;
+ fpScr->screen_bottom = hBD;
+ }
+
+ if (hTI != hBD)
+ ScreenListMove(hTD, hBD, hTI, hBI);
+
+ /*
+ Clear the lines moved from the deleted area to the
+ bottom of the scrolling area.
+ */
+ hLine = hTI;
+
+ for (idx = 0; idx < n; idx++) {
+ fpLine = LINE_MEM_LOCK(hLine);
+ hTemp = fpLine->next;
+ LINE_MEM_UNLOCK(hLine);
+ hLine = hTemp;
+ ScreenClearLine(fpScr, hLine);
+ }
+
+// CheckScreen(fpScr);
+
+ /*
+ Scroll the affected area on the screen.
+ */
+ rc.left = 0;
+ rc.right = fpScr->width * fpScr->cxChar;
+ rc.top = s * fpScr->cyChar;
+ rc.bottom = (fpScr->bottom + 1) * fpScr->cyChar;
+
+ hDC = GetDC(fpScr->hWnd);
+
+ ScrollDC(hDC, 0, -fpScr->cyChar * n, &rc, &rc, NULL, NULL);
+
+ PatBlt(hDC, 0, (fpScr->bottom - n + 1) * fpScr->cyChar,
+ fpScr->width * fpScr->cxChar, n * fpScr->cyChar, WHITENESS);
+
+ ReleaseDC(fpScr->hWnd, hDC);
+
+} /* ScreenDelLines */
+
+
+void ScreenInsertLine(SCREEN *fpScr, int s)
+{
+ ScreenInsLines(fpScr, 1, s);
+} /* ScreenInsertLine */
+
+
+void ScreenInsLines(SCREEN *fpScr, int n, int s)
+{
+ HSCREENLINE hLine;
+ HSCREENLINE hTemp;
+ HSCREENLINE hTI;
+ HSCREENLINE hBI;
+ HSCREENLINE hTD;
+ HSCREENLINE hBD;
+ SCREENLINE *fpLine;
+ SCREENLINE *BI;
+ SCREENLINE *TD;
+ int idx;
+ RECT rc;
+ HDC hDC;
+
+// wsprintf(strTmp, "ScreenInsLine (n=%d s=%d)", n, s);
+// OutputDebugString(strTmp);
+
+ if (s < 0)
+ s = fpScr->y;
+
+ if (s + n - 1 > fpScr->bottom)
+ n = fpScr->bottom - s + 1;
+
+ /*
+ Determine the top and bottom of the insert area. Also determine
+ the top and bottom of the area to be deleted and moved to the
+ insert area.
+ */
+ hBI = GetScreenLineFromY(fpScr, s);
+ BI = LINE_MEM_LOCK(hBI);
+ hTI = BI->prev;
+ hTD = GetScreenLineFromY(fpScr, fpScr->bottom - n + 1);
+ hBD = GetScreenLineFromY(fpScr, fpScr->bottom);
+
+ /*
+ Adjust the top of the screen and buffer if they will move.
+ */
+ if (hBI == fpScr->screen_top) {
+ if (fpScr->screen_top == fpScr->buffer_top)
+ fpScr->buffer_top = hTD;
+ fpScr->screen_top = hTD;
+ }
+
+ /*
+ Adjust the bottom of the screen and buffer if they will move.
+ */
+ if (hBD == fpScr->screen_bottom) {
+ TD = LINE_MEM_LOCK(hTD);
+ if (fpScr->screen_bottom == fpScr->buffer_bottom)
+ fpScr->buffer_bottom = TD->prev;
+ fpScr->screen_bottom = TD->prev;
+ LINE_MEM_UNLOCK(hTD);
+ }
+
+ /*
+ Move lines from the bottom of the scrolling region to the insert area.
+ */
+ if (hTD != hBI)
+ ScreenListMove(hTD,hBD,hTI,hBI);
+
+ /*
+ Clear the inserted lines
+ */
+ hLine = GetScreenLineFromY(fpScr, s);
+
+ for (idx = 0; idx < n; idx++) {
+ ScreenClearLine(fpScr, hLine);
+ fpLine = LINE_MEM_LOCK(hLine);
+ hTemp = fpLine->next;
+ LINE_MEM_UNLOCK(hLine);
+ hLine = hTemp;
+ }
+
+// CheckScreen(fpScr);
+
+ /*
+ Scroll the affected area on the screen.
+ */
+ rc.left = 0;
+ rc.right = fpScr->width * fpScr->cxChar;
+ rc.top = s * fpScr->cyChar;
+ rc.bottom = (fpScr->bottom + 1) * fpScr->cyChar;
+
+ hDC = GetDC(fpScr->hWnd);
+
+ ScrollDC(hDC, 0, fpScr->cyChar * n, &rc, &rc, NULL, NULL);
+
+ PatBlt(hDC, 0, s * fpScr->cyChar,
+ fpScr->width * fpScr->cxChar, n * fpScr->cyChar, WHITENESS);
+
+ ReleaseDC(fpScr->hWnd, hDC);
+
+} /* ScreenInsLines */
+
+
+void ScreenIndex(SCREEN * fpScr)
+{
+ if(fpScr->y>=fpScr->bottom)
+ ScreenScroll(fpScr);
+ else
+ fpScr->y++;
+}
+
+void ScreenWrapNow(SCREEN *fpScr,int *xp,int *yp)
+{
+ if(fpScr->x > fpScr->width) {
+ fpScr->x=0;
+ ScreenIndex(fpScr);
+ } /* end if */
+ *xp=fpScr->x;
+ *yp=fpScr->y;
+}
+
+void ScreenEraseToEOL(SCREEN *fpScr)
+{
+ int x1=fpScr->x,y1=fpScr->y;
+ int x2=fpScr->width,y2=fpScr->y;
+ int n=(-1);
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ RECT rc;
+
+ ScreenWrapNow(fpScr,&x1,&y1);
+ y2=y1;
+// wsprintf(strTmp,"[EraseEOL:%d]",y2);
+// OutputDebugString(strTmp);
+ hgScrLine=GetScreenLineFromY(fpScr,y2);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ memset(&fpScrLine->attrib[x1], ScreenClearAttrib, fpScr->width-x1+1);
+ memset(&fpScrLine->text[x1], ' ', fpScr->width-x1+1);
+ LINE_MEM_UNLOCK(hgScrLine);
+ rc.left=x1*fpScr->cxChar;
+ rc.right=(fpScr->width*fpScr->cxChar);
+ rc.top=(fpScr->cyChar*y1);
+ rc.bottom=(fpScr->cyChar*(y1+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+ UpdateWindow(fpScr->hWnd);
+}
+
+void ScreenDelChars(SCREEN *fpScr, int n)
+{
+ int x = fpScr->x;
+ int y = fpScr->y;
+ int width;
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ RECT rc;
+
+ hgScrLine = GetScreenLineFromY(fpScr, y);
+ fpScrLine = LINE_MEM_LOCK(hgScrLine);
+
+ width = fpScr->width - x - n;
+
+ if (width > 0) {
+ memmove(&fpScrLine->attrib[x], &fpScrLine->attrib[x + n], width);
+ memmove(&fpScrLine->text[x], &fpScrLine->text[x + n], width);
+ }
+
+ memset(&fpScrLine->attrib[fpScr->width - n], ScreenClearAttrib, n);
+ memset(&fpScrLine->text[fpScr->width - n], ' ', n);
+
+ LINE_MEM_UNLOCK(hgScrLine);
+
+ rc.left = x * fpScr->cxChar;
+ rc.right = fpScr->width * fpScr->cxChar;
+ rc.top = fpScr->cyChar * y;
+ rc.bottom = fpScr->cyChar * (y + 1);
+
+ InvalidateRect(fpScr->hWnd, &rc, TRUE);
+
+ UpdateWindow(fpScr->hWnd);
+}
+
+void ScreenRevIndex(SCREEN *fpScr)
+{
+ HSCREENLINE hgScrLine,hTopLine;
+
+ hgScrLine=GetScreenLineFromY(fpScr,fpScr->y);
+ hTopLine=GetScreenLineFromY(fpScr,fpScr->top);
+
+ if(hgScrLine==hTopLine)
+ ScreenInsertLine(fpScr,fpScr->y);
+ else
+ fpScr->y--;
+}
+
+void ScreenEraseToBOL(SCREEN *fpScr)
+{
+ int x1=0,y1=fpScr->y;
+ int x2=fpScr->x,y2=fpScr->y;
+ int n=(-1);
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+
+ hgScrLine=GetScreenLineFromY(fpScr,fpScr->y);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+
+ ScreenWrapNow(fpScr,&x2,&y1);
+ y2=y1;
+ memset(fpScrLine->attrib, ScreenClearAttrib, x2);
+ memset(fpScrLine->text, ' ', x2);
+ LINE_MEM_UNLOCK(hgScrLine);
+}
+
+void ScreenEraseLine(SCREEN *fpScr,int s)
+{
+ int x1=0,y1=s;
+ int x2=fpScr->width,y2=s;
+ int n=(-1);
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ RECT rc;
+
+ if(s<0) {
+ ScreenWrapNow(fpScr,&x1,&y1);
+ s=y2=y1;
+ x1=0;
+ } /* end if */
+
+ hgScrLine=GetScreenLineFromY(fpScr,y1);
+ fpScrLine=LINE_MEM_LOCK(hgScrLine);
+ memset(fpScrLine->attrib, ScreenClearAttrib, fpScr->width);
+ memset(fpScrLine->text, ' ', fpScr->width);
+ LINE_MEM_UNLOCK(hgScrLine);
+ rc.left=0;
+ rc.right=(fpScr->width*fpScr->cxChar);
+ rc.top=(fpScr->cyChar*y1);
+ rc.bottom=(fpScr->cyChar*(y1+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+}
+
+void ScreenEraseToEndOfScreen(SCREEN *fpScr)
+{
+ register int i;
+ int x1=0,y1=fpScr->y+1;
+ int x2=fpScr->width,y2=fpScr->height;
+ int n=(-1);
+
+ ScreenWrapNow(fpScr,&x1,&y1);
+ y1++;
+ x1=0;
+ i=y1;
+ ScreenEraseToEOL(fpScr);
+ while(i<fpScr->height) {
+ ScreenELO(fpScr,i);
+ ScreenEraseLine(fpScr,i);
+ i++;
+ } /* end while */
+}
+
+void ScreenRange(SCREEN *fpScr) /* check and resolve range errors on x and y */
+{
+ int wrap=0;
+
+ if(fpScr->DECAWM)
+ wrap=1;
+ if(fpScr->x<0)
+ fpScr->x=0;
+ if(fpScr->x>(fpScr->width+wrap))
+ fpScr->x=fpScr->width+wrap;
+ if(fpScr->y<0)
+ fpScr->y=0;
+ if(fpScr->y>=fpScr->height)
+ fpScr->y=fpScr->height-1;
+}
+
+void ScreenAlign(SCREEN *fpScr) /* vt100 alignment, fill screen with 'E's */
+{
+ char *tt;
+ register int i,j;
+ HSCREENLINE hgScrLine,hgScrLineTmp;
+ SCREENLINE *fpScrLine;
+
+ hgScrLine=GetScreenLineFromY(fpScr,fpScr->top);
+ ScreenEraseScreen(fpScr); /* erase the screen */
+
+ for(j=0; j<fpScr->height; j++) {
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ tt=&fpScrLine->text[0];
+ for(i=0; i<=fpScr->width; i++)
+ *tt++='E';
+ hgScrLineTmp=fpScrLine->next;
+ LINE_MEM_UNLOCK(hgScrLine);
+ hgScrLine=hgScrLineTmp;
+
+ } /* end for */
+ LINE_MEM_UNLOCK(hgScrLine);
+}
+
+/* reset all the ANSI parameters back to the default state */
+void ScreenApClear(SCREEN *fpScr)
+{
+ for(fpScr->parmptr=5; fpScr->parmptr>=0; fpScr->parmptr--)
+ fpScr->parms[fpScr->parmptr]=-1;
+ fpScr->parmptr=0;
+}
+
+void ScreenSetOption(SCREEN *fpScr,int toggle) {
+// int WindWidth=(fpScr->width - 1);
+
+ switch(fpScr->parms[0]) {
+ case -2:
+ switch(fpScr->parms[1]) {
+ case 1: /* set/reset cursor key mode */
+ fpScr->DECCKM=toggle;
+ break;
+
+#ifdef NOT_SUPPORTED
+ case 2: /* set/reset ANSI/vt52 mode */
+ break;
+#endif
+
+ case 3: /* set/reset column mode */
+ fpScr->x=fpScr->y=0; /* Clear the screen, mama! */
+ ScreenEraseScreen(fpScr);
+ #if 0 /* removed for variable screen size */
+ if(toggle) /* 132 column mode */
+ fpScr->width=fpScr->allwidth;
+ else
+ fpScr->width=79;
+ #endif
+ break;
+
+#ifdef NOT_SUPPORTED
+ case 4: /* set/reset scrolling mode */
+ case 5: /* set/reset screen mode */
+ case 6: /* set/rest origin mode */
+ fpScr->DECORG = toggle;
+ break;
+#endif
+
+ case 7: /* set/reset wrap mode */
+ fpScr->DECAWM=toggle;
+// set_vtwrap(fpScrn,fpScr->DECAWM); /* QAK - 7/27/90: added because resetting the virtual screen's wrapping flag doesn't reset telnet window's wrapping */
+ break;
+
+#ifdef NOT_SUPPORTED
+ case 8: /* set/reset autorepeat mode */
+ case 9: /* set/reset interlace mode */
+ break;
+#endif
+
+ default:
+ break;
+ } /* end switch */
+ break;
+
+ case 4:
+ fpScr->IRM=toggle;
+ break;
+
+ default:
+ break;
+
+ } /* end switch */
+}
+
+#ifdef NOT_SUPPORTED
+void ScreenTab(SCREEN *fpScr)
+{
+ if(fpScr->x>=fpScr->width)
+ fpScr->x=fpScr->width;
+ fpScr->x++;
+ while((fpScr->tabs[fpScr->x] != 'x') && (fpScr->x < fpScr->width))
+ fpScr->x++;
+}
+#endif
+
+int ScreenInsChar(SCREEN *fpScr,int x)
+{
+ int i;
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ RECT rc;
+
+// ScreenWrapNow(&i,&j); /* JEM- Why is this here? comment out for now */
+
+// OutputDebugString("OOPS-InsChar!");
+ hgScrLine=GetScreenLineFromY(fpScr,fpScr->y);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL) return (-1);
+
+ for(i=fpScr->width-x; i>=fpScr->x; i--) {
+ fpScrLine->text[x+i]=fpScrLine->text[i];
+ fpScrLine->attrib[x+i]=fpScrLine->attrib[i];
+ } /* end for */
+
+ memset(&fpScrLine->attrib[fpScr->x], ScreenClearAttrib, x);
+ memset(&fpScrLine->text[fpScr->x], ' ', x);
+
+ for(i=fpScr->x; i<fpScr->x+x; i++) {
+ fpScrLine->text[i]=' ';
+ fpScrLine->attrib[i]=ScreenClearAttrib;
+ } /* end for */
+ LINE_MEM_UNLOCK(hgScrLine);
+ rc.left= (fpScr->cxChar*x);
+ rc.right= ((fpScr->cxChar*x)+(fpScr->cxChar*(x+fpScr->x)));
+ rc.top=(fpScr->cyChar*((fpScr->y)-1));
+ rc.bottom=(fpScr->cyChar*(fpScr->y));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+}
+
+void ScreenInsString(SCREEN *fpScr,int len,char *start)
+{
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ int idx;
+ RECT rc;
+
+ if(fpScr->VSIDC) return; /* Call RSinsstring which does nothing? */
+
+ hgScrLine=GetScreenLineFromY(fpScr,fpScr->y);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL) return;
+
+ for(idx=fpScr->x; idx<fpScr->x+len; idx++) {
+ fpScrLine->text[idx]=start[idx];
+ fpScrLine->attrib[idx]=fpScr->attrib;
+ } /* end for */
+ LINE_MEM_UNLOCK(hgScrLine);
+ rc.left= (fpScr->cxChar*fpScr->x);
+ rc.right= ((fpScr->cxChar*fpScr->x)+(fpScr->cxChar*(fpScr->x+len)));
+ rc.top=(fpScr->cyChar*(fpScr->y));
+ rc.bottom=(fpScr->cyChar*(fpScr->y+1));
+
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+}
+
+void ScreenSaveCursor(SCREEN *fpScr)
+{
+ fpScr->Px=fpScr->x;
+ fpScr->Py=fpScr->y;
+ fpScr->Pattrib=fpScr->attrib;
+}
+
+void ScreenRestoreCursor(SCREEN *fpScr)
+{
+ fpScr->x=fpScr->Px;
+ fpScr->y=fpScr->Py;
+ ScreenRange(fpScr);
+}
+
+void ScreenDraw(SCREEN *fpScr,int x,int y,int a,int len,char *c)
+{
+ int idx;
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ RECT rc;
+
+ hgScrLine=GetScreenLineFromY(fpScr,y);
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL) {
+ OutputDebugString("fpScrLine==NULL");
+ return;
+ }
+
+ for(idx=x; idx<(x+len); idx++) {
+ fpScrLine->text[idx]=c[idx-x];
+ fpScrLine->attrib[idx-x]=a;
+ }
+ LINE_MEM_UNLOCK(hgScrLine);
+
+ rc.left= (fpScr->cxChar*x);
+ rc.right= (fpScr->cxChar*(x+len));
+ rc.top=(fpScr->cyChar*(fpScr->y));
+ rc.bottom=(fpScr->cyChar*((fpScr->y)+1));
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+ SendMessage(fpScr->hWnd,WM_PAINT,NULL,NULL);
+}
+
+#ifdef _DEBUG
+
+ BOOL CheckScreen(SCREEN *fpScr)
+ {
+ HSCREENLINE hLine;
+ HSCREENLINE hLinePrev;
+ SCREENLINE *fpLine;
+ int nscreen = 0;
+ int nbuffer = 0;
+ int topline = 0;
+ char buf[512];
+ BOOL bBottom;
+ BOOL bOK;
+
+ hLine = fpScr->buffer_top;
+
+ if (hLine == NULL) {
+ OutputDebugString("CheckScreen: buffer_top invalid");
+ MessageBox(NULL, "buffer_top invalid", "CheckScreen", MB_OK);
+ return(FALSE);
+ }
+
+ bBottom = FALSE;
+ while (TRUE) {
+ hLinePrev = hLine;
+ if (nscreen > 0 || hLine == fpScr->screen_top)
+ if (!bBottom)
+ nscreen++;
+ nbuffer++;
+ if (hLine == fpScr->screen_top)
+ topline = nbuffer - 1;
+ if (hLine == fpScr->screen_bottom)
+ bBottom = TRUE;
+ fpLine = LINE_MEM_LOCK(hLine);
+ hLine = fpLine->next;
+ LINE_MEM_UNLOCK(hLine);
+ if (hLine == NULL)
+ break;
+ fpLine = LINE_MEM_LOCK(hLine);
+ if (fpLine->prev != hLinePrev) {
+ wsprintf(buf,
+ "Previous ptr of line %d does not match next ptr of line %d",
+ nbuffer, nbuffer - 1);
+ OutputDebugString(buf);
+ MessageBox(NULL, buf, "CheckScreen", MB_OK);
+ }
+ LINE_MEM_UNLOCK(hLine);
+ }
+
+ if (hLinePrev == fpScr->buffer_bottom && nscreen == fpScr->height)
+ bOK = TRUE;
+ else {
+ OutputDebugString("CheckScreen: Invalid number of lines on screen");
+ bOK = FALSE;
+ }
+
+ wsprintf(buf, \
+ "screen.width = %d\n"
+ "screen.height = %d\n"
+ "screen.maxlines = %d\n"
+ "screen.numlines = %d\n"
+ "screen.x = %d\n"
+ "screen.y = %d\n"
+ "screen.top = %d\n"
+ "screen.bottom = %d\n"
+ "Actual top line = %d\n"
+ "Actual buffer lines = %d\n"
+ "Actual screen lines = %d\n"
+ "Bottom of buffer is %s",
+ fpScr->width, fpScr->height, fpScr->maxlines, fpScr->numlines,
+ fpScr->x, fpScr->y, fpScr->top, fpScr->bottom,
+ topline, nbuffer, nscreen,
+ (hLinePrev == fpScr->buffer_bottom) ? "valid" : "invalid");
+
+ MessageBox(NULL, buf, "CheckScreen", MB_OK);
+
+ return(bOK);
+ }
+
+#endif
--- /dev/null
+/*+*************************************************************************
+**
+** K5stream
+**
+** Emulates the kstream package in Kerberos 4
+**
+***************************************************************************/
+
+#include <stdio.h>
+#include <io.h>
+#include <malloc.h>
+#include "telnet.h"
+#include "k5stream.h"
+#include "auth.h"
+
+int
+kstream_destroy (kstream ks) {
+ if (ks != NULL) {
+ auth_destroy (ks); /* Destroy authorizing */
+
+ closesocket (ks->fd); /* Close the socket??? */
+ free (ks);
+ }
+ return 0;
+}
+
+void
+kstream_set_buffer_mode (kstream ks, int mode) {
+}
+
+
+kstream
+kstream_create_from_fd (int fd,
+ const struct kstream_crypt_ctl_block __far *ctl,
+ kstream_ptr data)
+{
+ kstream ks;
+ int n;
+
+ ks = malloc (sizeof(kstream *));
+ if (ks == NULL)
+ return NULL;
+
+ ks->fd = fd;
+
+ n = auth_init (ks, data); /* Initialize authorizing */
+ if (n) {
+ free (ks);
+ return NULL;
+ }
+
+ return ks;
+}
+
+int
+kstream_write (kstream ks, void __far *p_data, size_t p_len) {
+ int n;
+
+ n = send (ks->fd, p_data, p_len, 0); /* Write the data */
+
+ return n; /* higher layer does retries */
+}
+
--- /dev/null
+/* Header file for encrypted-stream library.
+ * Written by Ken Raeburn (Raeburn@Cygnus.COM).
+ * Copyright (C) 1991, 1992, 1994 by Cygnus Support.
+ *
+ * Permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation.
+ * Cygnus Support makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#ifndef K5STREAM_H
+#define K5STREAM_H
+
+typedef struct { /* Object we pass around */
+ int fd; /* Open socket descriptor */
+} *kstream;
+
+typedef void *kstream_ptr; /* Data send on the kstream */
+
+struct kstream_data_block {
+ kstream_ptr ptr;
+ size_t length;
+};
+
+struct kstream_crypt_ctl_block {
+ int (INTERFACE *encrypt) (
+ struct kstream_data_block *, /* output -- written */
+ struct kstream_data_block *, /* input */
+ kstream str);
+ int (INTERFACE *decrypt) (
+ struct kstream_data_block *, /* output -- written */
+ struct kstream_data_block *, /* input */
+ kstream str);
+ int (INTERFACE *init) (kstream str, kstream_ptr data);
+ void (INTERFACE *destroy) (kstream str);
+};
+
+
+/* Prototypes */
+
+int kstream_destroy (kstream);
+void kstream_set_buffer_mode (kstream, int);
+kstream kstream_create_from_fd (int fd,
+ const struct kstream_crypt_ctl_block __far *ctl,
+ kstream_ptr data);
+int kstream_write (kstream, void __far *, size_t);
+
+#endif /* K5STREAM_H */
--- /dev/null
+# makefile: Constructs the kerborized telnet client
+# Works for both k4 and k5 releases.
+#
+NAME = telnet
+OBJS = telnet.obj negotiat.obj auth.obj edit.obj emul.obj \
+ font.obj intern.obj screen.obj
+
+##### Options
+DEBUG = 1
+!IF ! defined(KVERSION)
+KVERSION = 5
+!endif
+KRB = KRB$(KVERSION)
+
+!if $(KVERSION) == 4
+BUILDTOP = ..
+LIBDIR = $(BUILDTOP)\lib\krb
+KLIB = $(LIBDIR)\kerberos.lib
+WLIB = $(LIBDIR)\winsock.lib
+INCLUDES = /I$(BUILDTOP)\include
+XOBJS =
+!endif
+
+!if $(KVERSION) == 5
+BUILDTOP =..\..
+LIBDIR = $(BUILDTOP)\lib
+KLIB = $(LIBDIR)\libkrb5.lib
+WLIB = $(LIBDIR)\winsock.lib
+INCLUDES = /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 \
+ /I$(BUILDTOP)\lib\crypto\des
+XOBJS = k5stream.obj
+!endif
+
+##### C Compiler
+CC = cl
+CFLAGS_RELEASE = /nologo /W3 /AL /GAs /Gx /O1 /DNDEBUG
+CFLAGS_DEBUG = /nologo /W3 /AL /GAs /Gx /G2 /Zi /Od /D_DEBUG /Fd"TELNET.PDB"
+!if $(DEBUG)
+CFLAGS = $(CFLAGS_DEBUG) $(INCLUDES) /D$(KRB)=1
+!else
+CFLAGS = $(CFLAGS_RELEASE) $(INCLUDES) /D$(KRB)=1
+!endif
+
+##### RC Compiler
+RC = rc
+RFLAGS_RELEASE = /nologo
+RFLAGS_DEBUG = /nologo /D_DEBUG
+!if $(DEBUG)
+RFLAGS = $(RFLAGS_DEBUG) $(INCLUDES)
+!else
+RFLAGS = $(RFLAGS_RELEASE) $(INCLUDES)
+!endif
+
+##### Linker
+LINK = link
+LIBS = $(KLIB) $(WLIB)
+SYSLIBS = libw llibcew commdlg
+!if $(DEBUG)
+LFLAGS = /co /nol /nod /packc:61440 /stack:32768 /align:16 /onerror:noexe
+!else
+LFLAGS = /nol /nod /packc:61440 /stack:32768 /align:16 /onerror:noexe
+!endif
+
+all: makefile $(NAME).exe
+
+$(NAME).exe: $*.def $*.res $(OBJS) $(XOBJS) $(LIBS)
+ $(LINK) $(LFLAGS) $(OBJS) $(XOBJS), $@, $*.map, \
+ $(LIBS) $(SYSLIBS), $*.def
+ $(RC) $(RFLAGS) /k $*.res $@
+
+install:
+ copy telnet.exe ..\floppy
+
+clean:
+ if exist *.obj del *.obj
+ if exist *.exe del *.exe
+ if exist *.res del *.res
+ if exist *.map del *.map
+ if exist *.pdb del *.pdb
+ if exist *.err del *.err
+ if exist ..\floppy\telnet.exe del ..\floppy\telnet.exe
+
+telnet.obj: telnet.h dialog.h screen.h struct.h wt-proto.h ini.h
+
+negotiat.obj: telnet.h dialog.h screen.h struct.h wt-proto.h ini.h
+
+auth.obj: telopts.h telnet.h dialog.h screen.h struct.h wt-proto.h ini.h
+
+edit.obj: screen.h
+
+emul.obj: screen.h
+
+font.obj: screen.h ini.h
+
+intern.obj: screen.h
+
+screen.obj: screen.h ini.h
+
+telnet.res: screen.h dialog.h telnet.dlg ncsa.ico terminal.ico
+
+!if $(KVERSION) == 5
+k5stream.c: k5stream.h auth.h
+!endif
+
--- /dev/null
+/*
+* negotiat.c
+*
+* Telnet option negotiation functions
+*
+
+/*
+* Includes
+*/
+
+/* #define USETEK */
+/* #define USERAS */
+
+#if 0 /* define this to print the raw network data to debuging monitor */
+#define NEGOTIATEDEBUG
+#endif
+
+#include <time.h>
+#include "telnet.h"
+#include "telopts.h"
+#include "auth.h"
+
+unsigned char parsedat[256];
+
+/* Local functions */
+static void parse_subnegotiat(kstream ks,int end_sub);
+
+/* Local variables */
+static char *telstates[]={
+ "EOF",
+ "Suspend Process",
+ "Abort Process",
+ "Unknown (239)",
+ "Subnegotiation End",
+ "NOP",
+ "Data Mark",
+ "Break",
+ "Interrupt Process",
+ "Abort Output",
+ "Are You There",
+ "Erase Character",
+ "Erase Line",
+ "Go Ahead",
+ "Subnegotiate",
+ "Will",
+ "Won't",
+ "Do",
+ "Don't"
+};
+
+static char *teloptions[256]={ /* ascii strings for Telnet options */
+ "Binary", /* 0 */
+ "Echo",
+ "Reconnection",
+ "Supress Go Ahead",
+ "Message Size Negotiation",
+ "Status", /* 5 */
+ "Timing Mark",
+ "Remote Controlled Trans and Echo",
+ "Output Line Width",
+ "Output Page Size",
+ "Output Carriage-Return Disposition", /* 10 */
+ "Output Horizontal Tab Stops",
+ "Output Horizontal Tab Disposition",
+ "Output Formfeed Disposition",
+ "Output Vertical Tabstops",
+ "Output Vertical Tab Disposition", /* 15 */
+ "Output Linefeed Disposition",
+ "Extended ASCII",
+ "Logout",
+ "Byte Macro",
+ "Data Entry Terminal", /* 20 */
+ "SUPDUP",
+ "SUPDUP Output",
+ "Send Location",
+ "Terminal Type",
+ "End of Record", /* 25 */
+ "TACACS User Identification",
+ "Output Marking",
+ "Terminal Location Number",
+ "3270 Regime",
+ "X.3 PAD", /* 30 */
+ "Negotiate About Window Size",
+ "Terminal Speed",
+ "Toggle Flow Control",
+ "Linemode",
+ "X Display Location", /* 35 */
+ "Environment",
+ "Authentication",
+ "Data Encryption",
+ "39",
+ "40","41","42","43","44","45","46","47","48","49",
+ "50","51","52","53","54","55","56","57","58","59",
+ "60","61","62","63","64","65","66","67","68","69",
+ "70","71","72","73","74","75","76","77","78","79",
+ "80","81","82","83","84","85","86","87","88","89",
+ "90","91","92","93","94","95","96","97","98","99",
+ "100","101","102","103","104","105","106","107","108","109",
+ "110","111","112","113","114","115","116","117","118","119",
+ "120","121","122","123","124","125","126","127","128","129",
+ "130","131","132","133","134","135","136","137","138","139",
+ "140","141","142","143","144","145","146","147","148","149",
+ "150","151","152","153","154","155","156","157","158","159",
+ "160","161","162","163","164","165","166","167","168","169",
+ "170","171","172","173","174","175","176","177","178","179",
+ "180","181","182","183","184","185","186","187","188","189",
+ "190","191","192","193","194","195","196","197","198","199",
+ "200","201","202","203","204","205","206","207","208","209",
+ "210","211","212","213","214","215","216","217","218","219",
+ "220","221","222","223","224","225","226","227","228","229",
+ "230","231","232","233","234","235","236","237","238","239",
+ "240","241","242","243","244","245","246","247","248","249",
+ "250","251","252","253","254",
+ "Extended Options List" /* 255 */
+};
+
+static char *LMoptions[]={ /* ascii strings for Linemode sub-options */
+ "None", "MODE", "FORWARDMASK", "SLC"
+};
+
+static char *ModeOptions[]={ /* ascii strings for Linemode edit options */
+ "None", "EDIT", "TRAPSIG", "ACK", "SOFT TAB", "LIT ECHO"
+};
+
+static char *SLCoptions[]={ /* ascii strings for Linemode SLC characters */
+ "None", "SYNCH", "BREAK", "IP", "ABORT OUTPUT",
+ "AYT", "EOR", "ABORT", "EOF", "SUSP",
+ "EC", "EL", "EW", "RP", "LNEXT",
+ "XON", "XOFF", "FORW1", "FORW2", "MCL",
+ "MCR", "MCWL", "MCWR", "MCBOL", "MCEOL",
+ "INSRT", "OVER", "ECR", "EWR", "EBOL",
+ "EEOL"
+};
+
+static char *SLCflags[]={ /* ascii strings for Linemode SLC flags */
+ "SLC_NOSUPPORT", "SLC_CANTCHANGE", "SLC_VALUE", "SLC_DEFAULT"
+};
+
+ /* Linemode default character for each function */
+static unsigned char LMdefaults[NUMLMODEOPTIONS+1]={
+ (unsigned char)-1, /* zero isn't used */
+ (unsigned char)-1, /* we don't support SYNCH */
+ 3, /* ^C is default for BRK */
+ 3, /* ^C is default for IP */
+ 15, /* ^O is default for AO */
+ 25, /* ^Y is default for AYT */ /* 5 */
+ (unsigned char)-1, /* we don't support EOR */
+ 3, /* ^C is default for ABORT */
+ 4, /* ^D is default for EOF */
+ 26, /* ^Z is default for SUSP */
+ 8, /* ^H is default for EC */ /* 10 */
+ 21, /* ^U is default for EL */
+ 23, /* ^W is default for EW */
+ 18, /* ^R is default for RP */
+ 22, /* ^V is default for LNEXT */
+ 17, /* ^Q is default for XON */ /* 15 */
+ 19, /* ^S is default for XOFF */
+ 22, /* ^V is default for FORW1 */
+ 5, /* ^E is default for FORW2 */
+ (unsigned char)-1, /* we don't support MCL */
+ (unsigned char)-1, /* we don't support MCR */ /* 20 */
+ (unsigned char)-1, /* we don't support MCWL */
+ (unsigned char)-1, /* we don't support MCWR */
+ (unsigned char)-1, /* we don't support MCBOL */
+ (unsigned char)-1, /* we don't support MCEOL */
+ (unsigned char)-1, /* we don't support INSRT */ /* 25 */
+ (unsigned char)-1, /* we don't support OVER */
+ (unsigned char)-1, /* we don't support ECR */
+ (unsigned char)-1, /* we don't support EWR */
+ (unsigned char)-1, /* we don't support EBOL */
+ (unsigned char)-1 /* we don't support EEOL */ /* 30 */
+};
+
+
+/*+********************************************************************
+* Function : start_negotiation()
+* Purpose : Send the initial negotiations on the network and print
+* the negotitations to the console screen.
+* Parameters :
+* dat - the port number to write to
+* cvs - the console's virtual screen
+* Returns : none
+* Calls : tprintf(), netprintf()
+* Called by : dosessions()
+**********************************************************************/
+void
+start_negotiation(kstream ks)
+{
+ char buf[128];
+
+ /* Send the initial tlnet negotiations */
+ wsprintf(buf,"%c%c%c",IAC,DOTEL,SGA);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+ wsprintf(buf,"%c%c%c",IAC,DOTEL,ECHO);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+ wsprintf(buf,"%c%c%c",IAC,WILLTEL,NAWS);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+
+#ifdef NOT
+ /* check whether we are going to be output mapping */
+ if(tw->mapoutput) {
+ netprintf(tw->pnum,"%c%c%c",IAC,DOTEL,BINARY);
+ /* set the flag indicating we wanted server to start transmitting binary */
+ tw->uwantbinary=1;
+ netprintf(tw->pnum,"%c%c%c",IAC,WILLTEL,BINARY);
+ /* set the flag indicating we want to start transmitting binary */
+ tw->iwantbinary=1;
+ } /* end if */
+#endif
+
+ /* Print to the console what we just did */
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",telstates[DOTEL-LOW_TEL_OPT],
+ teloptions[ECHO]);
+ OutputDebugString(strTmp);
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",telstates[DOTEL-LOW_TEL_OPT],
+ teloptions[SGA]);
+ OutputDebugString(strTmp);
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[NAWS]);
+ OutputDebugString(strTmp);
+
+#ifdef NOT
+ tprintf(cvs,"SEND: %ls %ls\r\n",telstates[DOTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ tprintf(cvs,"SEND: %ls %ls\r\n",telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+#endif
+#endif
+} /* end start_negotiation() */
+
+/*+*******************************************************************
+* parse
+* Do the telnet negotiation parsing.
+*
+* look at the string which has just come in from outside and
+* check for special sequences that we are interested in.
+*
+* Tries to pass through routine strings immediately, waiting for special
+* characters ESC and IAC to change modes.
+*/
+void
+parse (CONNECTION *con,unsigned char *st,int cnt) {
+ static int sub_pos; /* the position we are in the subnegotiation parsing */
+ static int end_sub; /* index of last byte in parsedat in a subnegotiation */
+ unsigned char *mark, *orig;
+ char buf[256];
+ kstream ks;
+
+ ks=con->ks;
+
+#ifdef PRINT_EVERYTHING
+ OutputDebugString("\r\n");
+ for(i=0; i<cnt; i++) {
+ int j;
+
+ for(j=0; (j < 16) && ((i + j) < cnt); j++) {
+ wsprintf(strTmp,"%2.2X ", *(unsigned char *) (st + i + j));
+ OutputDebugString(strTmp);
+ }
+ i+=j-1;
+ OutputDebugString("\r\n");
+ } /* end for */
+ OutputDebugString("\r\n");
+#endif //PRINT_EVERYTHING
+
+ orig=st; /* remember beginning point */
+ mark=st+cnt; /* set to end of input string */
+
+#ifdef HUH
+ netpush(tw->pnum);
+#endif
+
+/*
+* traverse string, looking for any special characters which indicate that
+* we need to change modes.
+*/
+ while(st<mark) {
+ while(con->telstate!=STNORM && st<mark) {
+ switch(con->telstate) {
+ case IACFOUND: /* telnet option negotiation */
+ if(*st==IAC) { /* real data=255 */
+ st++; /* real 255 will get sent */
+ con->telstate=STNORM;
+ break;
+ } /* end if */
+
+ if(*st>239) {
+ con->telstate=*st++; /* by what the option is */
+ break;
+ } /* end if */
+
+#ifdef NEGOTIATEDEBUG
+ wsprintf(buf,"\r\n strange telnet option");
+ OutputDebugString(buf);
+#endif
+ orig=++st;
+ con->telstate=STNORM;
+ break;
+
+ case EL: /* received a telnet erase line command */
+ case EC: /* received a telnet erase character command */
+ case AYT: /* received a telnet Are-You-There command */
+ case AO: /* received a telnet Abort Output command */
+ case IP: /* received a telnet Interrupt Process command */
+ case BREAK: /* received a telnet Break command */
+ case DM: /* received a telnet Data Mark command */
+ case NOP: /* received a telnet No Operation command */
+ case SE: /* received a telnet Subnegotiation End command */
+ case ABORT: /* received a telnet Abort Process command */
+ case SUSP: /* received a telnet Suspend Process command */
+ case TEL_EOF:/* received a telnet EOF command */
+#ifdef NEGOTIATEDEBUG
+ wsprintf(buf,"RECV: %ls\r\n",
+ telstates[con->telstate-LOW_TEL_OPT]);
+ OutputDebugString(buf);
+#endif
+ con->telstate=STNORM;
+ orig=++st;
+ break;
+
+ case GOAHEAD: /* telnet go ahead option*/
+#ifdef NEGOTIATEDEBUG
+ wsprintf(buf,"RECV: %ls\r\n",
+ telstates[con->telstate-LOW_TEL_OPT]);
+ OutputDebugString(buf);
+#endif
+ con->telstate=STNORM;
+ orig=++st;
+ break;
+
+ case DOTEL: /* received a telnet DO negotiation */
+#ifdef NEGOTIATEDEBUG
+ wsprintf(buf,"RECV: %ls %ls\r\n",
+ telstates[con->telstate-LOW_TEL_OPT],teloptions[*st]);
+ OutputDebugString(buf);
+#endif
+ switch(*st) {
+#ifdef NOT
+ case BINARY: /* DO: binary transmission */
+ if(!tw->ibinary) { /* binary */
+ if(!tw->iwantbinary) {
+ netprintf(tw->pnum,"%c%c%c",
+ IAC,WILLTEL,BINARY);
+ if(tw->condebug>0)
+ tprintf(cv,"SEND: %ls %ls\r\n",
+ telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ } /* end if */
+ else
+ tw->iwantbinary=0; /* turn off this now */
+ tw->ibinary=1;
+ } /* end if */
+ else {
+ if(tw->condebug>0)
+ tprintf(cv,"NO REPLY NEEDED: %ls %ls\r\n",
+ telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ } /* end else */
+ break;
+#endif
+
+ case SGA: /* DO: Suppress go-ahead */
+ if(!con->igoahead) { /* suppress go-ahead */
+ wsprintf(buf,"%c%c%c",IAC,WILLTEL,SGA);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",
+ telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[SGA]);
+ OutputDebugString(strTmp);
+ OutputDebugString("igoahead");
+#endif
+ con->igoahead=1;
+ } /* end if */
+ else {
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,
+ "NO REPLY NEEDED: %ls %ls\r\n",
+ telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[SGA]);
+ OutputDebugString(strTmp);
+#endif
+ } /* end else */
+ break;
+
+ case TERMTYPE: /* DO: terminal type negotiation */
+ if(!con->termsent) {
+ con->termsent=TRUE;
+ wsprintf(buf,"%c%c%c",IAC,WILLTEL,TERMTYPE);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",
+ telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[TERMTYPE]);
+ OutputDebugString(strTmp);
+#endif
+ } /* end if */
+ else {
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"NO REPLY NEEDED: %ls %ls\r\n",
+ telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[TERMTYPE]);
+ OutputDebugString(strTmp);
+#endif
+ } /* end else */
+ break;
+
+#ifdef LATER
+ case LINEMODE: /* DO: linemode negotiation */
+ tw->lmflag=1; /* set the linemode flag */
+ netprintf(tw->pnum,"%c%c%c",IAC,WILLTEL,LINEMODE);
+ /*
+ ** Tell the other side to send us
+ ** it's default character set
+ */
+ netprintf(tw->pnum,"%c%c%c%c",
+ IAC,SB,LINEMODE,SLC,0,SLC_DEFAULT,0,IAC,SE);
+ if(tw->condebug>0) {
+ tprintf(cv,"SEND: %ls %ls\r\n",
+ telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[LINEMODE]);
+ tprintf(cv,
+ "SEND: SB LINEMODE SLC 0 SLC_DEFAULT 0 IAC SE\r\n");
+ } /* end if */
+ break;
+#endif
+ case NAWS: /* DO: Negotiate About Window Size */
+ con->bResizeable=TRUE;
+ send_naws(con);
+ break;
+
+ case AUTHENTICATION: /* DO: Authentication requested */
+ wsprintf(buf,"%c%c%c",IAC,WILLTEL,AUTHENTICATION);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",
+ telstates[WILLTEL-LOW_TEL_OPT],
+ teloptions[AUTHENTICATION]);
+ OutputDebugString(strTmp);
+#endif
+ break;
+
+ default: /* DO: */
+ wsprintf(buf,"%c%c%c",IAC,WONTTEL,*st);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",
+ telstates[WONTTEL-LOW_TEL_OPT],teloptions[*st]);
+ OutputDebugString(strTmp);
+#endif
+ break;
+
+ } /* end switch */
+ con->telstate=STNORM;
+ orig=++st;
+ break;
+
+ case DONTTEL: /* Received a telnet DONT option */
+ if (*st==NAWS)
+ con->bResizeable=FALSE;
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"RECV: %ls %ls\r\n",
+ telstates[con->telstate-LOW_TEL_OPT],teloptions[*st]);
+ OutputDebugString(strTmp);
+#endif
+
+#ifdef NOT
+ if((*st)==BINARY) { /* DONT: check for binary neg. */
+ if(tw->ibinary) { /* binary */
+ if(!tw->iwantbinary) {
+ netprintf(tw->pnum,"%c%c%c",IAC,WONTTEL,BINARY);
+ if(tw->condebug>0)
+ tprintf(cv,"SEND: %ls %ls\r\n",
+ telstates[WONTTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ } /* end if */
+ else
+ tw->iwantbinary=0; /* turn off this now */
+ tw->ibinary=0;
+ tw->mapoutput=0; /* turn output mapping off */
+ } /* end if */
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"NO REPLY NEEDED: %ls %ls\r\n",
+ telstates[WONTTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ OutputDebugString(strTmp);
+#endif
+ }
+#endif
+ con->telstate=STNORM;
+ orig=++st;
+ break;
+
+ case WILLTEL: /* received a telnet WILL option */
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"RECV: %ls %ls\r\n",
+ telstates[con->telstate-LOW_TEL_OPT],
+ teloptions[*st]);
+ OutputDebugString(strTmp);
+#endif
+ switch(*st) {
+#ifdef NOT
+ case BINARY: /* WILL: binary */
+ if(!tw->ubinary) { /* binary */
+ if(!tw->uwantbinary) {
+ netprintf(tw->pnum,"%c%c%c",
+ IAC,DOTEL,BINARY);
+ if(tw->condebug>0)
+ tprintf(cv,"SEND: %ls %ls\r\n",
+ telstates[DOTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ } /* end if */
+ else
+ tw->uwantbinary=0; /* turn off this now */
+ tw->ubinary=1;
+ } /* end if */
+ else {
+ if(tw->condebug>0)
+ tprintf(cv,"NO REPLY NEEDED: %ls %ls\r\n",
+ telstates[DOTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ } /* end else */
+ break;
+#endif
+
+ case SGA: /* WILL: suppress go-ahead */
+ if(!con->ugoahead) {
+ con->ugoahead=1;
+ wsprintf(buf,"%c%c%c",IAC,DOTEL,SGA); /* ack */
+ TelnetSend(ks,buf,lstrlen(buf),0);
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",
+ telstates[DOTEL-LOW_TEL_OPT],
+ teloptions[SGA]);
+ OutputDebugString(strTmp);
+#endif
+ } /* end if */
+ break;
+
+ case ECHO: /* WILL: echo */
+ if(!con->echo) {
+ con->echo=1;
+ wsprintf(buf,"%c%c%c",IAC,DOTEL,ECHO); /* ack */
+ TelnetSend(ks,buf,lstrlen(buf),0);
+#ifdef NEGOTIATEDEBUG
+
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",
+ telstates[DOTEL-LOW_TEL_OPT],
+ teloptions[ECHO]);
+ OutputDebugString(strTmp);
+#endif
+ } /* end if */
+ break;
+
+ case TIMING: /* WILL: Timing mark */
+ con->timing=0;
+ break;
+
+ default:
+ wsprintf(buf,"%c%c%c",IAC,DONTTEL,*st);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",
+ telstates[DONTTEL-LOW_TEL_OPT],teloptions[*st]);
+ OutputDebugString(strTmp);
+#endif
+ break;
+ } /* end switch */
+ con->telstate=STNORM;
+ orig=++st;
+ break;
+
+ case WONTTEL: /* Received a telnet WONT option */
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"RECV: %ls %ls\r\n",
+ telstates[con->telstate-LOW_TEL_OPT],teloptions[*st]);
+ OutputDebugString((LPSTR)strTmp);
+#endif
+ con->telstate=STNORM;
+ switch(*st++) { /* which option? */
+#ifdef NOT
+ case BINARY: /* WONT: binary */
+ if(tw->ubinary) { /* binary */
+ if(!tw->uwantbinary) {
+ netprintf(tw->pnum,"%c%c%c",
+ IAC,DONTTEL,BINARY);
+ if(tw->condebug>0)
+ tprintf(cv,"SEND: %ls %ls\r\n",
+ telstates[DONTTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ } /* end if */
+ else
+ tw->uwantbinary=0; /* turn off this now */
+ tw->ubinary=0;
+ tw->mapoutput=0; /* turn output mapping off */
+ } /* end if */
+ else {
+ if(tw->condebug>0)
+ tprintf(cv,"NO REPLY NEEDED: %ls %ls\r\n",
+ telstates[DONTTEL-LOW_TEL_OPT],
+ teloptions[BINARY]);
+ } /* end else */
+ break;
+
+#endif
+ case ECHO: /* WONT: echo */
+ if(con->echo) {
+ con->echo=0;
+ wsprintf(buf,"%c%c%c",IAC,DONTTEL,ECHO);
+ TelnetSend(ks,buf,lstrlen(buf),0);
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SEND: %ls %ls\r\n",
+ telstates[DONTTEL-LOW_TEL_OPT],
+ teloptions[ECHO]);
+ OutputDebugString(strTmp);
+ OutputDebugString("Other side won't echo!");
+#endif
+ } /* end if */
+ break;
+
+ case TIMING: /* WONT: Telnet timing mark option */
+ con->timing=0;
+ break;
+
+ default:
+ break;
+ } /* end switch */
+ orig=st;
+ break;
+
+ case SB: /* telnet sub-options negotiation */
+// OutputDebugString("[SB]");
+ con->telstate=NEGOTIATE;
+ orig=st;
+ end_sub=0;
+ sub_pos=con->substate=0; /* Defined for each */
+#ifdef OLD_WAY
+ break;
+#endif
+
+ case NEGOTIATE:
+// OutputDebugString("[NEG:");
+// OutputDebugString(st);
+ /* until we change sub-negotiation states, accumulate bytes */
+ if(con->substate==0) {
+ if(*st==IAC) { /* check if we found an IAC byte */
+ if(*(st+1)==IAC) { /* skip over double IAC's */
+ st++;
+ parsedat[sub_pos++]=*st++;
+ } /* end if */
+ else {
+ end_sub=sub_pos;
+ con->substate=*st++;
+ } /* end else */
+ } /* end if */
+ else /* otherwise, just stash the byte */
+ parsedat[sub_pos++]=*st++;
+ } /* end if */
+ else {
+ con->substate=*st++;
+ /* check if we've really ended the sub-negotiations */
+ if(con->substate==SE)
+ parse_subnegotiat(ks,end_sub);
+ orig=st;
+ con->telstate=STNORM;
+ } /* end else */
+ break;
+
+ default:
+ con->telstate=STNORM;
+ break;
+ } /* end switch */
+ } /* end while */
+
+/*
+* quick scan of the remaining string, skip chars while they are
+* uninteresting
+*/
+ if(con->telstate==STNORM && st<mark) {
+/*
+* skip along as fast as possible until an interesting character is found
+*/
+ while(st<mark && *st!=27 && *st!=IAC) {
+// if(!tw->ubinary)
+// *st&=127; /* mask off high bit */
+ st++;
+ } /* end while */
+// if(!tw->timing)
+// parsewrite(tw,orig,st-orig);
+ orig=st; /* forget what we have sent already */
+ if(st<mark)
+ switch(*st) {
+ case IAC: /* telnet IAC */
+ con->telstate=IACFOUND;
+ st++;
+ break;
+
+ default:
+#ifdef NEGOTIATEDEBUG
+// wsprintf(buf," strange char>128\r\n");
+// OutputDebugString(buf);
+#endif
+ st++;
+ break;
+ } /* end switch */
+ } /* end if */
+ } /* end while */
+} /* end parse() */
+
+
+/*+********************************************************************
+* Function : parse_subnegotiat()
+* Purpose : Parse the telnet sub-negotiations read into the parsedat
+* array.
+* Parameters :
+* end_sub - index of the character in the 'parsedat' array which
+* is the last byte in a sub-negotiation
+* Returns : none
+* Calls :
+* Called by : parse()
+**********************************************************************/
+static void
+parse_subnegotiat(kstream ks,int end_sub) {
+ char buf[128];
+
+// OutputDebugString("INTO SUBNEGOTIATE");
+ switch(parsedat[0]) {
+ case TERMTYPE:
+// OutputDebugString(":INTO TERMTYPE");
+ if(parsedat[1]==1) {
+/* QAK!!! */ wsprintf(buf,"%c%c%c%cvt100%c%c",IAC,SB,TERMTYPE,0,IAC,SE);
+ TelnetSend(ks,(LPSTR)buf,11,0);
+#ifdef NEGOTIATEDEBUG
+ wsprintf(strTmp,"SB TERMINAL-TYPE SEND\r\n"
+ "SEND: SB TERMINAL-TYPE IS vt100 \r\n len=%d \r\n",
+ lstrlen((LPSTR)buf));
+// OutputDebugString(strTmp);
+#endif
+ }
+ break;
+
+ case AUTHENTICATION:
+ auth_parse(ks, parsedat, end_sub);
+ break;
+ default:
+ break;
+ } /* end switch */
+} /* end parse_subnegotiat() */
+/*+********************************************************************
+* Function : send_naws
+* Purpose : Send a window size sub-negotiation.
+* Parameters :
+* ks - the kstream to send to.
+* Returns : none
+**********************************************************************/
+void
+send_naws(CONNECTION *con) {
+ unsigned char buf[13];
+ int len;
+
+ wsprintf(buf, "%c%c%c", IAC, SB, NAWS);
+ len = 3;
+
+ buf[len++] = HIBYTE(con->width);
+ if (buf[len-1] == IAC) buf[len++] = IAC;
+
+ buf[len++] = LOBYTE(con->width);
+ if (buf[len-1] == IAC) buf[len++] = IAC;
+
+ buf[len++] = HIBYTE(con->height);
+ if (buf[len-1] == IAC) buf[len++] = IAC;
+
+ buf[len++] = LOBYTE(con->height);
+ if (buf[len-1] == IAC) buf[len++] = IAC;
+
+ buf[len++] = IAC;
+ buf[len++] = SE;
+
+ TelnetSend(con->ks, buf, len, 0);
+
+#ifdef NEGOTIATEDEBUG
+/// wsprintf(buf, "SEND: SB NAWS %d %d %d %d IAC SE\r\n",
+/// HIBYTE(con->width), LOBYTE(con->width),
+/// HIBYTE(con->height), LOBYTE(con->height));
+/// OutputDebugString(buf);
+#endif
+} /* send_naws */
--- /dev/null
+#include <windows.h>
+#include <commdlg.h>
+#include <stdlib.h>
+#include <string.h>
+#include "screen.h"
+#include "ini.h"
+
+extern char *cInvertedArray;
+HSCREEN ScreenList;
+HINSTANCE hInst;
+HDC hDC;
+char gszAllocErrorMsg[]="Error Allocating Memory!";
+char gszLockErrorMsg[]="Error Locking Memory!";
+char gszLoadStrFail[]="LoadString failed!";
+
+int bDoubleClick=FALSE;
+extern LOGFONT lf;
+extern HFONT hFont;
+extern int bMouseDown;
+extern int bSelection;
+
+char szScreenClass[]="ScreenWClass";
+char szScreenMenu[]="ScreenMenu";
+
+OFSTRUCT ofFile;
+HFILE fh;
+
+#ifdef WINMEM
+CATCHBUF EndRtn; /* error return buffer (required by WinMem)*/
+#endif
+
+//#define FILE_DEBUG
+
+void ScreenInit(HANDLE hInstance) {
+
+ WNDCLASS wc;
+
+ hInst=hInstance;
+
+// wsprintf(strTmp,"hInst= %d \r\n",hInst);
+// OutputDebugString(strTmp);
+
+ ScreenList=NULL;
+
+ wc.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_GLOBALCLASS; /* Class style(s). */
+ wc.lpfnWndProc = ScreenWndProc; /* Function to retrieve messages for */
+ /* windows of this class. */
+ wc.cbClsExtra = 0; /* No per-class extra data. */
+ wc.cbWndExtra = sizeof(HGLOBAL); /* Only extra data is handle to screen*/
+ wc.hInstance = hInstance; /* Application that owns the class. */
+ wc.hIcon = LoadIcon(hInstance, "TERMINAL");
+ wc.hCursor = LoadCursor(NULL, IDC_IBEAM);
+ wc.hbrBackground = GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = szScreenMenu; /* Name of menu resource in .RC file. */
+ wc.lpszClassName = szScreenClass; /* Name used in call to CreateWindow. */
+
+ /* Register the window class and return success/failure code. */
+ if (!RegisterClass(&wc))
+ MessageBox(NULL,"Couldn't register Class!",NULL,MB_OK);
+}
+
+int GetNewScreen(void) {
+ HGLOBAL ghScr;
+ SCREEN *fpScr, *fpTmp, *fpTmp2;
+ static int id=0;
+
+ if (ScreenList==NULL) {
+ ghScr = GlobalAlloc(GHND,sizeof(SCREEN));
+ if (ghScr==NULL) return -1;
+ fpScr = (SCREEN *)GlobalLock(ghScr);
+ if (fpScr==NULL) return -1;
+ fpScr->next=NULL;
+ fpScr->prev=NULL;
+ GlobalUnlock(ghScr);
+ ScreenList=ghScr;
+ return(id++);
+ }
+ else {
+ ghScr = GlobalAlloc(GHND,sizeof(SCREEN));
+ if (ghScr==NULL) return -1;
+ fpScr = (SCREEN *)GlobalLock(ghScr);
+ if (fpScr==NULL) return -1;
+ fpScr->next=ScreenList;
+ fpTmp = (SCREEN *)GlobalLock(ScreenList);
+ if (fpTmp != NULL) {
+ if (fpTmp->next==NULL) {
+ fpScr->next=ScreenList;
+ fpScr->prev=ScreenList;
+ fpTmp->next=ghScr;
+ fpTmp->prev=ghScr;
+ } else {
+ fpScr->prev=fpTmp->prev;
+ fpTmp2 = (SCREEN *)GlobalLock(fpTmp->prev);
+ if (fpTmp2 != NULL)
+ fpTmp2->next=ghScr;
+ GlobalUnlock(fpTmp->prev);
+ fpTmp->prev=ghScr;
+ }
+ }
+ GlobalUnlock(fpScr->next);
+ GlobalUnlock(ghScr);
+ ScreenList=ghScr;
+ return(id++);
+ }
+}
+
+HSCREENLINE ScreenNewLine(void)
+{
+
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+
+ hgScrLine=LINE_MEM_ALLOC(sizeof(SCREENLINE)+2*MAX_LINE_WIDTH);
+ if (hgScrLine==NULL)
+ return (NULL);
+ fpScrLine=LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL)
+ return (NULL);
+ memset(fpScrLine,0,sizeof(SCREENLINE)+2*MAX_LINE_WIDTH);
+ fpScrLine->text=&fpScrLine->buffer[0];
+ fpScrLine->attrib=&fpScrLine->buffer[MAX_LINE_WIDTH];
+ LINE_MEM_UNLOCK(hgScrLine);
+ return(hgScrLine);
+}
+
+static void MakeWindowTitle(char *host, int width, int height, char *title, int nchars)
+{
+ char buf[128];
+ int hlen;
+
+ hlen = strlen(host);
+
+ title[0] = 0;
+
+ if (hlen + 1 > nchars)
+ return;
+
+ strcpy(title, host);
+
+ wsprintf(buf, " (%dh x %dw)", height, width);
+
+ if ((int) strlen(buf) + hlen + 1 > nchars)
+ return;
+
+ strcat(title, buf);
+}
+
+HSCREEN InitNewScreen(CONFIG *Config) {
+ TEXTMETRIC tm;
+ HMENU hMenu=NULL;
+ SCREEN *scr=NULL;
+ HSCREENLINE hgScrLine;
+ HSCREENLINE hgScrLineLast;
+ SCREENLINE *fpScrLine;
+ SCREENLINE *fpScrLineLast;
+ int id,idx=0;
+ HGLOBAL h;
+ char title[128];
+
+ id=GetNewScreen();
+ if (id == -1) return(0);
+ scr=(SCREEN *) GlobalLock(ScreenList);
+ if (scr==NULL) OutputDebugString("Scr is NULL!\r\n");
+
+ hMenu = LoadMenu(hInst,szScreenMenu);
+ if (hMenu==NULL) OutputDebugString("hMenu is NULL! \r\n");
+
+ scr->title=Config->title;
+ MakeWindowTitle(Config->title,Config->width,Config->height,title,sizeof(title));
+
+ scr->hWnd = CreateWindow((char *)szScreenClass,title,WS_OVERLAPPEDWINDOW|WS_VSCROLL,
+ CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,hMenu,hInst,NULL);
+
+ if (!(scr->hWnd)) {
+ OutputDebugString("Couldn't Create Window!! \r\n");
+ return(0);
+ }
+ scr->hwndTel=Config->hwndTel; /* save HWND of calling window */
+
+ if (Config->backspace) {
+ CheckMenuItem(hMenu,IDM_BACKSPACE,MF_CHECKED);
+ CheckMenuItem(hMenu,IDM_DELETE,MF_UNCHECKED);
+ }
+ else {
+ CheckMenuItem(hMenu,IDM_BACKSPACE,MF_UNCHECKED);
+ CheckMenuItem(hMenu,IDM_DELETE,MF_CHECKED);
+ }
+ SetWindowWord(scr->hWnd,SCREEN_HANDLE,(WORD)ScreenList);
+ hDC = GetDC(scr->hWnd);
+
+ scr->lf.lfPitchAndFamily=FIXED_PITCH;
+ GetPrivateProfileString(INI_FONT,"FaceName","Courier",scr->lf.lfFaceName,
+ LF_FACESIZE,TELNET_INI);
+ scr->lf.lfHeight=(int)GetPrivateProfileInt(INI_FONT,"Height",0,TELNET_INI);
+ scr->lf.lfWidth=(int)GetPrivateProfileInt(INI_FONT,"Width",0,TELNET_INI);
+ scr->lf.lfPitchAndFamily=(BYTE)GetPrivateProfileInt(INI_FONT,"PitchAndFamily",0,TELNET_INI);
+ scr->lf.lfCharSet=(BYTE)GetPrivateProfileInt(INI_FONT,"CharSet",0,TELNET_INI);
+ scr->lf.lfEscapement=(BYTE)GetPrivateProfileInt(INI_FONT,"Escapement",0,TELNET_INI);
+ scr->lf.lfQuality=PROOF_QUALITY;
+ scr->ghSelectedFont = CreateFontIndirect((LPLOGFONT)&(scr->lf));
+
+ SelectObject(hDC,scr->ghSelectedFont);
+
+ GetTextMetrics(hDC,(LPTEXTMETRIC)&tm);
+ scr->cxChar = tm.tmAveCharWidth;
+ scr->cyChar = tm.tmHeight + tm.tmExternalLeading;
+
+ ReleaseDC(scr->hWnd,hDC);
+ scr->width=Config->width;
+ scr->height=Config->height;
+ scr->ID=id;
+ scr->x=0;
+ scr->y=0;
+ scr->Oldx=0;
+ scr->Oldy=0;
+ scr->attrib=0;
+ scr->DECAWM=1;
+ scr->top=0;
+ scr->bottom=scr->height-1;
+ scr->parmptr=0;
+ scr->escflg=0;
+ scr->bAlert=FALSE;
+ scr->numlines=0;
+ scr->maxlines=150;
+
+ h=GlobalAlloc(GHND,scr->width*scr->height);
+ if (h==NULL)
+ return(0);
+ cInvertedArray=GlobalLock(h);
+
+ hgScrLineLast=ScreenNewLine();
+ scr->screen_top=scr->buffer_top=hgScrLineLast;
+ hgScrLine=hgScrLineLast;
+
+ for (idx=0; idx<scr->height-1; idx++) {
+ hgScrLine=ScreenNewLine();
+ fpScrLine=LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine == NULL)
+ return(NULL);
+ fpScrLine->prev=hgScrLineLast;
+ LINE_MEM_UNLOCK(hgScrLine);
+
+ fpScrLineLast=LINE_MEM_LOCK(hgScrLineLast);
+ if (fpScrLineLast == NULL)
+ return(NULL);
+ fpScrLineLast->next=hgScrLine;
+ LINE_MEM_UNLOCK(hgScrLineLast);
+
+ hgScrLineLast=hgScrLine;
+ }
+
+ scr->screen_bottom=scr->buffer_bottom=hgScrLine;
+
+ SetWindowPos(scr->hWnd,NULL,0,0,scr->cxChar * scr->width + FRAME_WIDTH,
+ scr->cyChar * scr->height + FRAME_HEIGHT, SWP_NOMOVE|SWP_NOZORDER);
+
+ CreateCaret(scr->hWnd, NULL, scr->cxChar, 2);
+ SetCaretPos(scr->x*scr->cxChar, (scr->y+1)*scr->cyChar);
+ ShowCaret(scr->hWnd);
+
+ GlobalUnlock(ScreenList);
+ return(ScreenList);
+}
+
+void DeleteTopLine(SCREEN *fpScr) {
+ HSCREENLINE hsTop;
+ SCREENLINE *fpScrLine;
+
+ fpScrLine=(SCREENLINE *) LINE_MEM_LOCK(fpScr->buffer_top);
+ if (fpScrLine==NULL) OutputDebugString("Hosed in DeleteTopLine.\r\n");
+ hsTop=fpScrLine->next;
+ LINE_MEM_FREE(fpScr->buffer_top);
+ fpScr->buffer_top=hsTop;
+ fpScrLine=(SCREENLINE *) LINE_MEM_LOCK(fpScr->buffer_top);
+ if (fpScrLine==NULL) OutputDebugString("Hosed in DeleteTopLine.\r\n");
+ fpScrLine->prev=NULL;
+ LINE_MEM_UNLOCK(fpScr->buffer_top);
+ fpScr->numlines--;
+}
+
+
+static void SetScreenScrollBar(SCREEN *fpScr)
+{
+ if (fpScr->numlines <= 0) {
+ SetScrollRange(fpScr->hWnd, SB_VERT, 0, 100, FALSE);
+ SetScrollPos(fpScr->hWnd, SB_VERT, 0, TRUE);
+ EnableScrollBar(fpScr->hWnd, SB_VERT, ESB_DISABLE_BOTH);
+ }
+ else {
+ SetScrollRange(fpScr->hWnd, SB_VERT, 0, fpScr->numlines, FALSE);
+ SetScrollPos(fpScr->hWnd, SB_VERT, fpScr->numlines, TRUE);
+ EnableScrollBar(fpScr->hWnd, SB_VERT, ESB_ENABLE_BOTH);
+ }
+} /* SetScreenScrollBar */
+
+
+int ScreenScroll(SCREEN *fpScr)
+{
+ HSCREENLINE hgScrLine;
+ HSCREENLINE hScrollTop;
+ HSCREENLINE hScrollBottom;
+ HSCREENLINE hPrev;
+ HSCREENLINE hNext;
+ SCREENLINE *fpScrLine;
+ SCREENLINE *fpPrev;
+ SCREENLINE *fpNext;
+ SCREENLINE *fpScrollTop;
+ SCREENLINE *fpScrollBottom;
+ BOOL bFullScreen = TRUE;
+ HDC hDC;
+ RECT rc;
+
+ Edit_ClearSelection(fpScr);
+
+ hScrollTop = (HSCREENLINE) GetScreenLineFromY(fpScr, fpScr->top);
+
+ hScrollBottom = (HSCREENLINE) GetScreenLineFromY(fpScr, fpScr->bottom);
+
+ if (hScrollTop != fpScr->screen_top) {
+ bFullScreen = FALSE;
+ rc.left = 0;
+ rc.right = fpScr->cxChar * fpScr->width;
+ rc.top = fpScr->cyChar * (fpScr->top);
+ rc.bottom = fpScr->cyChar * (fpScr->bottom+1);
+
+ fpScrollTop = LINE_MEM_LOCK(hScrollTop);
+ hNext = fpScrollTop->next;
+ hPrev = fpScrollTop->prev;
+ LINE_MEM_UNLOCK(hScrollTop);
+
+ fpPrev = LINE_MEM_LOCK(hPrev);
+ fpPrev->next = hNext;
+ fpNext = LINE_MEM_LOCK(hNext);
+ fpNext->prev = hPrev;
+ LINE_MEM_UNLOCK(hPrev);
+ LINE_MEM_UNLOCK(hNext);
+
+ hgScrLine = hScrollTop;
+ ScreenClearLine(fpScr, hgScrLine);
+ }
+ else {
+ fpScr->numlines++;
+ hgScrLine = ScreenNewLine();
+ if (hgScrLine == NULL)
+ return(0);
+ fpScrollTop = LINE_MEM_LOCK(hScrollTop);
+ fpScr->screen_top = fpScrollTop->next;
+ LINE_MEM_UNLOCK(hScrollTop);
+ }
+
+ fpScrLine= LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine == NULL)
+ return(0);
+
+ fpScrollBottom = LINE_MEM_LOCK(hScrollBottom);
+ hNext = fpScrollBottom->next;
+ fpScrollBottom->next = hgScrLine;
+ LINE_MEM_UNLOCK(hScrollBottom);
+ fpScrLine->next = hNext;
+ fpScrLine->prev = hScrollBottom;
+ if (hNext != NULL) {
+ fpNext = LINE_MEM_LOCK(hNext);
+ fpNext->prev = hgScrLine;
+ LINE_MEM_UNLOCK(hNext);
+ }
+
+ LINE_MEM_UNLOCK(hgScrLine);
+
+ if (hScrollBottom != fpScr->screen_bottom) {
+ bFullScreen = FALSE;
+ rc.left = 0;
+ rc.right = fpScr->cxChar * fpScr->width;
+ rc.top = fpScr->cyChar * fpScr->top;
+ rc.bottom = fpScr->cyChar * (fpScr->bottom+1);
+ }
+ else {
+ if (fpScr->screen_bottom == fpScr->buffer_bottom)
+ fpScr->buffer_bottom = hgScrLine;
+ fpScr->screen_bottom = hgScrLine;
+ }
+
+// CheckScreen(fpScr);
+
+ fpScr->y++;
+
+ if (fpScr->y > fpScr->bottom)
+ fpScr->y = fpScr->bottom;
+
+ hDC = GetDC(fpScr->hWnd);
+ if (bFullScreen)
+ ScrollDC(hDC, 0, -fpScr->cyChar, NULL, NULL, NULL, NULL);
+ else
+ ScrollDC(hDC, 0, -fpScr->cyChar, &rc, &rc, NULL, NULL);
+
+ PatBlt(hDC, 0, fpScr->bottom * fpScr->cyChar,
+ fpScr->width * fpScr->cxChar, fpScr->cyChar, WHITENESS);
+
+ ReleaseDC(fpScr->hWnd, hDC);
+
+ if (fpScr->numlines == fpScr->maxlines)
+ DeleteTopLine(fpScr);
+ else
+ SetScreenScrollBar(fpScr);
+
+ return(1);
+}
+
+
+void DrawCursor(SCREEN *fpScr) {
+#ifdef NOT
+ HDC hDC;
+ char ch=95;
+
+ hDC=GetDC(fpScr->hWnd);
+ SelectObject(hDC,fpScr->ghSelectedFont);
+ SetTextColor(hDC,RGB(255,255,255));
+ TextOut(hDC,fpScr->Oldx*fpScr->cxChar,fpScr->Oldy*fpScr->cyChar,&ch,1);
+ fpScr->Oldx=fpScr->x;
+ fpScr->Oldy=fpScr->y;
+ SetTextColor(hDC,RGB(0,0,0));
+ TextOut(hDC,fpScr->x*fpScr->cxChar,fpScr->y*fpScr->cyChar,&ch,1);
+ ReleaseDC(fpScr->hWnd,hDC);
+#endif
+}
+
+int DrawTextScreen(RECT rcInvalid, SCREEN * fpScr, HDC hDC)
+{
+ HSCREENLINE hgScrLine, hgScrLineTmp;
+ SCREENLINE *fpScrLine;
+ int x=0, y=0;
+ int left=0, right=0;
+ int i;
+ int len;
+ char attrib;
+ #define YPOS (y*fpScr->cyChar)
+
+ hgScrLine=fpScr->screen_top;
+// hgScrLine=GetScreenLineFromY(fpScr,0);
+// wsprintf(strTmp,"{DTS: (%d)=%X }",fpScr->top,hgScrLine);
+// OutputDebugString(strTmp);
+
+ for (y = 0; y < fpScr->height; y++) {
+ fpScrLine = LINE_MEM_LOCK(hgScrLine);
+
+ if (!fpScrLine)
+ continue;
+
+ if (YPOS >= rcInvalid.top - fpScr->cyChar &&
+ YPOS <= rcInvalid.bottom + fpScr->cyChar) {
+
+ if (y < 0)
+ y = 0;
+
+ if (y >= fpScr->height)
+ y = fpScr->height - 1;
+
+ left = (rcInvalid.left / fpScr->cxChar) - 1;
+
+ right = (rcInvalid.right / fpScr->cxChar) + 1;
+
+ if (left < 0)
+ left = 0;
+
+ if (right > fpScr->width - 1)
+ right = fpScr->width - 1;
+
+ x = left;
+
+ while (x <= right) {
+ if (!fpScrLine->text[x]) {
+ x++;
+ continue;
+ }
+
+ if (SCR_isrev(fpScrLine->attrib[x])) {
+ SelectObject(hDC, fpScr->ghSelectedFont);
+ SetTextColor(hDC, RGB(255, 255, 255));
+ SetBkColor(hDC, RGB(0, 0, 0));
+ }
+ else if (SCR_isblnk(fpScrLine->attrib[x])) {
+ SelectObject(hDC, fpScr->ghSelectedFont);
+ SetTextColor(hDC, RGB(255, 0, 0));
+ SetBkColor(hDC, RGB(255, 255, 255));
+ }
+ else if (SCR_isundl(fpScrLine->attrib[x])) {
+ SetTextColor(hDC, RGB(255, 0, 0));
+ SetBkColor(hDC, RGB(255, 255, 255));
+ SelectObject(hDC, fpScr->ghSelectedULFont);
+ }
+ else {
+ SelectObject(hDC,fpScr->ghSelectedFont);
+ SetTextColor(hDC,RGB(0, 0, 0));
+ SetBkColor(hDC,RGB(255, 255, 255));
+ }
+
+ len = 1;
+ attrib = fpScrLine->attrib[x];
+ for (i = x + 1; i <= right; i++) {
+ if (fpScrLine->attrib[i] != attrib || !fpScrLine->text[i])
+ break;
+ len++;
+ }
+
+ TextOut(hDC, x*fpScr->cxChar, y*fpScr->cyChar, &fpScrLine->text[x], len);
+ x += len;
+ }
+ }
+ hgScrLineTmp = fpScrLine->next;
+ LINE_MEM_UNLOCK(hgScrLine);
+ hgScrLine = hgScrLineTmp;
+ }
+ return(0);
+}
+
+static BOOL SetInternalScreenSize(SCREEN *fpScr, int width, int height)
+{
+ RECT rc;
+ char *p;
+ HGLOBAL h;
+ int idx;
+ int n;
+ int newlines;
+ HSCREENLINE hgNewLine;
+ SCREENLINE *fpNewLine;
+ HSCREENLINE hgTopLine;
+ SCREENLINE *fpTopLine;
+ HSCREENLINE hgBottomLine;
+ SCREENLINE *fpBottomLine;
+ #if 0
+ int col;
+ int row;
+ int dydestbottom;
+ #endif
+
+ GetClientRect(fpScr->hWnd, &rc);
+
+ width = (rc.right - rc.left) / fpScr->cxChar;
+ height = (rc.bottom - rc.top) / fpScr->cyChar;
+
+ if (fpScr->height == height && fpScr->width == width)
+ return(FALSE);
+
+ fpScr->Oldx = 0;
+ fpScr->Oldy = 0;
+ fpScr->attrib = 0;
+
+ /*
+ Reallocate the inverted array of bytes and copy the values
+ from the old screen to the new screen.
+ */
+ h = GlobalAlloc(GHND, width * height);
+ if (h == NULL)
+ return(0);
+
+ ScreenCursorOff(fpScr);
+
+ p = GlobalLock(h);
+
+ #if 0 /* Copy inversion array to desitination */
+ for (col = 0; col < width; col++) {
+ for (row = 0; row < height; row++) {
+ dydestbottom = height - 1 - row;
+ if (col < fpScr->width && dydestbottom < fpScr->height - 1)
+ p[row * width + col] =
+ cInvertedArray[(fpScr->height - 1 - dydestbottom) * fpScr->width + col];
+ }
+ }
+ #endif
+
+ h = LOWORD(GlobalHandle(SELECTOROF(cInvertedArray)));
+ GlobalUnlock(h);
+ GlobalFree(h);
+ cInvertedArray = p;
+
+ /*
+ Append any new lines which need to be added to accomodate the new
+ screen size.
+ */
+ hgBottomLine = fpScr->buffer_bottom;
+ newlines = height - (fpScr->height + fpScr->numlines);
+
+ if (newlines > 0) {
+ fpScr->y += fpScr->numlines;
+ fpScr->numlines = 0;
+
+ for (idx = 0; idx < newlines; idx++) {
+ hgNewLine = ScreenNewLine();
+ fpNewLine = LINE_MEM_LOCK(hgNewLine);
+ if (fpNewLine == NULL)
+ return(FALSE);
+ fpNewLine->prev = hgBottomLine;
+
+ fpBottomLine = LINE_MEM_LOCK(hgBottomLine);
+ if (fpBottomLine == NULL)
+ return(FALSE);
+ fpBottomLine->next = hgNewLine;
+ LINE_MEM_UNLOCK(hgBottomLine);
+
+ LINE_MEM_UNLOCK(hgNewLine);
+
+ hgBottomLine = hgNewLine;
+ }
+ }
+
+ /*
+ If we already have plenty of lines, then we need to get rid of the
+ scrollback lines, if too many exist. The cursor should end up
+ the same distance from the bottom of the screen as is started out
+ in this instance.
+ */
+ if (newlines < 0) {
+ fpScr->y = (height - 1) - (fpScr->bottom - fpScr->y);
+ if (fpScr->y < 0)
+ fpScr->y = 0;
+ fpScr->numlines = -newlines;
+ n = fpScr->numlines - fpScr->maxlines;
+ for (idx = 0; idx < n; idx++)
+ DeleteTopLine(fpScr);
+ }
+
+ /*
+ Calculate the position of the buffer relative to the screen.
+ */
+ fpScr->screen_bottom = hgBottomLine;
+ fpScr->buffer_bottom = hgBottomLine;
+
+ hgTopLine = hgBottomLine;
+
+ for (idx = 1; idx < height; idx++) {
+ fpTopLine = LINE_MEM_LOCK(hgTopLine);
+ hgTopLine = fpTopLine->prev;
+ LINE_MEM_UNLOCK(hgTopLine);
+ }
+
+ fpScr->screen_top = hgTopLine;
+ fpScr->width = width;
+ fpScr->height = height;
+ fpScr->top = 0;
+ fpScr->bottom = height - 1;
+
+ if (fpScr->x >= width)
+ fpScr->x = width - 1;
+
+ if (fpScr->y >= height)
+ fpScr->y = height - 1;
+
+ SetScreenScrollBar(fpScr);
+ ScreenCursorOn(fpScr);
+ return(TRUE);
+}
+
+static int ScreenAdjustUp(SCREEN *fpScr, int n)
+{
+ int idx;
+ HSCREENLINE hslLine1;
+ HSCREENLINE hslLine2;
+ SCREENLINE *fpScrLine1;
+ SCREENLINE *fpScrLine2;
+
+ for (idx = 0; idx < n; idx++) {
+ if (fpScr->screen_top == fpScr->buffer_top)
+ return(-idx);
+ fpScrLine1 = LINE_MEM_LOCK(fpScr->screen_top);
+ hslLine1 = fpScrLine1->prev;
+ LINE_MEM_UNLOCK(fpScr->screen_top);
+ if (hslLine1 == NULL)
+ return(-idx);
+ fpScrLine2 = LINE_MEM_LOCK(fpScr->screen_bottom);
+ hslLine2 = fpScrLine2->prev;
+ LINE_MEM_UNLOCK(fpScr->screen_bottom);
+ if (hslLine2 == NULL)
+ return(-idx);
+ fpScr->screen_top = hslLine1;
+ fpScr->screen_bottom = hslLine2;
+ }
+ return(idx);
+}
+
+static int ScreenAdjustDown(SCREEN *fpScr, int n)
+{
+ int idx;
+ HSCREENLINE hslLine1;
+ HSCREENLINE hslLine2;
+ SCREENLINE *fpScrLine1;
+ SCREENLINE *fpScrLine2;
+
+ for (idx = 0; idx < n; idx++) {
+ if (fpScr->screen_bottom == fpScr->buffer_bottom)
+ return(-idx);
+ fpScrLine1 = LINE_MEM_LOCK(fpScr->screen_top);
+ hslLine1 = fpScrLine1->next;
+ LINE_MEM_UNLOCK(fpScr->screen_top);
+ if (hslLine1 == NULL)
+ return(-idx);
+ fpScrLine2 = LINE_MEM_LOCK(fpScr->screen_bottom);
+ hslLine2 = fpScrLine2->next;
+ LINE_MEM_UNLOCK(fpScr->screen_bottom);
+ if (hslLine2 == NULL)
+ return(-idx);
+ fpScr->screen_top = hslLine1;
+ fpScr->screen_bottom = hslLine2;
+ }
+ return(idx);
+}
+
+long FAR PASCAL ScreenWndProc(hWnd, message, wParam, lParam)
+HWND hWnd; /* window handle */
+UINT message; /* type of message */
+WPARAM wParam; /* additional information */
+LPARAM lParam; /* additional information */
+{
+ MINMAXINFO *lpmmi;
+ SCREEN *fpScr;
+ HGLOBAL hgScr;
+ HMENU hMenu;
+ PAINTSTRUCT ps;
+ int x=0,
+ y=0,
+ ScrollPos,tmpScroll=0,
+ idx;
+ HSCREENLINE hslLine;
+ HDC hDC;
+ RECT rc;
+ char title[128];
+
+ switch (message) {
+
+ case WM_COMMAND:
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+
+ switch (wParam) {
+
+ case IDM_BACKSPACE:
+ hMenu=GetMenu(hWnd);
+ CheckMenuItem(hMenu,IDM_BACKSPACE,MF_CHECKED);
+ CheckMenuItem(hMenu,IDM_DELETE,MF_UNCHECKED);
+ SendMessage(fpScr->hwndTel,WM_MYSCREENCHANGEBKSP,VK_BACK,(HSCREEN)hgScr);
+ break;
+ case IDM_DELETE:
+ hMenu=GetMenu(hWnd);
+ CheckMenuItem(hMenu,IDM_BACKSPACE,MF_UNCHECKED);
+ CheckMenuItem(hMenu,IDM_DELETE,MF_CHECKED);
+ SendMessage(fpScr->hwndTel,WM_MYSCREENCHANGEBKSP,0x7f,(HSCREEN)hgScr);
+ break;
+ case IDM_FONT:
+ ScreenCursorOff(fpScr);
+ ProcessFontChange(hWnd);
+ ScreenCursorOn(fpScr);
+ break;
+ case IDM_COPY:
+ Edit_Copy(hWnd);
+ hMenu=GetMenu(hWnd);
+ Edit_ClearSelection(fpScr);
+ GlobalUnlock(hgScr);
+ break;
+ case IDM_PASTE:
+ Edit_Paste(hWnd);
+ break;
+#ifdef _DEBUG
+ case IDM_DEBUG:
+ CheckScreen(fpScr);
+ break;
+#endif
+ }
+
+ GlobalUnlock(hgScr);
+ break;
+
+ case WM_CREATE:
+// OutputDebugString("WM_CREATE\r\n");
+ SetWindowWord(hWnd,SCREEN_HANDLE,NULL);
+ SetScrollRange(hWnd,SB_VERT,0,100,FALSE);
+ SetScrollPos(hWnd,SB_VERT,0,TRUE);
+ EnableScrollBar(hWnd,SB_VERT,ESB_DISABLE_BOTH);
+ ShowWindow(hWnd,SW_SHOW);
+#ifdef FILE_DEBUG
+ fh=OpenFile("d:\\debug.txt",&ofFile,OF_CREATE|OF_WRITE);
+#endif
+ break;
+
+ case WM_VSCROLL:
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+
+ ScreenCursorOff(fpScr);
+
+ switch(wParam) {
+ case SB_LINEDOWN:
+ if (ScreenAdjustDown(fpScr, 1) <= 0)
+ break;
+ hDC = GetDC(hWnd);
+ rc.left = 0;
+ rc.right = fpScr->cxChar * fpScr->width;
+ rc.top = 0;
+ rc.bottom = fpScr->cyChar * (fpScr->bottom+1);
+ ScrollDC(hDC, 0, -fpScr->cyChar, &rc, &rc, NULL, NULL);
+ ReleaseDC(hWnd, hDC);
+ rc.top = fpScr->cyChar * fpScr->bottom;
+ InvalidateRect(hWnd, &rc, TRUE);
+ ScrollPos=GetScrollPos(hWnd,SB_VERT);
+ SetScrollPos(hWnd,SB_VERT,ScrollPos+1,TRUE);
+ UpdateWindow(hWnd);
+ break;
+
+ case SB_LINEUP:
+ if (ScreenAdjustUp(fpScr, 1) <= 0)
+ break;
+ hDC = GetDC(hWnd);
+ rc.left = 0;
+ rc.right = fpScr->cxChar * fpScr->width;
+ rc.top = 0;
+ rc.bottom = fpScr->cyChar * (fpScr->bottom+1);
+ ScrollDC(hDC, 0, fpScr->cyChar, &rc, &rc, NULL, NULL);
+ ReleaseDC(hWnd, hDC);
+ rc.bottom = fpScr->cyChar;
+ InvalidateRect(hWnd, &rc, TRUE);
+ ScrollPos=GetScrollPos(fpScr->hWnd,SB_VERT);
+ SetScrollPos(hWnd,SB_VERT,ScrollPos-1,TRUE);
+ UpdateWindow(hWnd);
+ break;
+
+ case SB_PAGEDOWN:
+ idx = abs(ScreenAdjustDown(fpScr, fpScr->height));
+ hDC = GetDC(hWnd);
+ rc.left = 0;
+ rc.right = fpScr->cxChar * fpScr->width;
+ rc.top = 0;
+ rc.bottom = fpScr->cyChar * (fpScr->bottom+1);
+ ScrollDC(hDC, 0, -idx * fpScr->cyChar, &rc, &rc, NULL, NULL);
+ ReleaseDC(hWnd, hDC);
+ rc.top = fpScr->cyChar * (fpScr->bottom - idx + 1);
+ InvalidateRect(hWnd, &rc, TRUE);
+ ScrollPos=GetScrollPos(hWnd,SB_VERT);
+ SetScrollPos(hWnd,SB_VERT,ScrollPos+idx,TRUE);
+ break;
+
+ case SB_PAGEUP:
+ idx = abs(ScreenAdjustUp(fpScr, fpScr->height));
+ hDC = GetDC(hWnd);
+ rc.left = 0;
+ rc.right = fpScr->cxChar * fpScr->width;
+ rc.top = 0;
+ rc.bottom = fpScr->cyChar * (fpScr->bottom+1);
+ ScrollDC(hDC, 0, idx * fpScr->cyChar, &rc, &rc, NULL, NULL);
+ ReleaseDC(hWnd, hDC);
+ rc.bottom = idx * fpScr->cyChar;
+ InvalidateRect(hWnd, &rc, TRUE);
+ ScrollPos=GetScrollPos(hWnd,SB_VERT);
+ SetScrollPos(hWnd,SB_VERT,ScrollPos-idx,TRUE);
+ break;
+
+ case SB_THUMBPOSITION:
+ case SB_THUMBTRACK:
+ ScrollPos = GetScrollPos(hWnd,SB_VERT);
+ tmpScroll = ScrollPos - LOWORD(lParam);
+ if (tmpScroll == 0)
+ break;
+ if (tmpScroll > 0)
+ ScreenAdjustUp(fpScr, tmpScroll);
+ else
+ ScreenAdjustDown(fpScr, -tmpScroll);
+ if (abs(tmpScroll) < fpScr->height) {
+ hDC=GetDC(hWnd);
+ rc.left = 0;
+ rc.right = fpScr->cxChar * fpScr->width;
+ rc.top = 0;
+ rc.bottom = fpScr->cyChar * (fpScr->bottom+1);
+ ScrollDC(hDC,0,tmpScroll*fpScr->cyChar,&rc,&rc,NULL,NULL);
+ ReleaseDC(hWnd, hDC);
+ if (tmpScroll > 0) {
+ rc.bottom = tmpScroll * fpScr->cyChar;
+ InvalidateRect(hWnd, &rc, TRUE);
+ }
+ else {
+ rc.top = (fpScr->bottom + tmpScroll + 1) * fpScr->cyChar;
+ InvalidateRect(hWnd, &rc, TRUE);
+ }
+ }
+ else
+ InvalidateRect(hWnd, NULL, TRUE);
+
+ SetScrollPos(hWnd,SB_VERT,LOWORD(lParam),TRUE);
+ UpdateWindow(hWnd);
+ break;
+ }
+ ScreenCursorOn(fpScr);
+ GlobalUnlock(hgScr);
+ break;
+
+ case WM_KEYDOWN:
+ if (wParam==VK_INSERT) {
+ if (GetKeyState(VK_SHIFT)<0)
+ PostMessage(hWnd,WM_COMMAND,IDM_PASTE,NULL);
+ else if (GetKeyState(VK_CONTROL)<0)
+ PostMessage(hWnd,WM_COMMAND,IDM_COPY,NULL);
+ break;
+ }
+ if ((wParam < VK_PRIOR)||(wParam > VK_DOWN)) break;
+ switch (wParam) {
+ case VK_PRIOR: /* Page up */
+ SendMessage(hWnd,WM_VSCROLL,SB_PAGEUP,NULL);
+ break;
+ case VK_NEXT: /* Page down */
+ SendMessage(hWnd,WM_VSCROLL,SB_PAGEDOWN,NULL);
+ break;
+ case VK_UP: /* Line up */
+ SendMessage(hWnd,WM_VSCROLL,SB_LINEUP,NULL);
+ break;
+ case VK_DOWN: /* Line down */
+ SendMessage(hWnd,WM_VSCROLL,SB_LINEDOWN,NULL);
+ break;
+ }
+ UpdateWindow(hWnd);
+ break;
+
+ case WM_CHAR:
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) {
+ OutputDebugString("Hosed #1.\r\n");
+ break;
+ }
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) {
+ OutputDebugString("Hosed #2.\r\n");
+ break;
+ }
+ SendMessage(fpScr->hwndTel,WM_MYSCREENCHAR,wParam,(HSCREEN)hgScr);
+ GlobalUnlock(hgScr);
+ break;
+
+ case WM_SYSCHAR:
+ if ((wParam=='c')||(wParam=='e'))
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) {
+ OutputDebugString("Hosed #1.\r\n");
+ break;
+ }
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) {
+ OutputDebugString("Hosed #2.\r\n");
+ break;
+ }
+ SendMessage(fpScr->hwndTel,WM_MYSYSCHAR,wParam,(HSCREEN)hgScr);
+ GlobalUnlock(hgScr);
+ break;
+
+ case WM_INITMENU:
+ if (IsClipboardFormatAvailable(CF_TEXT))
+ EnableMenuItem((HMENU) wParam,IDM_PASTE,MF_ENABLED);
+ else EnableMenuItem((HMENU) wParam,IDM_PASTE,MF_GRAYED);
+ if (bSelection) EnableMenuItem((HMENU) wParam,IDM_COPY,MF_ENABLED);
+ else EnableMenuItem((HMENU) wParam,IDM_COPY,MF_GRAYED);
+ break;
+
+ case WM_GETMINMAXINFO:
+// OutputDebugString("WM_GETMINMAX_INFO\r\n");
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) break;
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+// if (fpScr == NULL) OutputDebugString("Hosed in GetMinMaxInfo.\r\n");
+// wsprintf(strTmp,"cx=%d cy=%d width=%d height=%d",fpScr->cxChar,fpScr->cyChar,fpScr->width,fpScr->height);
+// OutputDebugString(strTmp);
+ lpmmi = (MINMAXINFO *) lParam;
+ if (FRAME_WIDTH + MAX_LINE_WIDTH * fpScr->cxChar < lpmmi->ptMaxSize.x)
+ lpmmi->ptMaxSize.x = FRAME_WIDTH + MAX_LINE_WIDTH * fpScr->cxChar;
+ lpmmi->ptMaxTrackSize.x = lpmmi->ptMaxSize.x;
+ lpmmi->ptMinTrackSize.x = FRAME_WIDTH + 20 * fpScr->cxChar;
+ lpmmi->ptMinTrackSize.y = FRAME_HEIGHT + 4 * fpScr->cyChar;
+ GlobalUnlock(hgScr);
+ break;
+
+ case WM_LBUTTONDOWN:
+ if (bDoubleClick) Edit_TripleClick(hWnd,lParam);
+ else Edit_LbuttonDown(hWnd,lParam);
+ break;
+
+ case WM_LBUTTONUP:
+ Edit_LbuttonUp(hWnd,lParam);
+ break;
+
+ case WM_LBUTTONDBLCLK:
+ bDoubleClick=TRUE;
+ SetTimer(hWnd,TIMER_TRIPLECLICK,GetDoubleClickTime(),NULL);
+ Edit_LbuttonDblclk(hWnd,lParam);
+ break;
+
+ case WM_TIMER:
+ if (wParam==TIMER_TRIPLECLICK) bDoubleClick=FALSE;
+ break;
+
+ case WM_RBUTTONUP:
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) {
+ OutputDebugString("Hosed #1.\r\n");
+ break;
+ }
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) {
+ OutputDebugString("Hosed #2.\r\n");
+ break;
+ }
+ Edit_Copy(hWnd);
+ Edit_ClearSelection(fpScr);
+ Edit_Paste(hWnd);
+ GlobalUnlock(hgScr);
+ break;
+
+ case WM_MOUSEMOVE:
+ if (bMouseDown) Edit_MouseMove(hWnd,lParam);
+ break;
+
+ case WM_RBUTTONDOWN: {
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) {
+ OutputDebugString("Hosed #1.\r\n");
+ break;
+ }
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) {
+ OutputDebugString("Hosed #2.\r\n");
+ break;
+ }
+ hgScrLine=fpScr->screen_top;
+ fpScrLine=LINE_MEM_LOCK(hgScrLine);
+
+// wsprintf(strTmp,"fp->x=%d fp->y=%d text=%s \r\n",fpScr->x,fpScr->y,fpScrLine->text);
+// OutputDebugString(strTmp);
+ LINE_MEM_LOCK(hgScrLine);
+ }
+ break;
+
+ case WM_PAINT:
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) {
+ OutputDebugString("Hosed #1.\r\n");
+ break;
+ }
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) {
+ OutputDebugString("Hosed #2.\r\n");
+ break;
+ }
+ BeginPaint (hWnd,&ps);
+ SelectObject(ps.hdc,fpScr->ghSelectedFont);
+ hslLine=fpScr->screen_bottom;
+ if (hslLine==NULL) {
+ OutputDebugString("screen_bottom is NULL.\r\n");
+ EndPaint(hWnd,&ps);
+ GlobalUnlock(hgScr);
+ break;
+ }
+ DrawTextScreen(ps.rcPaint, fpScr, ps.hdc);
+ EndPaint(hWnd,&ps);
+ DrawCursor(fpScr);
+ GlobalUnlock(hgScr);
+ break;
+
+ case WM_CLOSE:
+#ifdef FILE_DEBUG
+ _lclose(fh);
+#endif
+ if (MessageBox(hWnd,"Terminate this connection?","Telnet",MB_OKCANCEL) == IDOK) {
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) OutputDebugString("Hosed #1.\r\n");
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+ SendMessage(fpScr->hwndTel,WM_MYSCREENCLOSE,NULL,(HSCREEN)hgScr);
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+ break;
+
+ case WM_DESTROY:
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr != NULL) {
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr != NULL)
+ DeleteObject(fpScr->ghSelectedFont);
+ }
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+
+ case WM_ACTIVATE:
+ if (wParam!=WA_INACTIVE) {
+ hgScr=(HGLOBAL)GetWindowWord(hWnd,SCREEN_HANDLE);
+ if (hgScr == NULL) return (DefWindowProc(hWnd, message, wParam, lParam));
+ fpScr=(SCREEN *)GlobalLock(hgScr);
+ if (fpScr == NULL) OutputDebugString("Hosed #2.\r\n");
+ if (fpScr->bAlert) {
+ char strTitle[128];
+ int idx;
+
+ GetWindowText(hWnd,strTitle,sizeof(strTitle));
+ if (strTitle[0] == ALERT) {
+ idx=lstrlen(strTitle);
+ strTitle[idx-2]=0;
+ SetWindowText(hWnd,&strTitle[2]);
+ fpScr->bAlert=FALSE;
+ }
+ }
+ GlobalUnlock(hgScr);
+ } /* Allow control to drop down to DefWindowProc() */
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ break;
+
+ case WM_SIZE:
+ if (wParam == SIZE_MINIMIZED)
+ break;
+
+ hgScr = (HGLOBAL) GetWindowWord(hWnd, SCREEN_HANDLE);
+ if (hgScr == NULL)
+ break;
+ fpScr = (SCREEN *) GlobalLock(hgScr);
+ if (fpScr == NULL)
+ break;
+
+ if (SetInternalScreenSize(fpScr, LOWORD(lParam), HIWORD(lParam))) {
+ SendMessage(fpScr->hwndTel, WM_MYSCREENSIZE, 0,
+ MAKELONG(fpScr->width, fpScr->height));
+ MakeWindowTitle(fpScr->title,fpScr->width,fpScr->height,title,sizeof(title));
+ SetWindowText(hWnd,title);
+ }
+
+ GlobalUnlock(hgScr);
+ break;
+
+ case WM_SETFOCUS:
+ hgScr = (HGLOBAL) GetWindowWord(hWnd, SCREEN_HANDLE);
+ if (hgScr == NULL)
+ break;
+ fpScr = (SCREEN *) GlobalLock(hgScr);
+ if (fpScr == NULL)
+ break;
+
+ CreateCaret(hWnd, NULL, fpScr->cxChar, 2);
+ ScreenCursorOn(fpScr);
+ break;
+
+ case WM_KILLFOCUS:
+ DestroyCaret();
+ break;
+
+ default: /* Passes it on if unproccessed */
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+
+ return (NULL);
+}
+
+/**************************************************************************
+* *
+* Function: ReportError(WORD) *
+* *
+* Purpose: To report an error that has occurred while allocating *
+* memory for the CD struct, locking the memory or while *
+* trying to load a resource string. *
+* *
+* Returns: void *
+* *
+* Comments: *
+* *
+* History: Date Reason *
+* -------- ----------------------------------- *
+* *
+* 10/01/91 Created *
+* *
+**************************************************************************/
+void ReportError(WORD wErrorType){
+ LPSTR lpszErrorMsg;
+
+ switch( wErrorType )
+ {
+ case IDC_ALLOCFAIL:
+
+ lpszErrorMsg=gszAllocErrorMsg;
+ break;
+
+ case IDC_LOCKFAIL:
+
+ lpszErrorMsg=gszLockErrorMsg;
+ break;
+
+ case IDC_LOADSTRINGFAIL:
+
+ lpszErrorMsg=gszLoadStrFail;
+ break;
+
+ default: //let's hope we never get here!
+ return;
+ }
+
+ MessageBox(NULL, (LPSTR)lpszErrorMsg, NULL, MB_OK);
+
+ return;
+}
+
+void ScreenBell(SCREEN *fpScr) {
+ MessageBeep(MB_ICONEXCLAMATION);
+ if (fpScr->hWnd != GetActiveWindow()) {
+ char strTitle[128];
+ int idx;
+
+ FlashWindow(fpScr->hWnd,TRUE);
+ if (!fpScr->bAlert) {
+ strTitle[0]=ALERT;
+ strTitle[1]=SPACE;
+ GetWindowText(fpScr->hWnd,&strTitle[2],sizeof(strTitle)-2);
+ idx=lstrlen(strTitle);
+ strTitle[idx]=SPACE;
+ strTitle[idx+1]=ALERT;
+ strTitle[idx+2]=0;
+ SetWindowText(fpScr->hWnd,strTitle);
+ }
+ FlashWindow(fpScr->hWnd,FALSE);
+ fpScr->bAlert=TRUE;
+ }
+}
+
+void ScreenBackspace(SCREEN * fpScr) {
+ RECT rc;
+
+// hDC=GetDC(fpScr->hWnd);
+// SelectObject(hDC,fpScr->ghSelectedFont);
+// TextOut(hDC,fpScr->x*fpScr->cxChar,fpScr->y*fpScr->cyChar," ",1);
+// ReleaseDC(fpScr->hWnd,hDC);
+ rc.left=fpScr->x*fpScr->cxChar;
+ rc.right=((fpScr->x+1)*fpScr->cxChar);
+ rc.top=(fpScr->cyChar*fpScr->y);
+ rc.bottom=(fpScr->cyChar*fpScr->y+1);
+ InvalidateRect(fpScr->hWnd,&rc,TRUE);
+ fpScr->x--;
+ if (fpScr->x < 0) fpScr->x=0;
+// DrawCursor(fpScr);
+ UpdateWindow(fpScr->hWnd);
+
+}
+
+void ScreenTab(SCREEN *fpScr) {
+ int num_spaces,idx;
+ HSCREENLINE hgScrLine;
+ SCREENLINE *fpScrLine;
+ int iTest=0;
+
+ num_spaces = TAB_SPACES - (fpScr->x % TAB_SPACES);
+ if ((fpScr->x + num_spaces) >= fpScr->width) {
+ ScreenScroll(fpScr);
+ num_spaces -= fpScr->width - fpScr->x;
+ fpScr->x=0;
+ }
+// hgScrLine=fpScr->buffer_bottom;
+ hgScrLine=GetScreenLineFromY(fpScr,fpScr->y);
+ if (hgScrLine==NULL) return;
+ fpScrLine=(SCREENLINE *)LINE_MEM_LOCK(hgScrLine);
+ if (fpScrLine==NULL) return;
+ for (idx=0; idx<num_spaces; idx++,fpScr->x++) {
+ if (!fpScrLine->text[fpScr->x])
+ iTest=1;
+ if (iTest)
+ fpScrLine->text[fpScr->x]=SPACE;
+ }
+// fpScrLine->text[fpScr->x]=0;
+ hDC=GetDC(fpScr->hWnd);
+ SelectObject(hDC,fpScr->ghSelectedFont);
+ TextOut(hDC,(fpScr->x-num_spaces)*fpScr->cxChar,fpScr->y*fpScr->cyChar,
+ fpScrLine->text+fpScr->x-num_spaces,num_spaces);
+ ReleaseDC(fpScr->hWnd,hDC);
+ LINE_MEM_UNLOCK(hgScrLine);
+ DrawCursor(fpScr);
+}
+
+void ScreenCarriageFeed(SCREEN *fpScr) {
+ DrawCursor(fpScr);
+ fpScr->x=0;
+}
--- /dev/null
+extern long FAR PASCAL ScreenWndProc(HWND,UINT,WPARAM,LPARAM);
+
+//#define WINMEM
+
+/*
+* Definition of attribute bits in the Virtual Screen
+*
+* 0 - Bold
+* 1 -
+* 2 -
+* 3 - Underline
+* 4 - Blink
+* 5 -
+* 6 - Reverse
+* 7 - Graphics character set
+*
+*/
+#define SCR_isbold(x) (x & 0x01)
+#define SCR_isundl(x) (x & 0x08)
+#define SCR_isblnk(x) (x & 0x10)
+#define SCR_isrev(x) (x & 0x40)
+#define SCR_setrev(x) (x ^= 0x40)
+#define SCR_isgrph(x) (x & 0x80)
+#define SCR_inattr(x) (x & 0xd9)
+#define SCR_graph(x) (x | 0x80)
+#define SCR_notgraph(x) (x & 0x7F)
+
+#define SCREEN_HANDLE 0 /* offset in extra window info */
+
+#define WM_MYSCREENCHAR (WM_USER+1)
+#define WM_MYSCREENBLOCK (WM_USER+2)
+#define WM_MYSYSCHAR (WM_USER+3)
+#define WM_MYSCREENCLOSE (WM_USER+4)
+#define WM_MYSCREENCHANGEBKSP (WM_USER+5)
+#define WM_MYSCREENSIZE (WM_USER+6)
+#define WM_NETWORKEVENT (WM_USER+7)
+#define WM_HOSTNAMEFOUND (WM_USER+8)
+
+#define FRAME_HEIGHT ((2* GetSystemMetrics(SM_CYFRAME))+GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYMENU)+3)
+#define FRAME_WIDTH (2*GetSystemMetrics(SM_CXFRAME)+GetSystemMetrics(SM_CXVSCROLL))
+#define TAB_SPACES 8
+#define SPACE 32
+#define ALERT 0x21
+#define MAX_LINE_WIDTH 256 /* not restricted to 1 byte */
+
+#ifdef WINMEM
+#define HSCREENLINE DWORD
+#define LINE_MEM_ALLOC(x) sAlloc(x)
+#define LINE_MEM_LOCK(x) (SCREENLINE *)sLock(x)
+#define LINE_MEM_UNLOCK(x) sUnlock(x)
+#define LINE_MEM_FREE(x) sFree(x)
+#else
+#define HSCREENLINE HGLOBAL
+#define LINE_MEM_ALLOC(x) GlobalAlloc(GHND,x)
+#define LINE_MEM_LOCK(x) (SCREENLINE *) GlobalLock(x)
+#define LINE_MEM_UNLOCK(x) GlobalUnlock(x)
+#define LINE_MEM_FREE(x) GlobalFree(x)
+#endif
+
+#define HSCREEN HGLOBAL
+
+typedef struct SCREENLINE {
+ HSCREENLINE next;
+ HSCREENLINE prev;
+ int width;
+ char *text;
+ char *attrib;
+ char buffer[0];
+} SCREENLINE;
+
+typedef struct SCREEN {
+ LPSTR title;
+ HWND hWnd;
+ HWND hwndTel;
+ HSCREENLINE screen_top,
+ screen_bottom,
+ buffer_top,
+ buffer_bottom;
+ int ID,
+ type,
+ width,
+ height,
+ maxlines, //Maximum number of scrollback lines
+ numlines, //Current number of scrollback lines
+ savelines, //Save lines off top?
+ ESscroll, //Scroll screen when ES received
+ attrib, //current attribute
+ x,y, //current cursor position
+ Oldx,Oldy, // internally used to redraw cursor
+ Px,Py,Pattrib, //saved cursor pos and attribute
+ VSIDC, // Insert/Delete character mode 0=draw line
+ DECAWM, // AutoWrap mode 0=off
+ DECCKM, // Cursor key mode
+ DECPAM, // keyPad Application mode
+ IRM, // Insert/Replace mode
+ escflg, // Current Escape level
+ top,bottom, // Vertical bounds of screen
+ parmptr,
+ cxChar, /* Width of the current font */
+ cyChar; /* Height of the current font */
+ BOOL bAlert;
+ int parms[6]; //Ansi Params
+ LOGFONT lf;
+ HFONT ghSelectedFont,ghSelectedULFont;
+ char tabs[MAX_LINE_WIDTH];
+ HSCREEN next, prev;
+} SCREEN;
+
+typedef struct CONFIG {
+ LPSTR title;
+ HWND hwndTel;
+ int ID,
+ type,
+ height,
+ width,
+ maxlines, //Maximum number of scrollback lines
+ backspace,
+ ESscroll, //Scroll screen when ES received
+ VSIDC, // Insert/Delete character mode 0=draw line
+ DECAWM, // AutoWrap mode 0=off
+ IRM; // Insert/Replace mode
+} CONFIG;
+
+#define TELNET_SCREEN 0
+#define CONSOLE_SCREEN 1
+
+#define IDM_FONT 100
+#define IDM_BACKSPACE 101
+#define IDM_DELETE 102
+
+#define IDM_COPY 200
+#define IDM_PASTE 201
+#define IDM_DEBUG 202
+
+#define TIMER_TRIPLECLICK 1000
+
+#define IDC_ALLOCFAIL 1
+#define IDC_LOCKFAIL 2
+#define IDC_LOADSTRINGFAIL 3
+#define IDC_FONT 6
+
+#define DESIREDPOINTSIZE 12
+
+
+void ReportError(WORD);
+LPSTR NEAR AllocAndLockMem(HANDLE *hChunk, WORD wSize);
+void NEAR InitializeStruct(WORD wCommDlgType, LPSTR lpStruct, HWND hWnd);
+
+void ScreenInit(HANDLE hInstance);
+HSCREENLINE ScreenNewLine();
+void ScreenBell(SCREEN *fpScr);
+void ScreenBackspace(SCREEN * fpScr);
+void ScreenTab(SCREEN *fpScr);
+void ScreenCarriageFeed(SCREEN *fpScr);
+int ScreenScroll(SCREEN *fpScr);
+void DeleteTopLine(SCREEN *fpScr);
+/* emul.c */
+void ScreenEm(LPSTR c,int len,HSCREEN hsScr);
+
+
+/* intern.c */
+HSCREENLINE GetScreenLineFromY(SCREEN *fpScr,int y);
+HSCREENLINE ScreenClearLine(SCREEN *fpScr,HSCREENLINE hgScrLine);
+void ScreenUnscroll(SCREEN *fpScr);
+void ScreenELO(SCREEN *fpScr,int s);
+void ScreenEraseScreen(SCREEN *fpScr);
+void ScreenTabClear(SCREEN *fpScr);
+void ScreenTabInit(SCREEN *fpScr);
+void ScreenReset(SCREEN *fpScr);
+void ScreenIndex(SCREEN * fpScr);
+void ScreenWrapNow(SCREEN *fpScr,int *xp,int *yp);
+void ScreenEraseToEOL(SCREEN *fpScr);
+void ScreenEraseToBOL(SCREEN *fpScr);
+void ScreenEraseLine(SCREEN *fpScr,int s);
+void ScreenEraseToEndOfScreen(SCREEN *fpScr);
+void ScreenRange(SCREEN *fpScr);
+void ScreenAlign(SCREEN *fpScr);
+void ScreenApClear(SCREEN *fpScr);
+int ScreenInsChar(SCREEN *fpScr,int x);
+void ScreenInsString(SCREEN *fpScr,int len,char *start);
+void ScreenSaveCursor(SCREEN *fpScr);
+void ScreenRestoreCursor(SCREEN *fpScr);
+void ScreenDraw(SCREEN *fpScr,int x,int y,int a,int len,char *c);
+void ScreenCursorOff(SCREEN *fpScr);
+void ScreenCursorOn(SCREEN *fpScr);
+void ScreenDelChars(SCREEN *fpScr, int n);
+void ScreenRevIndex(SCREEN *fpScr);
+void ScreenDelLines(SCREEN *fpScr, int n, int s);
+void ScreenInsLines(SCREEN *fpScr, int n, int s);
+#ifdef _DEBUG
+ BOOL CheckScreen(SCREEN *fpScr);
+#endif
+
+void ProcessFontChange(HWND hWnd);
+void Edit_LbuttonDown(HWND hWnd,LPARAM lParam);
+void Edit_LbuttonDblclk(HWND hWnd,LPARAM lParam);
+void Edit_LbuttonUp(HWND hWnd, LPARAM lParam);
+void Edit_TripleClick(HWND hWnd, LPARAM lParam);
+void Edit_MouseMove(HWND hWnd, LPARAM lParam);
+void Edit_ClearSelection(SCREEN *fpScr);
+void Edit_Copy(HWND hWnd);
+void Edit_Paste(HWND hWnd);
+
+HSCREEN InitNewScreen(CONFIG *Config);
+
+
--- /dev/null
+#include "winsock.h"
+#ifdef KRB4
+ #include "kstream.h"
+#endif
+#ifdef KRB5
+ #include "k5stream.h"
+#endif
+
+#define HCONNECTION HGLOBAL
+
+typedef struct CONNECTION {
+ HSCREEN hScreen; // handle to screen associated with connection
+ kstream ks;
+ SOCKET socket;
+ int pnum; // port number associated with connection
+ int telstate; // telnet state for this connection
+ int substate; // telnet subnegotiation state
+ int termsent;
+ int echo;
+ int ugoahead;
+ int igoahead;
+ int timing;
+ int backspace;
+ int ctrl_backspace;
+ int termstate; // terminal type for this connection
+ int width;
+ int height;
+ BOOL bResizeable;
+} CONNECTION;
+
--- /dev/null
+/****************************************************************************
+
+ PROGRAM: telnet.c
+
+ PURPOSE: Windows networking kernel - Telnet
+
+ FUNCTIONS:
+
+ WinMain() - calls initialization function, processes message loop
+ InitApplication() - initializes window data and registers window
+ InitInstance() - saves instance handle and creates main window
+ MainWndProc() - processes messages
+ About() - processes messages for "About" dialog box
+
+ COMMENTS:
+
+ Windows can have several copies of your application running at the
+ same time. The variable hInst keeps track of which instance this
+ application is so that processing will be to the correct window.
+
+****************************************************************************/
+
+#include <windows.h>
+#include <string.h>
+#include "telnet.h"
+#include "auth.h"
+
+HANDLE hInst; /* current instance */
+HWND hWnd; /* Main window handle. */
+CONFIG *tmpConfig;
+GLOBALHANDLE hGlobalMem, hTitleMem;
+CONNECTION *con = NULL;
+char hostdata[MAXGETHOSTSTRUCT];
+HGLOBAL ghCon;
+SCREEN *fpScr;
+int debug = 1;
+
+char __near strTmp[1024];
+
+BOOL bAutoConnection = FALSE;
+char szAutoHostName[64];
+char szUserName[64];
+char szHostName[64];
+
+#ifdef KRB4
+ #define WINDOW_CLASS "telnetWClass_4"
+#endif
+
+#ifdef KRB5
+ krb5_context k5_context;
+ #define WINDOW_CLASS "telnetWClass"
+#endif
+
+/*+**************************************************************************
+
+ FUNCTION: WinMain(HANDLE, HANDLE, LPSTR, int)
+
+ PURPOSE: calls initialization function, processes message loop
+
+ COMMENTS:
+
+ Windows recognizes this function by name as the initial entry point
+ for the program. This function calls the application initialization
+ routine, if no other instance of the program is running, and always
+ calls the instance initialization routine. It then executes a message
+ retrieval and dispatch loop that is the top-level control structure
+ for the remainder of execution. The loop is terminated when a WM_QUIT
+ message is received, at which time this function exits the application
+ instance by returning the value passed by PostQuitMessage().
+
+ If this function must abort before entering the message loop, it
+ returns the conventional value NULL.
+
+****************************************************************************/
+
+int PASCAL
+WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow)
+HANDLE hInstance; /* current instance */
+HANDLE hPrevInstance; /* previous instance */
+LPSTR lpCmdLine; /* command line */
+int nCmdShow; /* show-window type (open/icon) */
+{
+ MSG msg; /* message */
+
+ if (!hPrevInstance)
+ if (!InitApplication(hInstance)) /* Initialize shared things */
+ return (FALSE); /* Exits if unable to initialize */
+
+ /* Perform initializations that apply to a specific instance */
+
+ if (lpCmdLine[0]) {
+ bAutoConnection = TRUE;
+ lstrcpy((char *) szAutoHostName, lpCmdLine);
+ }
+ else bAutoConnection = FALSE;
+
+ if (!InitInstance(hInstance, nCmdShow))
+ return (FALSE);
+
+ /* Acquire and dispatch messages until a WM_QUIT message is received. */
+
+ while (GetMessage(&msg, NULL, NULL, NULL)) {
+ TranslateMessage(&msg); /* Translates virtual key codes */
+ DispatchMessage(&msg); /* Dispatches message to window */
+ }
+ return (msg.wParam); /* Returns the value from PostQuitMessage */
+}
+
+
+/*+**************************************************************************
+
+ FUNCTION: InitApplication(HANDLE)
+
+ PURPOSE: Initializes window data and registers window class
+
+ COMMENTS:
+
+ This function is called at initialization time only if no other
+ instances of the application are running. This function performs
+ initialization tasks that can be done once for any number of running
+ instances.
+
+ In this case, we initialize a window class by filling out a data
+ structure of type WNDCLASS and calling the Windows RegisterClass()
+ function. Since all instances of this application use the same window
+ class, we only need to do this when the first instance is initialized.
+
+
+****************************************************************************/
+
+BOOL
+InitApplication(hInstance)
+HANDLE hInstance; /* current instance */
+{
+ WNDCLASS wc;
+
+ ScreenInit(hInstance);
+
+ /* Fill in window class structure with parameters that describe the */
+ /* main window. */
+
+ wc.style = CS_HREDRAW|CS_VREDRAW; /* Class style(s). */
+ wc.lpfnWndProc = MainWndProc; /* Function to retrieve messages for */
+ /* windows of this class. */
+ wc.cbClsExtra = 0; /* No per-class extra data. */
+ wc.cbWndExtra = 0; /* No per-window extra data. */
+ wc.hInstance = hInstance; /* Application that owns the class. */
+ wc.hIcon = NULL; //LoadIcon(hInstance, "NCSA");
+ wc.hCursor = NULL; //Cursor(NULL, IDC_ARROW);
+ wc.hbrBackground = NULL; //GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = NULL; /* Name of menu resource in .RC file. */
+ wc.lpszClassName = WINDOW_CLASS; /* Name used in call to CreateWindow. */
+
+ /* Register the window class and return success/failure code. */
+ return (RegisterClass(&wc));
+}
+
+
+/*+**************************************************************************
+
+ FUNCTION: InitInstance(HANDLE, int)
+
+ PURPOSE: Saves instance handle and creates main window
+
+ COMMENTS:
+
+ This function is called at initialization time for every instance of
+ this application. This function performs initialization tasks that
+ cannot be shared by multiple instances.
+
+ In this case, we save the instance handle in a static variable and
+ create and display the main program window.
+
+****************************************************************************/
+BOOL
+InitInstance(hInstance, nCmdShow)
+ HANDLE hInstance; /* Current instance identifier. */
+ int nCmdShow; /* Param for first ShowWindow() call. */
+{
+ int xScreen = 0, yScreen = 0;
+
+ /* Save the instance handle in static variable, which will be used in */
+ /* many subsequence calls from this application to Windows. */
+
+ hInst = hInstance;
+
+ /* Create a main window for this application instance. */
+ hWnd = CreateWindow(
+ WINDOW_CLASS, /* See RegisterClass() call. */
+ "TCPWin", /* Text for window title bar. */
+ WS_SYSMENU, /* Window style. */
+ xScreen/3, /* Default horizontal position. */
+ yScreen/3, /* Default vertical position. */
+ xScreen/3, /* Default width. */
+ yScreen/3, /* Default height. */
+ NULL, /* Overlapped windows have no parent. */
+ NULL, /* Use the window class menu. */
+ hInstance, /* This instance owns this window. */
+ NULL /* Pointer not needed. */
+ );
+ if (!hWnd)
+ return (FALSE);
+
+// ShowWindow(hWnd, SW_SHOW); /* Show the window */
+// UpdateWindow(hWnd); /* Sends WM_PAINT message */
+
+ {
+ WSADATA wsaData;
+ if (WSAStartup(0x0101, &wsaData) != 0) { /* Initialize the network */
+ MessageBox(NULL, "Couldn't initialize Winsock!",
+ NULL, MB_OK | MB_ICONEXCLAMATION);
+ return FALSE;
+ }
+ }
+
+ if (! OpenTelnetConnection()) {
+ WSACleanup();
+ return(FALSE);
+ }
+
+ #ifdef KRB5
+ krb5_init_context(&k5_context);
+ krb5_init_ets(k5_context);
+ #endif
+ return (TRUE);
+}
+
+/*+***************************************************************************
+
+ FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)
+
+ PURPOSE: Processes messages
+
+ MESSAGES:
+
+ WM_COMMAND - application menu (About dialog box)
+ WM_DESTROY - destroy window
+
+****************************************************************************/
+
+long FAR PASCAL
+MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
+ HSCREEN hgScr;
+ SCREEN *fpScr;
+ HGLOBAL hBuffer;
+ LPSTR lpBuffer;
+ char c;
+ int iEvent, namelen, cnt, ret;
+ char buf[1024];
+ struct sockaddr_in name;
+ struct sockaddr_in remote_addr;
+ struct hostent *remote_host;
+ char *tmpCommaLoc;
+
+ switch (message) {
+
+ case WM_MYSCREENCHANGEBKSP:
+ if (!con) break;
+ con->backspace = wParam;
+ if (con->backspace == VK_BACK) {
+ con->ctrl_backspace = 0x7f;
+ WritePrivateProfileString(INI_TELNET, INI_BACKSPACE,
+ INI_BACKSPACE_BS, TELNET_INI);
+ }
+ else {
+ con->ctrl_backspace = VK_BACK;
+ WritePrivateProfileString(INI_TELNET, INI_BACKSPACE,
+ INI_BACKSPACE_DEL, TELNET_INI);
+ }
+ GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", buf, 128,
+ TELNET_INI);
+ tmpCommaLoc = strchr(buf, ',');
+ if (tmpCommaLoc) {
+ tmpCommaLoc++;
+ if (con->backspace == VK_BACK)
+ strcpy(tmpCommaLoc, INI_HOST_BS);
+ else
+ strcpy(tmpCommaLoc, INI_HOST_DEL);
+ }
+ WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI);
+ break;
+
+ case WM_MYSCREENCHAR:
+ if (!con) break;
+ if (wParam == VK_BACK)
+ wParam = con->backspace;
+ else
+ if (wParam == 0x7f)
+ wParam = con->ctrl_backspace;
+ TelnetSend(con->ks, (char *)&wParam, 1, NULL);
+ break;
+
+ case WM_MYSYSCHAR:
+ if (!con) break;
+ c = (char) wParam;
+ switch (c) {
+ case 'f':
+ getsockname(con->socket, (struct sockaddr *) &name,
+ (int *) &namelen);
+ wsprintf(buf, "ftp %d.%d.%d.%d\n",
+ name.sin_addr.S_un.S_un_b.s_b1,
+ name.sin_addr.S_un.S_un_b.s_b2,
+ name.sin_addr.S_un.S_un_b.s_b3,
+ name.sin_addr.S_un.S_un_b.s_b4);
+ TelnetSend(con->ks, buf, lstrlen(buf), NULL);
+ break;
+ case 'x':
+ hgScr = con->hScreen;
+ fpScr = (SCREEN *) GlobalLock(hgScr);
+ if (fpScr == NULL) break;
+ PostMessage(fpScr->hWnd, WM_CLOSE, NULL, NULL);
+ break;
+
+ }
+ break;
+
+ case WM_MYSCREENBLOCK:
+ if (!con) break;
+ hBuffer = (HGLOBAL) wParam;
+ lpBuffer = GlobalLock(hBuffer);
+ TelnetSend(con->ks, lpBuffer, lstrlen(lpBuffer), NULL);
+ GlobalUnlock(hBuffer);
+ break;
+
+ case WM_MYSCREENCLOSE:
+ if (!con) break;
+ kstream_destroy(con->ks);
+ DestroyWindow(hWnd);
+ break;
+
+ case WM_QUERYOPEN:
+ return(0);
+ break;
+
+ case WM_DESTROY: /* message: window being destroyed */
+ kstream_destroy(con->ks);
+ GlobalUnlock(ghCon);
+ GlobalFree(ghCon);
+ WSACleanup();
+ PostQuitMessage(0);
+ break;
+
+ case WM_NETWORKEVENT:
+ iEvent = WSAGETSELECTEVENT(lParam);
+
+ switch (iEvent) {
+
+ case FD_READ:
+ cnt = recv(con->socket, buf, 1024, NULL);
+ /*
+ The following line has been removed until kstream supports
+ non-blocking IO or larger size reads (jrivlin@fusion.com).
+ */
+ /* cnt = kstream_read(con->ks, buf, 1024); */
+ buf[cnt] = 0;
+ parse((CONNECTION *) con, (unsigned char *) buf, cnt);
+ ScreenEm(buf, cnt, con->hScreen);
+ break;
+
+ case FD_CLOSE:
+ kstream_destroy(con->ks);
+ GlobalUnlock(ghCon);
+ GlobalFree(ghCon);
+ WSACleanup();
+ PostQuitMessage(0);
+ break;
+
+ case FD_CONNECT:
+ ret = WSAGETSELECTERROR(lParam);
+ if (ret) {
+ wsprintf(buf, "Error %d on Connect", ret);
+ OutputDebugString (buf);
+ MessageBox(NULL, buf, NULL, MB_OK|MB_ICONEXCLAMATION);
+ kstream_destroy(con->ks);
+ GlobalUnlock(ghCon);
+ GlobalFree(ghCon);
+ WSACleanup();
+ PostQuitMessage(0);
+ break;
+ }
+ start_negotiation(con->ks);
+ break;
+ }
+ break;
+
+ case WM_HOSTNAMEFOUND:
+ ret = WSAGETASYNCERROR(lParam);
+ if (ret) {
+ wsprintf(buf, "Error %d on GetHostbyName", ret);
+ MessageBox(NULL, buf, NULL, MB_OK|MB_ICONEXCLAMATION);
+ kstream_destroy(con->ks);
+ GlobalUnlock(ghCon);
+ GlobalFree(ghCon);
+ WSACleanup();
+ PostQuitMessage(0);
+ break;
+ }
+ remote_host = (struct hostent *) hostdata;
+ remote_addr.sin_family = AF_INET;
+ remote_addr.sin_addr.S_un.S_un_b.s_b1 = remote_host->h_addr[0];
+ remote_addr.sin_addr.S_un.S_un_b.s_b2 = remote_host->h_addr[1];
+ remote_addr.sin_addr.S_un.S_un_b.s_b3 = remote_host->h_addr[2];
+ remote_addr.sin_addr.S_un.S_un_b.s_b4 = remote_host->h_addr[3];
+ #ifdef KRB4
+ remote_addr.sin_port = htons(23);
+ #endif
+ #ifdef KRB5
+ remote_addr.sin_port = htons(13131);
+ #endif
+
+ connect(con->socket, (struct sockaddr*) &remote_addr,
+ sizeof(struct sockaddr));
+ break;
+
+ case WM_MYSCREENSIZE:
+ con->width = LOWORD(lParam); /* width in characters */
+ con->height = HIWORD(lParam); /* height in characters */
+ if (con->bResizeable && con->ks)
+ send_naws(con);
+ wsprintf(buf, "%d", con->height);
+ WritePrivateProfileString(INI_TELNET, INI_HEIGHT, buf, TELNET_INI);
+ wsprintf(buf, "%d", con->width);
+ WritePrivateProfileString(INI_TELNET, INI_WIDTH, buf, TELNET_INI);
+ break;
+
+ default: /* Passes it on if unproccessed */
+ return(DefWindowProc(hWnd, message, wParam, lParam));
+ }
+ return (NULL);
+}
+
+
+/*+***************************************************************************
+
+ FUNCTION: SaveHostName(hostname)
+
+ PURPOSE: Saves the currently selected host name in the KERBEROS.INI file
+ and returns the preferred backspace setting if one exists for
+ that host.
+
+ RETURNS: VK_BACK or 0x7f depending on the desired backspace setting.
+
+****************************************************************************/
+
+int
+SaveHostName(char *host)
+{
+ char buf[128];
+ char hostName[10][128];
+ char *tmpCommaLoc;
+ char tmpName[128];
+ char tmpBuf[80];
+ int nhosts;
+ int n;
+ int iHostNum;
+ int bs;
+
+ nhosts = 0;
+ for (iHostNum = 0; iHostNum < 10; iHostNum++) {
+ wsprintf(tmpBuf, INI_HOST "%d", iHostNum);
+ GetPrivateProfileString(INI_HOSTS, tmpBuf, "", hostName[iHostNum],
+ 128, TELNET_INI);
+ strcpy(tmpName, hostName[iHostNum]);
+ tmpCommaLoc = strchr(tmpName, ',');
+ if (tmpCommaLoc) {
+ *tmpCommaLoc = '\0';
+ while (tmpCommaLoc[1] == ' ')
+ tmpCommaLoc++;
+ }
+ if (!hostName[iHostNum][0])
+ break;
+ nhosts++;
+ if (strcmp(tmpName, host) == 0)
+ break;
+ }
+
+ for (iHostNum++; iHostNum < 10; iHostNum++) {
+ wsprintf(tmpBuf, INI_HOST "%d", iHostNum);
+ GetPrivateProfileString(INI_HOSTS, tmpBuf, "", hostName[iHostNum],
+ 128, TELNET_INI);
+ if (!hostName[iHostNum][0])
+ break;
+ nhosts++;
+ }
+
+ if (tmpCommaLoc)
+ tmpCommaLoc++;
+
+ if (tmpName[0] && tmpCommaLoc) {
+ if (_stricmp(tmpCommaLoc, INI_HOST_DEL) == 0)
+ bs = 0x7f;
+ else if (_stricmp(tmpCommaLoc, INI_HOST_BS) == 0)
+ bs = VK_BACK;
+ }
+ else {
+ GetPrivateProfileString(INI_TELNET, INI_BACKSPACE, INI_BACKSPACE_BS,
+ tmpBuf, sizeof(tmpBuf), TELNET_INI);
+ if (_stricmp(tmpBuf, INI_BACKSPACE_DEL) == 0)
+ bs = 0x7f;
+ else
+ bs = VK_BACK;
+ }
+
+ strcpy(buf, tmpConfig->title);
+ strcat(buf, ", ");
+ if (bs == VK_BACK)
+ strcat(buf, INI_BACKSPACE_BS);
+ else
+ strcat(buf, INI_BACKSPACE_DEL);
+
+ WritePrivateProfileString(INI_HOSTS, INI_HOST "0", buf, TELNET_INI);
+ n = 1;
+ for (iHostNum = 0; iHostNum < nhosts; iHostNum++) {
+ strcpy(tmpName, hostName[iHostNum]);
+ tmpCommaLoc = strchr(tmpName, ',');
+ if (tmpCommaLoc) {
+ *tmpCommaLoc = '\0';
+ while (tmpCommaLoc[1] == ' ')
+ tmpCommaLoc++;
+ }
+ if (strcmp(tmpName, host) != 0) {
+ wsprintf(tmpBuf, INI_HOST "%d", n++);
+ WritePrivateProfileString(INI_HOSTS, tmpBuf, hostName[iHostNum],
+ TELNET_INI);
+ }
+ }
+ return (bs);
+}
+
+/*+*/
+int
+OpenTelnetConnection(void) {
+ int nReturn, ret;
+ struct sockaddr_in sockaddr;
+ char *p;
+ static struct kstream_crypt_ctl_block ctl;
+ char buf[128];
+
+ hGlobalMem = GlobalAlloc(GPTR, sizeof(CONFIG));
+ tmpConfig = (CONFIG *) GlobalLock(hGlobalMem);
+
+ if (bAutoConnection) {
+ hTitleMem = GlobalAlloc(GPTR, lstrlen(szAutoHostName));
+ tmpConfig->title = (char *) GlobalLock(hTitleMem);
+ lstrcpy(tmpConfig->title, (char *) szAutoHostName);
+ } else {
+ nReturn = DoDialog("OPENTELNETDLG", OpenTelnetDlg);
+ if (nReturn == FALSE) return(FALSE);
+ }
+
+ con = (CONNECTION *) GetNewConnection();
+ if (con == NULL) return(0);
+
+ tmpConfig->width = GetPrivateProfileInt(INI_TELNET, INI_WIDTH,
+ DEF_WIDTH, TELNET_INI);
+ tmpConfig->height = GetPrivateProfileInt(INI_TELNET, INI_HEIGHT,
+ DEF_HEIGHT, TELNET_INI);
+ con->width = tmpConfig->width;
+ con->height = tmpConfig->height;
+
+ con->backspace = SaveHostName(tmpConfig->title);
+
+ if (con->backspace == VK_BACK) {
+ tmpConfig->backspace = TRUE;
+ con->ctrl_backspace = 0x7f;
+ } else {
+ tmpConfig->backspace = FALSE;
+ con->ctrl_backspace = 0x08;
+ }
+
+ tmpConfig->hwndTel = hWnd;
+ con->hScreen = (HSCREEN) InitNewScreen((CONFIG *) tmpConfig);
+ if (!(con->hScreen)) {
+ OutputDebugString("Failed to initialize new screen! \r\n");
+ GlobalUnlock(con->hScreen);
+ GlobalUnlock(ghCon);
+ GlobalFree(ghCon);
+ GlobalUnlock(hGlobalMem);
+ GlobalFree(hGlobalMem);
+ return(-1);
+ }
+
+ ret = (SOCKET) socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if (ret == SOCKET_ERROR) {
+ wsprintf(buf, "Socket error on socket = %d!", WSAGetLastError());
+ MessageBox(NULL, buf, NULL, MB_OK|MB_ICONEXCLAMATION);
+ fpScr = (SCREEN *) GlobalLock(con->hScreen);
+ if (fpScr != NULL)
+ DestroyWindow(fpScr->hWnd);
+ GlobalUnlock(con->hScreen);
+ GlobalUnlock(ghCon);
+ GlobalFree(ghCon);
+ GlobalUnlock(hGlobalMem);
+ GlobalFree(hGlobalMem);
+ return(-1);
+ }
+
+ con->socket = ret;
+
+ sockaddr.sin_family = AF_INET ;
+ sockaddr.sin_addr.s_addr = htonl( INADDR_ANY );
+ sockaddr.sin_port = htons( 0 ) ;
+
+ ret = bind(con->socket, (struct sockaddr *) &sockaddr,
+ (int) sizeof(struct sockaddr_in));
+
+ if (ret == SOCKET_ERROR) {
+ wsprintf(buf, "Socket error on bind!");
+ MessageBox(NULL, buf, NULL, MB_OK|MB_ICONEXCLAMATION);
+ fpScr = (SCREEN *) GlobalLock(con->hScreen);
+ if (fpScr != NULL)
+ DestroyWindow(fpScr->hWnd);
+ GlobalUnlock(con->hScreen);
+ GlobalUnlock(ghCon);
+ GlobalFree(ghCon);
+ GlobalUnlock(hGlobalMem);
+ GlobalFree(hGlobalMem);
+ return(-1);
+ }
+ WSAAsyncSelect(con->socket, hWnd, WM_NETWORKEVENT,
+ FD_READ | FD_CLOSE | FD_CONNECT);
+
+ lstrcpy(szHostName, tmpConfig->title);
+ p = strchr(szHostName, '@');
+ if (p != NULL) {
+ *p = 0;
+ strcpy (szUserName, szHostName);
+ strcpy(szHostName, ++p);
+ }
+
+ WSAAsyncGetHostByName(hWnd, WM_HOSTNAMEFOUND, szHostName, hostdata,
+ MAXGETHOSTSTRUCT);
+ GlobalUnlock(con->hScreen);
+// GlobalUnlock(ghCon);
+// GlobalFree(ghCon);
+ GlobalUnlock(hGlobalMem);
+ GlobalFree(hGlobalMem);
+
+ ctl.encrypt = auth_encrypt;
+ ctl.decrypt = auth_decrypt;
+ ctl.init = auth_init;
+ ctl.destroy = auth_destroy;
+
+ con->ks = kstream_create_from_fd(con->socket, &ctl, NULL);
+
+ kstream_set_buffer_mode(con->ks, 0);
+
+ if (con->ks == NULL)
+ return(-1);
+
+ return(1);
+}
+
+/*+*/
+CONNECTION *
+GetNewConnection(void) {
+ CONNECTION *fpCon;
+
+ ghCon = GlobalAlloc(GHND, sizeof(CONNECTION));
+ if (ghCon == NULL) return NULL;
+ fpCon = (CONNECTION *) GlobalLock(ghCon);
+ if (fpCon == NULL) return NULL;
+ fpCon->backspace = TRUE;
+ fpCon->bResizeable = TRUE;
+ return(fpCon);
+}
+
+/*+***************************************************************************/
+int NEAR
+DoDialog(char *szDialog, FARPROC lpfnDlgProc) {
+ int nReturn;
+
+ lpfnDlgProc = MakeProcInstance(lpfnDlgProc, hInst);
+ if (lpfnDlgProc == NULL)
+ MessageBox(hWnd, "Couldn't make procedure instance", NULL, MB_OK);
+
+ nReturn = DialogBox(hInst, szDialog, hWnd, lpfnDlgProc);
+ FreeProcInstance(lpfnDlgProc);
+ return (nReturn);
+}
+
+/*+***************************************************************************
+
+ FUNCTION: OpenTelnetDlg(HWND, unsigned, WORD, LONG)
+
+ PURPOSE: Processes messages for "Open New Telnet Connection" dialog box
+
+ MESSAGES:
+
+ WM_INITDIALOG - initialize dialog box
+ WM_COMMAND - Input received
+
+****************************************************************************/
+
+BOOL FAR PASCAL
+OpenTelnetDlg(HWND hDlg, WORD message, WORD wParam, LONG lParam) {
+ char szConnectName[256];
+ HDC hDC;
+ int xExt, yExt;
+ DWORD Ext;
+ HWND hEdit;
+ int nLen;
+ int iHostNum = 0;
+ char tmpName[128], tmpBuf[80];
+ char *tmpCommaLoc;
+
+ switch (message) {
+ case WM_INITDIALOG: /* message: initialize dialog box */
+ hDC = GetDC(hDlg);
+ Ext = GetDialogBaseUnits();
+ xExt = (190 *LOWORD(Ext)) /4 ;
+ yExt = (72 * HIWORD(Ext)) /8 ;
+ GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", tmpName,
+ 128, TELNET_INI);
+ if (tmpName[0]) {
+ tmpCommaLoc = strchr(tmpName, ',');
+ if (tmpCommaLoc)
+ *tmpCommaLoc = '\0';
+ SetDlgItemText(hDlg, TEL_CONNECT_NAME, tmpName);
+ }
+ hEdit = GetWindow(GetDlgItem(hDlg, TEL_CONNECT_NAME), GW_CHILD);
+ while (TRUE) {
+ wsprintf(tmpBuf, INI_HOST "%d", iHostNum++);
+ GetPrivateProfileString(INI_HOSTS, tmpBuf, "", tmpName,
+ 128, TELNET_INI);
+ tmpCommaLoc = strchr(tmpName, ',');
+ if (tmpCommaLoc)
+ *tmpCommaLoc = '\0';
+ if (tmpName[0])
+ SendDlgItemMessage(hDlg, TEL_CONNECT_NAME, CB_ADDSTRING, 0,
+ (LPARAM) ((LPSTR) tmpName));
+ else
+ break;
+ }
+ SetWindowPos(hDlg, NULL, (GetSystemMetrics(SM_CXSCREEN)/2)-(xExt/2),
+ (GetSystemMetrics(SM_CYSCREEN)/2)-(yExt/2), 0, 0,
+ SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW);
+ ReleaseDC(hDlg, hDC);
+ SendMessage(hEdit, WM_USER+1, NULL, NULL);
+ SendMessage(hDlg, WM_SETFOCUS, NULL, NULL);
+ return (TRUE);
+
+ case WM_COMMAND: /* message: received a command */
+ switch (wParam) {
+ case TEL_CANCEL:
+ EndDialog(hDlg, FALSE); /* Exits the dialog box */
+ break;
+
+ case TEL_OK:
+ GetDlgItemText(hDlg, TEL_CONNECT_NAME, szConnectName, 256);
+ nLen = lstrlen(szConnectName);
+ if (nLen == 0) {
+ MessageBox(hDlg, "You must enter a session name!",
+ NULL, MB_OK);
+ break;
+ }
+ hTitleMem = GlobalAlloc(GPTR, nLen);
+ tmpConfig->title = (char *) GlobalLock(hTitleMem);
+ lstrcpy(tmpConfig->title, szConnectName);
+ EndDialog(hDlg, TRUE);
+ break;
+ }
+ return (FALSE);
+ }
+ return (FALSE); /* Didn't process a message */
+}
+
+/*+***************************************************************************
+
+ FUNCTION: TelnetSend(kstream ks, char *buf, int len, int flags)
+
+ PURPOSE: This is a replacement for the WinSock send() function, to
+ send a buffer of characters to an output socket. It differs
+ by retrying endlessly if sending the bytes would cause
+ the send() to block. <gnu@cygnus.com> observed EWOULDBLOCK
+ errors when running using TCP Software's PC/TCP 3.0 stack,
+ even when writing as little as 109 bytes into a socket
+ that had no more than 9 bytes queued for output. Note also that
+ a kstream is used during output rather than a socket to facilitate
+ encryption.
+
+ Eventually, for cleanliness and responsiveness, this
+ routine should not loop; instead, if the send doesn't
+ send all the bytes, it should put them into a buffer
+ and return. Message handling code would send out the
+ buffer whenever it gets an FD_WRITE message.
+
+****************************************************************************/
+
+int
+TelnetSend(kstream ks, char *buf, int len, int flags) {
+
+ int writelen;
+ int origlen = len;
+
+ while (TRUE) {
+ writelen = kstream_write(ks, buf, len);
+
+ if (writelen == len) /* Success, first or Nth time */
+ return (origlen);
+
+ if (writelen == SOCKET_ERROR) {
+ if (WSAGetLastError() != WSAEWOULDBLOCK)
+ return (SOCKET_ERROR); /* Some error */
+ /* For WOULDBLOCK, immediately repeat the send. */
+ }
+ else {
+ /* Partial write; update the pointers and retry. */
+ len -= writelen;
+ buf += writelen;
+ }
+ }
+}
--- /dev/null
+; module-definition file for testdll -- used by LINK.EXE
+NAME telnet ; application's module name
+
+DESCRIPTION 'Sample Microsoft Windows Application'
+
+EXETYPE WINDOWS ; required for all Windows applications
+
+STUB 'WINSTUB.EXE' ; Generates error message if application
+ ; is run without Windows
+
+;CODE can be moved in memory and discarded/reloaded
+CODE PRELOAD MOVEABLE
+;DISCARDABLE
+
+;DATA must be MULTIPLE if program can be invoked more than once
+DATA PRELOAD MOVEABLE
+
+
+HEAPSIZE 10240
+
+; All functions that will be called by any Windows routine
+; MUST be exported.
+
+EXPORTS
+ MainWndProc @1 ; name of window processing function
+ OpenTelnetDlg @3 ; name of "Open New Telnet Connection" Dialog Function
+
+IMPORTS
+ WINSOCK.WSAStartup
+ WINSOCK.WSACleanup
+ WINSOCK.WSAAsyncSelect
+ WINSOCK.WSAGetLastError
+ WINSOCK.WSAAsyncGetHostByName
+ WINSOCK.listen
+ WINSOCK.accept
+ WINSOCK.__wsafdisset
+ WINSOCK.socket
+ WINSOCK.bind
+ WINSOCK.gethostbyname
+ WINSOCK.getsockname
+ WINSOCK.htons
+ WINSOCK.connect
+ WINSOCK.recv
+ WINSOCK.send
+ WINSOCK.htonl
+ WINSOCK.closesocket
+ WINSOCK.select
+ WINSOCK.ioctlsocket
+ WINSOCK.getpeername
--- /dev/null
+DLGINCLUDE RCDATA DISCARDABLE
+BEGIN
+ "DIALOG.H\0"
+END
+
+OPENTELNETDLG DIALOG 63, 65, 175, 51
+STYLE DS_ABSALIGN | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Open New Telnet Connection"
+FONT 8, "MS Sans Serif"
+BEGIN
+ CONTROL "To Host:", -1, "STATIC", NOT WS_GROUP, 3, 10, 33, 10
+ CONTROL "", TEL_CONNECT_NAME, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_GROUP | WS_TABSTOP, 42, 9, 128, 60
+ CONTROL "OK", TEL_OK, "BUTTON", WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON, 27, 30, 51, 14
+ CONTROL "Cancel", TEL_CANCEL, "BUTTON", WS_TABSTOP, 97, 30, 51, 14
+END
+
+ABOUTBOX DIALOG 69, 33, 175, 148
+STYLE DS_ABSALIGN | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
+CAPTION "About TCPwin"
+BEGIN
+ ICON "NCSA", -1, 15, 12, 16, 16
+ CTEXT "Microsoft Windows", -1, 48, 11, 93, 8
+ CTEXT "NCSA TCP/IP Networking Kernel", -1, 38, 21, 120, 8
+ CTEXT "Version 1.0b2", -1, 20, 31, 144, 8
+ CONTROL "OK", IDOK, "BUTTON", WS_GROUP, 72, 126, 39, 14
+ CTEXT "Written By:", 606, 20, 50, 144, 8
+ CTEXT "Jon Mittelhauser (jonm@ncsa.uiuc.edu)", 607, 20, 61, 144, 8
+ CTEXT "Chris Wilson (cwilson@ncsa.uiuc.edu)", 608, 20, 71, 144, 8
+ CTEXT "Special Thanks to:", 609, 21, 97, 143, 8
+ CTEXT "Joe Lepore for DPMI interface code", 610, 20, 107, 144, 8
+ CTEXT "Keberized by: Cygnus Support", 611, 20, 82, 144, 8
+END
+
+CONFIG_DLG DIALOG 6, 18, 160, 130
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Configure Session"
+FONT 8, "MS Sans Serif"
+BEGIN
+ LTEXT "Session Name:", 301, 1, 5, 54, 8
+ LTEXT "Default Session", CON_SESSIONNAME, 55, 5, 105, 8
+ LTEXT "Window Title:", 303, 1, 17, 49, 8
+ EDITTEXT CON_WINDOWTITLE, 53, 15, 102, 12, ES_AUTOHSCROLL
+ CONTROL "132", CON_COLUMNS132, "Button", BS_AUTORADIOBUTTON |
+ WS_GROUP, 53, 33, 39, 10
+ CONTROL "80", CON_COLUMNS80, "Button", BS_AUTORADIOBUTTON, 110,
+ 33, 39, 10
+ CONTROL "Backspace", CON_BACKSPACE, "Button", BS_AUTORADIOBUTTON |
+ WS_GROUP, 53, 46, 49, 10
+ CONTROL "Delete", CON_DELETE, "Button", BS_AUTORADIOBUTTON, 110,
+ 46, 39, 10
+ CONTROL "CRLF", CON_CRLF, "Button", BS_AUTORADIOBUTTON |
+ WS_GROUP, 53, 59, 39, 10
+ CONTROL "CR-NUL", CON_CRNUL, "Button", BS_AUTORADIOBUTTON, 110,
+ 59, 39, 10
+ CONTROL "Buffers", CON_BUFFERS, "Button", BS_AUTORADIOBUTTON |
+ WS_GROUP, 53, 72, 39, 10
+ CONTROL "Sends", CON_SENDS, "Button", BS_AUTORADIOBUTTON, 110,
+ 72, 39, 10
+ LTEXT "Columns", 313, 1, 33, 49, 8
+ LTEXT "Backspace is", 314, 1, 46, 51, 8
+ LTEXT "Return Sends", 315, 1, 59, 49, 8
+ LTEXT "Echo Mode", 316, 1, 72, 49, 8
+ CONTROL "Scrollback", CON_SCRLBCK, "Button", BS_AUTOCHECKBOX |
+ WS_TABSTOP, 1, 86, 50, 10
+ EDITTEXT CON_NUMLINES, 53, 85, 28, 12, ES_AUTOHSCROLL
+ LTEXT "lines", 319, 85, 86, 33, 8
+ DEFPUSHBUTTON "OK", CON_OK, 20, 108, 50, 14, WS_GROUP
+ PUSHBUTTON "Use Defaults", CON_USEDEFAULTS, 90, 108, 50, 14
+END
+
+IDM_PRINTQUEUE DIALOG 69, 25, 160, 80
+STYLE WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION |
+ WS_VSCROLL | WS_HSCROLL | WS_SYSMENU
+CAPTION "Print Queue"
+FONT 8, "MS Sans Serif"
+BEGIN
+END
--- /dev/null
+#ifndef TELNET_H_INC
+#define TELNET_H_INC
+
+#include <windows.h>
+#include <stdarg.h>
+
+#ifdef KRB5
+#include "krb5.h"
+#include "k5stream.h"
+#endif
+
+#include "dialog.h"
+#include "screen.h"
+#include "struct.h"
+#include "wt-proto.h"
+#include "winsock.h"
+#include "ini.h"
+
+/* globals */
+extern char szAutoHostName[64];
+extern char szUserName[64];
+extern char szHostName[64];
+
+#ifdef KRB5
+ extern krb5_context k5_context;
+#endif
+
+extern void parse(CONNECTION *con,unsigned char *st,int cnt);
+extern void send_naws(CONNECTION *con);
+extern char __near strTmp[];
+
+#define DEF_WIDTH 80
+#define DEF_HEIGHT 24
+
+#endif /* TELNET_H_INC */
+
--- /dev/null
+#include <windows.h>
+#include "dialog.h"
+#include "telnet.dlg"
+#include "screen.h"
+
+NCSA ICON ncsa.ico
+TERMINAL ICON terminal.ico
+
+ScreenMenu MENU
+BEGIN
+ POPUP "&Configure"
+ BEGIN
+ MENUITEM "&Backspace", IDM_BACKSPACE, CHECKED
+ MENUITEM "&Delete", IDM_DELETE
+ MENUITEM SEPARATOR
+ MENUITEM "&Font...", IDM_FONT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "&Copy Cltr+Ins",IDM_COPY
+ MENUITEM "&Paste Shift+Ins", IDM_PASTE
+ #ifdef _DEBUG
+ MENUITEM "&Debug", IDM_DEBUG
+ #endif
+ END
+END
--- /dev/null
+/*
+* telopts.h
+* Used for telnet options
+****************************************************************************
+* *
+* *
+* NCSA Telnet *
+* by Tim Krauskopf, VT100 by Gaige Paulsen, Tek by Aaron Contorer *
+* Additions by Kurt Mahan, Heeren Pathak, & Quincey Koziol *
+* *
+* National Center for Supercomputing Applications *
+* 152 Computing Applications Building *
+* 605 E. Springfield Ave. *
+* Champaign, IL 61820 *
+* *
+****************************************************************************
+* Quincey Koziol
+* Defines for telnet options and related things
+*/
+
+#ifndef TELOPTS_H
+#define TELOPTS_H
+
+#define NUMLMODEOPTIONS 30
+
+/* Definitions for telnet protocol */
+
+#define STNORM 0
+
+/* Definition of the lowest telnet byte following an IAC byte */
+#define LOW_TEL_OPT 236
+
+#define TEL_EOF 236
+#define SUSP 237
+#define ABORT 238
+
+#define SE 240
+#define NOP 241
+#define DM 242
+#define BREAK 243
+#define IP 244
+#define AO 245
+#define AYT 246
+#define EC 247
+#define EL 248
+#define GOAHEAD 249
+#define SB 250
+#define WILLTEL 251
+#define WONTTEL 252
+#define DOTEL 253
+#define DONTTEL 254
+#define IAC 255
+
+/* Assigned Telnet Options */
+#define BINARY 0
+#define ECHO 1
+#define RECONNECT 2
+#define SGA 3
+#define AMSN 4
+#define STATUS 5
+#define TIMING 6
+#define RCTAN 7
+#define OLW 8
+#define OPS 9
+#define OCRD 10
+#define OHTS 11
+#define OHTD 12
+#define OFFD 13
+#define OVTS 14
+#define OVTD 15
+#define OLFD 16
+#define XASCII 17
+#define LOGOUT 18
+#define BYTEM 19
+#define DET 20
+#define SUPDUP 21
+#define SUPDUPOUT 22
+#define SENDLOC 23
+#define TERMTYPE 24
+#define EOR 25
+#define TACACSUID 26
+#define OUTPUTMARK 27
+#define TERMLOCNUM 28
+#define REGIME3270 29
+#define X3PAD 30
+#define NAWS 31
+#define TERMSPEED 32
+#define TFLOWCNTRL 33
+#define LINEMODE 34
+ #define MODE 1
+ #define MODE_EDIT 1
+ #define MODE_TRAPSIG 2
+ #define MODE_ACK 4
+ #define MODE_SOFT_TAB 8
+ #define MODE_LIT_ECHO 16
+
+ #define FORWARDMASK 2
+
+ #define SLC 3
+ #define SLC_DEFAULT 3
+ #define SLC_VALUE 2
+ #define SLC_CANTCHANGE 1
+ #define SLC_NOSUPPORT 0
+ #define SLC_LEVELBITS 3
+
+ #define SLC_ACK 128
+ #define SLC_FLUSHIN 64
+ #define SLC_FLUSHOUT 32
+
+ #define SLC_SYNCH 1
+ #define SLC_BRK 2
+ #define SLC_IP 3
+ #define SLC_AO 4
+ #define SLC_AYT 5
+ #define SLC_EOR 6
+ #define SLC_ABORT 7
+ #define SLC_EOF 8
+ #define SLC_SUSP 9
+ #define SLC_EC 10
+ #define SLC_EL 11
+ #define SLC_EW 12
+ #define SLC_RP 13
+ #define SLC_LNEXT 14
+ #define SLC_XON 15
+ #define SLC_XOFF 16
+ #define SLC_FORW1 17
+ #define SLC_FORW2 18
+ #define SLC_MCL 19
+ #define SLC_MCR 20
+ #define SLC_MCWL 21
+ #define SLC_MCWR 22
+ #define SLC_MCBOL 23
+ #define SLC_MCEOL 24
+ #define SLC_INSRT 25
+ #define SLC_OVER 26
+ #define SLC_ECR 27
+ #define SLC_EWR 28
+ #define SLC_EBOL 29
+ #define SLC_EEOL 30
+
+#define XDISPLOC 35
+#define ENVIRONMENT 36
+#define AUTHENTICATION 37
+#define DATA_ENCRYPTION 38
+#define XOPTIONS 255
+
+#define LINEMODE_MODES_SUPPORTED 0x1B
+/* set this flag for linemode special functions which are supported by Telnet, even though they are not currently active */
+/* This is to allow the other side to negotiate to a "No Support" state for an option */
+/* and then change later to supporting it, so we know it's ok to change our "No Support" */
+/* state to something else ("Can't Change", "Value", whatever) */
+#define SLC_SUPPORTED 0x10
+
+#define ESCFOUND 5
+#define IACFOUND 6
+#define NEGOTIATE 1
+
+#endif /* telopts.h */
+
--- /dev/null
+int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
+BOOL InitApplication(HANDLE);
+BOOL InitInstance(HANDLE, int);
+long FAR PASCAL MainWndProc(HWND, UINT, WPARAM, LPARAM);
+BOOL FAR PASCAL About(HWND, WORD, WORD, LONG);
+BOOL FAR PASCAL OpenTelnetDlg(HWND, WORD, WORD, LONG);
+int TelnetSend(kstream, char *, int, int);
+BOOL FAR PASCAL ConfigSessionDlg(HWND, WORD, WORD, LONG);
+
+int OpenTelnetConnection(void);
+int NEAR DoDialog(char *szDialog, FARPROC lpfnDlgProc);
+///HCONNECTION FindConnectionFromPortNum(int ID);
+///HCONNECTION FindConnectionFromTelstate(int telstate);
+///HCONNECTION FindConnectionFromScreen(HSCREEN hScreen);
+CONNECTION * GetNewConnection(void);
+void start_negotiation(kstream ks);
+/* somewhere... */
+struct machinfo * FAR PASCAL Shostlook(char *hname);
+