(FILECREATED " 3-NOV-83 21:31:47" {SDR2020}PS:<DOLPHIN.SOURCES>VTCHAT.;30 60337 changes to: (FNS CHAT.TYPEIN) previous date: " 3-OCT-83 13:29:18" {SDR2020}PS:<DOLPHIN.SOURCES>VTCHAT.;29) (* Copyright (c) 1983 by sSCHLUMBERGER TECHNOLOGY CORPORATION) (PRETTYCOMPRINT VTCHATCOMS) (RPAQQ VTCHATCOMS ((COMS (* CHAT and its main -- typein -- process) (FNS CHAT CHAT.GODOWN CHAT.SCROLLDOWN CHAT.SMOOTHSCROLL CHAT.TAB CHAT.TAB.STOP? CHAT.TYPEIN CHAT.BIN BSPSOUT CHAT.CLOSE CHAT.DISABLE.INTERRUPTS CHAT.ENABLE.INTERRUPTS CHAT.FLASHCARET CHAT.SENDSCREENPARAMS VTCHAT.ATTRIBUTES VTCHAT.DECLFONT VTCHAT.DOCOMMAND VTCHAT.ERASE.IN.DISPLAY VTCHAT.ERASE.IN.LINE VTCHAT.ID VTCHAT.RESETMODE VTCHAT.RESTORE VTCHAT.REVERSE.INDEX VTCHAT.SAVE VTCHAT.SEQUENCE VTCHAT.SET.TAB VTCHAT.SETMARGINS VTCHAT.SETMODE VTCHAT.STATUS VTCHAT.UNDERLINE)) (COMS (* Typeout process, datamedia simulation) (FNS CHAT.TYPEOUT CHAT.HANDLECHARACTER) (FNS CHAT.ADDCHAR CHAT.ADDLINE CHAT.ADDRESS CHAT.CLEAR CHAT.CLEARMODES CHAT.DELCHAR CHAT.DELETELINE CHAT.DOWN CHAT.ERASE.TO.EOL CHAT.ERASEBITS CHAT.HOME CHAT.LEFT CHAT.NEWLINE CHAT.PRINTCHAR CHAT.RIGHT CHAT.UP) (ARRAY BITSARRAY TABARRAY)) (FNS CHAT.TYPESCRIPT) (COMS (* window stuff) (FNS CREATEWINDOWFROMBOX GETCHATWINDOW CHAT.BUTTONFN CHAT.HOLD CHAT.MENU CHAT.RESHAPEWINDOW CHAT.RESET CHAT.BEFORE.LOGOUT CHATWINDOW.ENTRYFN CHATWINDOW.EXITFN)) (COMS (* BSP hackers) (FNS CHAT.ERRORHANDLER CHAT.HANDLEMARK CHAT.PUPHANDLER CHAT.IMMEDIATE.PUPHANDLER)) (INITVARS (CHAT.CONTROLCHAR 193) (CHAT.METACHAR 195) (CHAT.INTERRUPTS) (DEFAULTCHATHOST (QUOTE SDR2020)) (CHATDEBUGFLG) (CTRLC.COUNT 4) (CHATWINDOWLST) (CHAT.OLDINTERRUPTS) (CHATWINDOW) (CHAT.AUTOCRLF T) (CLOSECHATWINDOWFLG) (CHAT.ALLHOSTS)) (VARS BLINKMODE (CHATMENU) (CHAT.REOPENMENU) (CHAT.HOSTMENU) (CHATFONT (FONTCREATE (QUOTE (GACHA 12 MRR)))) (GRAPHICSFONT CHATFONT) (CHAT.DISPLAYTYPE 18)) (ADDVARS (BEFORELOGOUTFORMS (CHAT.BEFORE.LOGOUT)) (RESETFORMS (CHAT.RESET T))) (COMS (* Caret stuff) (FNS \DOWNCARET \FLIPCARET) (DECLARE: EVAL@COMPILE DONTCOPY (RECORDS CARET))) (BITMAPS ACCENTGRAVE) (DECLARE: EVAL@COMPILE DONTCOPY (RECORDS CHATUSERSTATE) (CONSTANTS * WHPUPTYPES) (CONSTANTS (\SOCKET.TELNET 1) (\SOCKET.MISCSERVICES 4)) (CONSTANTS * CHATMARKTYPES) (GLOBALVARS CHAT.CONTROLCHAR CHAT.METACHAR CHAT.DISPLAYTYPE CHAT.OLDINTERRUPTS CHATDEBUGFLG CHATMARKTYPES CHATMENU CHATWINDOW CHATWINDOWLST CTRLC.COUNT DEFAULTCHATHOST PUPTYPES CHAT.INTERRUPTS INVERTWINDOWFN WHITESHADE CHAT.AUTOCRLF CLOSECHATWINDOWFLG CHAT.HOSTMENU CHAT.ALLHOSTS) (ALISTS (PUPPRINTMACROS 152 154)) (VARS (CHAT.INTERRUPTS (QUOTE ((7 HELP))))) (LOCALVARS . T)) (INITVARS (INVERTWINDOWFN (QUOTE INVERTW))) (FILES (SYSLOAD FROM VALUEOF LISPUSERSDIRECTORIES) BSP PROC VT100KP) (VARS (\BSP.MAXPUPS 12)) (* Default is 20; this is too much) (FNS CHAT.ADD.BACKGROUND.COMMAND) (DECLARE: DONTEVAL@LOAD DOCOPY (P (CHAT.ADD.BACKGROUND.COMMAND) (PUTCHARBITMAP 96 CHATFONT ACCENTGRAVE))) (RECORDS * VTCHATRECORDS))) (* CHAT and its main -- typein -- process) (DEFINEQ (CHAT [LAMBDA (HOST LOGOPTION INITSTREAM WINDOW FROMMENU) (* bvm: "26-AUG-82 17:53") [COND ((NOT (THIS.PROCESS)) (PRIN1 "Turning on Process mechanism and trying again... " T) (COND ((READP T) (PRINTBELLS) (DISMISS 1000))) (CLEARBUF T) [BKSYSBUF (MKSTRING (CONS (QUOTE CHAT) (AND (OR HOST LOGOPTION) (CONS (KWOTE HOST) (AND LOGOPTION (CONS (KWOTE LOGOPTION] (RETEVAL (QUOTE CHAT) (QUOTE (PROCESSWORLD T] (PROG (SOCKET PORT MSG PROCESS) [OR HOST (COND [FROMMENU [SETQ HOST (MENU (OR CHAT.HOSTMENU (SETQ CHAT.HOSTMENU (create MENU ITEMS ←(APPEND (UNION (LIST DEFAULTCHATHOST) CHAT.ALLHOSTS) (QUOTE (Other))) TITLE ← "Host"] (COND ((EQ HOST (QUOTE Other)) (SETQ HOST NIL)) ((NULL HOST) (RETURN] (T (SETQ HOST DEFAULTCHATHOST] TOP [COND ((NOT HOST) (COND ([NOT (SETQ HOST (CAR (PROCESS.READ (AND FROMMENU PROMPTWINDOW) " Host: "] (RETURN] (COND ((EQ HOST (QUOTE ?)) (SETQ MSG "Enter name of host to chat to, or NIL to abort")) [(NOT (SETQ PORT (ETHERPORT HOST))) (SETQ MSG (CONS HOST (QUOTE (not found] ([NOT (SETQ SOCKET (CREATEBSPSTREAM (COND ((ZEROP (CDR PORT)) (* No socket given, use normal telnet socket) (CONS (CAR PORT) \SOCKET.TELNET)) (T PORT)) (FUNCTION CHAT.IMMEDIATE.PUPHANDLER) (FUNCTION CHAT.ERRORHANDLER] (SETQ MSG "failed")) (T (SETQ WINDOW (GETCHATWINDOW (SETQ HOST (\CANONICAL.HOSTNAME HOST)) WINDOW)) (COND ((NOT (FMEMB HOST CHAT.ALLHOSTS)) (SETQ CHAT.ALLHOSTS (CONS HOST CHAT.ALLHOSTS)) (SETQ CHAT.HOSTMENU))) [WINDOWPROP WINDOW (QUOTE CHATSTATE) (SETBSPUSERINFO SOCKET (create CHATUSERSTATE RUNNING? ← T SYNCHCOUNT ← 0 CARETSTATE ←(create CARET CARETDS ←(WINDOWPROP WINDOW (QUOTE DSP] (* Need to store this info with the socket as well so that the error handler can get at it) (WINDOWPROP WINDOW (QUOTE SOCKET) SOCKET) [WINDOWPROP WINDOW (QUOTE PROCESS) (SETQ PROCESS (ADD.PROCESS (LIST (QUOTE CHAT.TYPEIN) SOCKET WINDOW (KWOTE LOGOPTION) (KWOTE HOST) (KWOTE INITSTREAM)) (PACK* "CHAT#" HOST] (WINDOWPROP WINDOW (QUOTE CHATHOST) (CONS HOST LOGOPTION)) (PROCESS.WINDOW PROCESS WINDOW) (WINDOWPROP WINDOW (QUOTE PROCESS.ENTRYFN) (FUNCTION CHATWINDOW.ENTRYFN)) (WINDOWPROP WINDOW (QUOTE PROCESS.EXITFN) (FUNCTION CHATWINDOW.EXITFN)) (PROCESS.SWITCH.TO.WINDOW WINDOW) (* transfer control to the chat window) (OR FROMMENU (\SYSBUFP)) (* This will cause us to block until we are reselected--hack to keep us from printing our return value and LISPXID in the wrong place. Eventually we need window holding conditions) (RETURN HOST))) (SETQ HOST) (PRIN1 MSG (COND (FROMMENU PROMPTWINDOW) (T T))) (COND (WINDOW (RETURN))) (GO TOP) (* Want to try again) ]) (CHAT.GODOWN (LAMBDA (RPT) (* ejs: " 7-NOV-82 16:41") (* Move down RPT lines) (COND ((IGREATERP YPOS (IPLUS BOTTOMMARGIN FONTDESCENT)) (MOVETO XPOS (SETQ YPOS (IMAX (IPLUS BOTTOMMARGIN FONTDESCENT) (SETQ YPOS (IDIFFERENCE YPOS (ITIMES RPT FONTHEIGHT) )))) DSP))))) (CHAT.SCROLLDOWN (LAMBDA (TOP) (* ejs: " 8-NOV-82 08:30") (* Scroll down a line, from the line at TOP) (BITBLT DSP 0 (IPLUS BOTTOMMARGIN FONTHEIGHT) DSP 0 BOTTOMMARGIN TTYWIDTH (IDIFFERENCE TOP (IPLUS BOTTOMMARGIN FONTHEIGHT)) (QUOTE INPUT) (QUOTE REPLACE)) (CHAT.ERASEBITS 0 (IDIFFERENCE (IDIFFERENCE TOP FONTHEIGHT) FONTDESCENT) TTYWIDTH FONTHEIGHT))) (CHAT.SMOOTHSCROLL (LAMBDA NIL (* ejs: " 6-NOV-82 18:36") (for I from 1 to FONTHEIGHT do (BITBLT DSP 0 0 DSP 0 1 TTYWIDTH TTYHEIGHT (QUOTE INPUT) (QUOTE REPLACE))) (CHAT.ERASEBITS 0 0 TTYWIDTH FONTHEIGHT))) (CHAT.TAB (LAMBDA NIL (* ejs: " 7-NOV-82 15:16") (for X from (IPLUS (IQUOTIENT XPOS FONTWIDTH) 2) to (ADD1 (IQUOTIENT TTYWIDTH FONTWIDTH)) until (CHAT.TAB.STOP? X) finally (SETQ XPOS (ITIMES (SUB1 X) FONTWIDTH))) (MOVETO XPOS YPOS DSP))) (CHAT.TAB.STOP? (LAMBDA (POS) (* ejs: " 7-NOV-82 15:07") (* * Function returns T if there is a tab stop at POS) (COND ((ZEROP (LOGAND (ELT TABARRAY (LRSH POS 3)) (ELT BITSARRAY (IREMAINDER POS 8)))) NIL) (T)))) (CHAT.TYPEIN (LAMBDA (SOCKET WINDOW LOGOPTION HOST INITSTREAM) (* ejs: " 3-NOV-83 21:17") (DECLARE (SPECVARS STREAM)) (* so that menu can change it) (WINDOWPROP WINDOW (QUOTE RESHAPEFN) (FUNCTION CHAT.RESHAPEWINDOW)) (WINDOWPROP WINDOW (QUOTE BUTTONEVENTFN) (FUNCTION CHAT.BUTTONFN)) (WINDOWPROP WINDOW (QUOTE CLOSEFN) (FUNCTION CHAT.CLOSE)) (RESETSAVE (PROGN WINDOW) (QUOTE (AND RESETSTATE (CHAT.CLOSE OLDVALUE 0)))) (* If an error occurs, process is killed, or HARDRESET happens, this will flush the connection etc) (bind (DEFAULTSTREAM ← T) (STATE ←(WINDOWPROP WINDOW (QUOTE CHATSTATE))) (CHATSTREAM ←(BSPOUTPUTSTREAM SOCKET)) (WINDOWSTREAM ←(WINDOWPROP WINDOW (QUOTE DSP))) STREAM CH first (replace TYPEOUTPROC of STATE with (ADD.PROCESS (LIST (QUOTE CHAT.TYPEOUT) SOCKET WINDOW))) (CHAT.SENDSCREENPARAMS CHATSTREAM WINDOW) (AND (NEQ LOGOPTION (QUOTE NONE)) (* CHAT.LOGIN HOST LOGOPTION CHATSTREAM STATE) ) (COND (INITSTREAM (XNLSETQ (SETQ STREAM (\GETOFD (OR (STRINGP INITSTREAM) (OPENFILE INITSTREAM (QUOTE INPUT))) (QUOTE INPUT))) NOBREAK))) do (COND ((NULL STREAM) (SETQ STREAM DEFAULTSTREAM))) (COND ((EQ STREAM T) (* Handle terminal differently. Mainly because we may be inside a blocked process's \fillbuffer, making READP think there is input. Ugh!!!) (OR (TTY.PROCESSP) (\WAIT.FOR.TTY)) (while (\SYSBUFP) do (SETQ CH (\GETKEY)) (BOUT CHATSTREAM (COND ((EQ CH CHAT.CONTROLCHAR) (* Controlify it) (LOGAND (CHAT.BIN SOCKET STATE) 31)) ((EQ CH CHAT.METACHAR) (* Prefix meta, turn on 200q bit) (LOGOR (CHAT.BIN SOCKET STATE) 128)) (T CH))))) (T (until (EOFP STREAM) do (BOUT CHATSTREAM (\BIN STREAM))) (CLOSEF STREAM) (SETQ STREAM))) (BSPFORCEOUTPUT CHATSTREAM) (CHAT.FLASHCARET STATE) (BLOCK) (SELECTQ (fetch RUNNING? of STATE) (NIL (* Connection died somehow) (while (fetch UNUSUALQ of STATE) do (BLOCK)) (* Wait for CHAT.TYPEOUT to finish. Not sure this is really necessary) (RETURN (CHAT.CLOSE WINDOW (COND ((BSPOPENP SOCKET (QUOTE OUTPUT)) 1000) (T 0))))) (CLOSE (RETURN (CHAT.CLOSE WINDOW 15000))) NIL)) (* * Get here if we close connection.) (BLOCK))) (CHAT.BIN [LAMBDA (SOCKET STATE) (* bvm: "28-APR-82 18:35") (until (\SYSBUFP) bind FIRSTTIME←T do (COND (FIRSTTIME (BSPFORCEOUTPUT SOCKET) (SETQ FIRSTTIME NIL))) (CHAT.FLASHCARET STATE) (BLOCK)) (\GETKEY]) (BSPSOUT (LAMBDA (SOCKET STR) (* ejs: " 1-APR-83 12:02") (for CH instring STR do (BSPBOUT SOCKET CH)))) (CHAT.CLOSE [LAMBDA (WINDOW TIMEOUT) (* bvm: "26-AUG-82 18:02") (* Close chat connection that is using WINDOW. Also serves as the CLOSEFN of this window, when TIMEOUT is NIL) (PROG ((CHATSTATE (WINDOWPROP WINDOW (QUOTE CHATSTATE))) PROC FILE SOCKET KEEP) (COND (CHATSTATE (SETQ SOCKET (WINDOWPROP WINDOW (QUOTE SOCKET))) (DEL.PROCESS (fetch TYPEOUTPROC of CHATSTATE)) (\DOWNCARET (fetch CARETSTATE of CHATSTATE)) (COND ((SETQ FILE (fetch TYPESCRIPTOFD of CHATSTATE)) (TERPRI WINDOW) (PRIN1 "Closing " WINDOW) (PRINT (CLOSEF FILE) WINDOW))) (ENDBSPSTREAM SOCKET (OR TIMEOUT 0)) (WINDOWPROP WINDOW (QUOTE SOCKET) NIL) (WINDOWPROP WINDOW (QUOTE CHATSTATE) NIL))) (SETQ CHATWINDOWLST (DREMOVE WINDOW CHATWINDOWLST)) (SETQ PROC (WINDOWPROP WINDOW (QUOTE PROCESS) NIL)) (* Save the process running, if any; don't do anything with it until after we close the window, if we're going to, so that windows don't flip around excessively) (WINDOWPROP WINDOW (QUOTE CLOSEFN) NIL) [COND ((AND (NOT (SETQ KEEP (WINDOWPROP WINDOW (QUOTE KEEPCHAT) NIL))) (FIXP TIMEOUT) (OR CLOSECHATWINDOWFLG (NEQ WINDOW CHATWINDOW))) (CLOSEW WINDOW)) (T (* Change title to indicate closure) (PROG [(TITLE (WINDOWPROP WINDOW (QUOTE TITLE] (WINDOWPROP WINDOW (QUOTE TITLE) (CONCAT (SUBSTRING TITLE 1 (SUB1 (OR (STRPOS ", height" TITLE) 0))) ", closed"] (OR (CDR CHATWINDOWLST) (SETQ CHATWINDOWLST)) [COND ((EQ KEEP (QUOTE NEW)) (* Invoked via the New command -- start up a new connection in this window) (ADD.PROCESS (LIST (QUOTE CHAT) NIL NIL NIL WINDOW T] (COND (PROC (* Do this last, because if we are PROC, DEL.PROCESS won't return) (DEL.PROCESS PROC]) (CHAT.DISABLE.INTERRUPTS [LAMBDA NIL (* bvm: "24-AUG-81 00:08") (DECLARE (GLOBALVARS \CURRENTINTERRUPTS CHAT.OLDINTERRUPTS CHAT.INTERRUPTS)) (* Turns off interrupts and returns a list of things to feed to INTERRUPTCHAR to turn them back on) (OR CHAT.OLDINTERRUPTS (PROG1 [SETQ CHAT.OLDINTERRUPTS (for PAIR in (APPEND \CURRENTINTERRUPTS) collect (INTERRUPTCHAR (CAR PAIR] (* Turn everything off, then turn selected interrupts back on) (MAPC CHAT.INTERRUPTS (FUNCTION INTERRUPTCHAR]) (CHAT.ENABLE.INTERRUPTS [LAMBDA NIL (* bvm: "21-AUG-81 16:20") (MAPC CHAT.OLDINTERRUPTS (FUNCTION INTERRUPTCHAR)) (SETQ CHAT.OLDINTERRUPTS]) (CHAT.FLASHCARET [LAMBDA (CHATSTATE) (* bvm: "23-SEP-81 12:16") (OR (fetch HELD of CHATSTATE) (\FLIPCARET (fetch CARETSTATE of CHATSTATE]) (CHAT.SENDSCREENPARAMS [LAMBDA (SOCKET WINDOW) (* bvm: "31-DEC-00 16:33") (* * Sends screen width, height to partner) (PROG [(HEIGHT (IMIN [IQUOTIENT (WINDOWPROP WINDOW (QUOTE HEIGHT)) (IABS (DSPLINEFEED NIL (WINDOWPROP WINDOW (QUOTE DSP] 127)) (WIDTH (IMIN (LINELENGTH NIL WINDOW) 127)) (TITLE (WINDOWPROP WINDOW (QUOTE TITLE] (BSPPUTMARK SOCKET \MARK.TERMTYPE) (BSPBOUT SOCKET CHAT.DISPLAYTYPE) (* Terminal type of "display") (BSPPUTMARK SOCKET \MARK.PAGELENGTH) (BSPBOUT SOCKET HEIGHT) (BSPPUTMARK SOCKET \MARK.LINEWIDTH) (BSPBOUT SOCKET WIDTH) (WINDOWPROP WINDOW (QUOTE TITLE) (CONCAT (SUBSTRING TITLE 1 (SUB1 (OR (STRPOS ", height" TITLE) 0))) ", height = " HEIGHT ", width = " WIDTH]) (VTCHAT.ATTRIBUTES (LAMBDA (ATTRARRAY ATTRCOUNT) (* ejs: " 8-NOV-82 10:15") (* * Function to do character attribute setting) (for A from 1 to ATTRCOUNT do (SELECTQ (ELT ATTRARRAY A) (0 (DSPFONT PLAINFONT DSP) (DSPSOURCETYPE (QUOTE INPUT) DSP) (SETQ UNDERLINEMODE NIL)) (1 (DSPFONT (OR CHATBOLDFONT (SETQ CHATBOLDFONT (FONTCOPY PLAINFONT (QUOTE WEIGHT) (QUOTE BOLD)))) DSP)) ((4 5) (SETQ UNDERLINEMODE T)) (7 (DSPSOURCETYPE (QUOTE INVERT) DSP)) NIL)))) (VTCHAT.DECLFONT (LAMBDA (CHAR) (* ejs: "11-JUL-83 12:28") (DECLARE (USEDFREE FONTDECL SIFONT SOFONT GRAPHICSFONT CHATFONT ESCAPESEQUENCE CURRENTFONT WINDOW) ) (SET (SELECTC FONTDECL ((CHARCODE %() (QUOTE SIFONT)) ((CHARCODE %)) (QUOTE SOFONT)) (QUOTE SOFONT)) (SELECTC CHAR ((CHARCODE A) CHATFONT) ((CHARCODE B) CHATFONT) (48 GRAPHICSFONT) CHATFONT)) (DSPFONT (EVAL CURRENTFONT) WINDOW) (SETQ FONTDECL NIL) (SETQ ESCAPESEQUENCE NIL))) (VTCHAT.DOCOMMAND (LAMBDA (CHAR SOCKET) (* ejs: "18-APR-83 13:32") (* * Function called when an escape or control sequence has been terminated by CHAR) (DECLARE (USEDFREE CSTERM ESCAPESEQUENCE)) (PROG (STAYESCAPE (PARAM1 (COND ((ZEROP ESCAPESEQUENCE) 0) (T (ELT PARAMARRAY 1)))) (PARAM2 (COND ((ILESSP ESCAPESEQUENCE 2) 0) (T (ELT PARAMARRAY 2))))) (SELCHARQ CHAR (%[ (* ESC-LeftBracket is the control sequence introducer) (SETQ CSTERM 64) (SETQ ESCAPESEQUENCE 1) (SETQ STAYESCAPE T) (SETA PARAMARRAY 1 0)) (7 (* Save parameters) (VTCHAT.SAVE)) (8 (* Restore parameters) (VTCHAT.RESTORE)) (A (* Move up; param1 indicates how far) (CHAT.UP (COND ((ZEROP PARAM1) 1) (T PARAM1)))) (B (* Move down; param1 indicates how far) (CHAT.GODOWN (COND ((ZEROP PARAM1) 1) (T PARAM1)))) (C (* Move right; param1 indicates how far) (CHAT.RIGHT (COND ((ZEROP PARAM1) 1) (T PARAM1)))) (D (* Move left; param1 indicates how far) (COND ((ZEROP ESCAPESEQUENCE) (CHAT.DOWN)) (T (CHAT.LEFT (COND ((ZEROP PARAM1) 1) (T PARAM1)))))) (E (* Do CRLF) (MOVETO (SETQ XPOS 0) YPOS DSP) (CHAT.DOWN)) (H (* Cursor addressing) (COND ((ZEROP ESCAPESEQUENCE) (VTCHAT.SET.TAB)) (T (CHAT.ADDRESS (COND ((OR (ZEROP PARAM1) (NULL PARAM1)) 1) (T PARAM1)) (COND ((OR (ZEROP PARAM2) (NULL PARAM2)) 1) (T PARAM2)))))) (J (* Erase in display; param1 indicates mode) (VTCHAT.ERASE.IN.DISPLAY (COND ((OR (ZEROP PARAM1) (NULL PARAM1)) 0) (T PARAM1)))) (K (* Erase in line; param1 indicates mode) (VTCHAT.ERASE.IN.LINE (COND ((OR (ZEROP PARAM1) (NULL PARAM1)) 0) (T PARAM1)))) (M (* Reverse Index) (VTCHAT.REVERSE.INDEX)) (Z (* What are you?) (VTCHAT.ID SOCKET)) (< NIL) (= (* Enter keypad application mode) (VTCHAT.KPAPPLMODE T)) (> (* Leave keypad application mode) (VTCHAT.KPAPPLMODE NIL)) (c (* What are you?) (VTCHAT.ID SOCKET)) (f (* Cursor addressing) (CHAT.ADDRESS (COND ((OR (ZEROP PARAM1) (NULL PARAM1)) 1) (T PARAM1)) (COND ((OR (ZEROP PARAM2) (NULL PARAM2)) 1) (T PARAM2)))) (h (* Set modes) (VTCHAT.SETMODE PARAMARRAY ESCAPESEQUENCE)) (l (* Reset mode) (VTCHAT.RESETMODE PARAMARRAY ESCAPESEQUENCE)) (m (* Set char attributes) (VTCHAT.ATTRIBUTES PARAMARRAY ESCAPESEQUENCE)) (n (* Status report) (VTCHAT.STATUS PARAM1 SOCKET)) (r (* Set scrolling margins) (VTCHAT.SETMARGINS (COND ((ZEROP PARAM1) 1) (T PARAM1)) (COND ((ZEROP PARAM2) 24) (T PARAM2)))) (COND ((ZEROP ESCAPESEQUENCE) (printout PROMPTWINDOW "ESC " (CHARACTER CHAR) T)) (T (printout PROMPTWINDOW "ESC[" PARAM1 ";" PARAM2 " " (CHARACTER CHAR) T)))) (OR STAYESCAPE (SETQ ESCAPESEQUENCE NIL))))) (VTCHAT.ERASE.IN.DISPLAY (LAMBDA (PARAM) (* ejs: " 6-NOV-82 16:12") (* Do erasing functions) (SELECTQ PARAM (0 (* Erase to end of screen) (CHAT.ERASE.TO.EOL) (CHAT.ERASEBITS 0 0 TTYWIDTH (IDIFFERENCE YPOS FONTDESCENT))) (1 (* Erase from HOME to current position) (CHAT.ERASEBITS 0 (IPLUS YPOS FONTHEIGHT) TTYWIDTH (IDIFFERENCE HOMEPOS (IPLUS YPOS FONTHEIGHT))) (CHAT.ERASEBITS 0 (IDIFFERENCE YPOS FONTDESCENT) XPOS FONTHEIGHT)) (2 (* Erase screen) (CLEARW WINDOW) (MOVETO XPOS YPOS DSP)) NIL))) (VTCHAT.ERASE.IN.LINE (LAMBDA (PARAM) (* ejs: " 6-NOV-82 16:21") (* Do line-oriented erasing) (SELECTQ PARAM (0 (* Erase to end-of-line) (CHAT.ERASE.TO.EOL)) (1 (* Erase from beginning of line to current pos) (CHAT.ERASEBITS 0 (IDIFFERENCE YPOS FONTDESCENT) XPOS FONTHEIGHT)) (2 (* Erase entire line) (CHAT.ERASEBITS 0 (IDIFFERENCE YPOS FONTDESCENT) TTYWIDTH FONTHEIGHT)) NIL))) (VTCHAT.ID (LAMBDA (SOCKET) (* ejs: " 1-APR-83 13:12") (* Identify self as base vt100 -- how degrading) (BSPSOUT SOCKET "[?1;2c"))) (VTCHAT.RESETMODE (LAMBDA (MODEARRAY SETCOUNT) (* ejs: "18-APR-83 13:47") (* Does mode resetting) (for M from 1 to SETCOUNT do (SELECTQ (ELT MODEARRAY M) (1 (WINDOWPROP WINDOW (QUOTE CURSORMODE) NIL)) (4 (SETQ SMOOTHSCROLL NIL)) (5 (COND (INVERTFLG (INVERTW WINDOW) (SETQ INVERTFLG NIL) (DSPTEXTURE WHITESHADE DSP) (DSPOPERATION (QUOTE REPLACE) DSP)))) (6 (SETQ RELORIGIN NIL) (CHAT.ADDRESS 1 1)) NIL)))) (VTCHAT.RESTORE (LAMBDA NIL (* ejs: " 1-APR-83 11:39") (* * Function to restor cursor, etc from storage) (AND VT100MEM (PROGN (MOVETO (SETQ XPOS (CAR (fetch (VT100SAVE CURSORPOS) of VT100MEM))) (SETQ YPOS (CDR (fetch (VT100SAVE CURSORPOS) of VT100MEM))) DSP) (DSPFONT (CAR (fetch (VT100SAVE CHARATTR) of VT100MEM)) DSP) (SETQ UNDERLINEMODE (CADR (fetch (VT100SAVE CHARATTR) of VT100MEM))) (DSPSOURCETYPE (CADDR (fetch (VT100SAVE CHARATTR) of VT100MEM)))) ))) (VTCHAT.REVERSE.INDEX (LAMBDA NIL (* ejs: " 8-NOV-82 08:24") (COND ((ILESSP YPOS (IDIFFERENCE TOPMARGIN FONTHEIGHT)) (MOVETO XPOS (SETQ YPOS (IMIN (IDIFFERENCE TOPMARGIN FONTHEIGHT) (IPLUS YPOS (ITIMES FONTHEIGHT RPT)))) DSP)) (T (CHAT.SCROLLDOWN TOPMARGIN))))) (VTCHAT.SAVE (LAMBDA NIL (* ejs: " 1-APR-83 11:39") (* * Function to save current curpos position, graphic rendition, and character set) (OR VT100MEM (SETQ VT100MEM (create VT100SAVE))) (replace (VT100SAVE CURSORPOS) of VT100MEM with (create POSITION XCOORD ← XPOS YCOORD ← YPOS)) (replace (VT100SAVE CHARATTR) of VT100MEM with (LIST FONT UNDERLINEMODE (DSPSOURCETYPE NIL DSP))))) (VTCHAT.SEQUENCE (LAMBDA (CHAR SOCKET) (* ejs: "11-JUL-83 11:56") (* Here when an ESC has been seen) (DECLARE (USEDFREE CSTERM PARAMARRAY ESCAPESEQUENCE FONTDECL)) (PROG (TEMP) (COND ((IGREATERP CHAR CSTERM) (VTCHAT.DOCOMMAND CHAR SOCKET)) (T (COND ((ZEROP ESCAPESEQUENCE) (SELECTC CHAR ((CHARCODE %() (SETQ FONTDECL CHAR) (SETQ ESCAPESEQUENCE 1) (SETQ CSTERM (CHARCODE B))) ((CHARCODE %)) (SETQ FONTDECL CHAR) (SETQ ESCAPESEQUENCE 1) (SETQ CSTERM (CHARCODE B))) (printout PROMPTWINDOW "Bad ESCAPESEQUENCE--CHAR is " (CHARACTER CHAR) T))) (T (COND (FONTDECL (VTCHAT.DECLFONT CHAR)) (T (SELCHARQ CHAR ((0 1 2 3 4 5 6 7 8 9) (SETQ TEMP (IPLUS (ITIMES 10 (ELT PARAMARRAY ESCAPESEQUENCE)) (IDIFFERENCE CHAR 48))) (SETA PARAMARRAY ESCAPESEQUENCE TEMP)) (; (SETQ ESCAPESEQUENCE (ADD1 ESCAPESEQUENCE)) (SETA PARAMARRAY ESCAPESEQUENCE 0)) NIL)))))))))) (VTCHAT.SET.TAB (LAMBDA NIL (* ejs: " 7-NOV-82 15:20") (* * Function to set tab stop at current XPOS) (PROG ((POS (ADD1 (IQUOTIENT XPOS FONTWIDTH)))) (SETA TABARRAY (LRSH POS 3) (LOGOR (ELT TABARRAY (LRSH POS 3)) (ELT BITSARRAY (IREMAINDER POS 8))))))) (VTCHAT.SETMARGINS (LAMBDA (TOP BOTTOM) (* ejs: " 8-NOV-82 08:16") (* * Function to set top and bottom margins) (SETQ TOPMARGIN (IDIFFERENCE HOMEPOS (ITIMES (IDIFFERENCE TOP 2) FONTHEIGHT))) (SETQ BOTTOMMARGIN (IDIFFERENCE (IDIFFERENCE HOMEPOS (ITIMES (SUB1 BOTTOM) FONTHEIGHT)) FONTDESCENT)))) (VTCHAT.SETMODE (LAMBDA (MODEARRAY SETCOUNT) (* ejs: "18-APR-83 13:47") (* Does mode setting) (for M from 1 to SETCOUNT do (SELECTQ (ELT MODEARRAY M) (1 (WINDOWPROP WINDOW (QUOTE CURSORMODE) T)) (4 (SETQ SMOOTHSCROLL T)) (5 (COND ((NULL INVERTFLG) (SETQ INVERTFLG T) (INVERTW WINDOW) (DSPOPERATION (QUOTE ERASE) DSP) (DSPTEXTURE BLACKSHADE DSP)))) (6 (SETQ RELORIGIN T) (CHAT.ADDRESS 1 1)) NIL)))) (VTCHAT.STATUS (LAMBDA (TYPE SOCKET) (* ejs: " 1-APR-83 11:50") (* Returns VT100 status info) (SELECTQ TYPE (5 (* Host wants device status) (BSPSOUT SOCKET "[0n")) (6 (* Host wants cursor coords) (BSPBOUT SOCKET (CHARCODE ↑%[)) (BSPBOUT SOCKET (CHARCODE %[)) (BSPSOUT SOCKET (MKSTRING (ADD1 (IQUOTIENT YPOS FONTHEIGHT)))) (BSPBOUT SOCKET (CHARCODE ;)) (BSPSOUT SOCKET (MKSTRING (ADD1 (IQUOTIENT XPOS FONTWIDTH)))) (BSPBOUT SOCKET (CHARCODE R))) NIL))) (VTCHAT.UNDERLINE (LAMBDA (CHAR) (* ejs: " 8-NOV-82 09:33") (BITBLT DSP XPOS (IDIFFERENCE YPOS 2) DSP XPOS (SUB1 YPOS) (CHARWIDTH CHAR FONT) 1 (QUOTE INVERT) (QUOTE REPLACE)))) ) (* Typeout process, datamedia simulation) (DEFINEQ (CHAT.TYPEOUT (LAMBDA (SOCKET WINDOW) (* ejs: "11-JUL-83 12:23") (DECLARE (SPECVARS WINDOW DSP OUTSTREAM DINGED EATLF EATCRLF EATTOCRLF AUTOLF TTYWIDTH TTYHEIGHT XPOS YPOS ADDRESSING FONTWIDTH FONTHEIGHT FONTDESCENT FONT PLAINFONT CHATBOLDFONT HOMEPOS PARAMARRAY PARAMCOUNT ESCAPESEQUENCE SMOOTHSCROLL BLINKMODE RELORIGIN INVERTFLG TOPMARGIN BOTTOMMARGIN CSTERM UNDERLINEMODE VT100MEM SIFONT SOFONT FONTDECL CURRENTFONT)) (bind (STATE ←(WINDOWPROP WINDOW (QUOTE CHATSTATE))) (DSP ←(WINDOWPROP WINDOW (QUOTE DSP))) (XPOS ← 0) (YPOS ← 0) HOMEPOS FONTDECL (CURRENTFONT ←(QUOTE SIFONT)) (CNT ← 1) (OUTSTREAM ←(\GETOFD WINDOW (QUOTE OUTPUT))) (SIFONT ← CHATFONT) (SOFONT ← GRAPHICSFONT) TYPESCRIPTSTREAM TTYWIDTH TTYHEIGHT DINGED CH COM CARET ADDRESSING EATLF EATCRLF EATTOCRLF AUTOLF UNDERLINEMODE FONT CHATBOLDFONT PLAINFONT FONTWIDTH FONTHEIGHT FONTDESCENT PARAMCOUNT ESCAPESEQUENCE BLINKMODE (VT100MEM ←(create VT100SAVE (SETQ CURSORPOS (create POSITION (SETQ XCOORD 1) (SETQ YCOORD 1))))) (PARAMARRAY ←(ARRAY 12 (QUOTE FIXP) 0 1)) SMOOTHSCROLL RELORIGIN INVERTFLG TOPMARGIN (BOTTOMMARGIN ← 0) CSTERM first (push (fetch (CHATUSERSTATE UNUSUALQ) of STATE) (QUOTE FIRST)) (* Hack to initialize) (SETQ CARET (fetch CARETSTATE of STATE)) while T do (SETQ CH (BSPBIN SOCKET)) (while (fetch HELD of STATE) do (BLOCK)) (\DOWNCARET CARET) (while (fetch (CHATUSERSTATE UNUSUALQ) of STATE) do (SETQ COM (pop (fetch (CHATUSERSTATE UNUSUALQ) of STATE))) (COND ((LITATOM COM) (* Reset state) (SETQ TYPESCRIPTSTREAM (fetch TYPESCRIPTOFD of STATE)) (SETQ FONTHEIGHT (IMINUS (DSPLINEFEED NIL DSP))) (SETQ FONTWIDTH (CHARWIDTH (CHARCODE A) (SETQ PLAINFONT (SETQ FONT (DSPFONT NIL DSP))))) (SETQ FONTDESCENT (FONTPROP FONT (QUOTE DESCENT))) (SETQ TTYWIDTH (WINDOWPROP WINDOW (QUOTE WIDTH))) (SETQ TTYWIDTH (ITIMES (IQUOTIENT TTYWIDTH FONTWIDTH) FONTWIDTH)) (* Make TTYWIDTH multiple of FONTWIDTH) (SETQ TTYHEIGHT (WINDOWPROP WINDOW (QUOTE HEIGHT))) (SETQ HOMEPOS (IPLUS (ITIMES (SUB1 (IQUOTIENT TTYHEIGHT FONTHEIGHT)) FONTHEIGHT) FONTDESCENT)) (SETQ TOPMARGIN (IPLUS HOMEPOS FONTHEIGHT)) (COND ((EQ COM (QUOTE FIRST)) (CHAT.HOME)))) (T (CHAT.PUPHANDLER COM SOCKET OUTSTREAM)))) (* Handle any error pups etc that came in while we were asleep) (COND ((IGEQ CH 0) (* Normal char) (COND ((IGREATERP (fetch SYNCHCOUNT of STATE) 0) (* In the middle of flushing output from a synch) ) (T (CHAT.HANDLECHARACTER CH SOCKET))) (COND (TYPESCRIPTSTREAM (\BOUT TYPESCRIPTSTREAM CH)))) (T (SELECTQ CH (-1 (* Mark byte) (CHAT.HANDLEMARK SOCKET STATE OUTSTREAM)) ((-2 -3) (* Dead) (COND ((EQ CH -2) (PRIN1 " [Connection closed by remote host] " OUTSTREAM))) (while T do (* Wait to be killed) (replace UNUSUALQ of STATE with NIL) (* flush any errors that come along, so CHAT.TYPEIN doesn't wait on us) (BLOCK))) (printout OUTSTREAM "[Unknown: " CH "]")))) (COND (CHATDEBUGFLG (COND ((OR (EQ CHATDEBUGFLG T) (IGREATERP (add CNT 1) CHATDEBUGFLG)) (BLOCK) (SETQ CNT 1)))))))) (CHAT.HANDLECHARACTER (LAMBDA (CHAR SOCKET) (* ejs: "11-JUL-83 14:26") (DECLARE (USEDFREE WINDOW DSP OUTSTREAM DINGED EATLF EATCRLF EATTOCRLF AUTOLF TTYWIDTH TTYHEIGHT XPOS YPOS ADDRESSING IDMODE ROLLMODE BLINKMODE FONT PLAINFONT CHATBOLDFONT FONTWIDTH FONTHEIGHT FONTDESCENT HOMEPOS)) (* Here and/or below) (PROG NIL (COND ((EQ CHAR (CHARCODE BELL)) (RETURN (COND ((NOT DINGED) (APPLY* INVERTWINDOWFN WINDOW) (* Complement window) (SETQ DINGED T)))))) (COND (DINGED (APPLY* INVERTWINDOWFN WINDOW) (SETQ DINGED NIL))) (COND ((EQ CHAR (CHARCODE ↑%[)) (SETQ AUTOLF NIL))) (SELCHARQ CHAR ((LF ↑L ↑K) (* Line Feed) (CHAT.DOWN)) (↑I (* Tab) (CHAT.TAB)) (CR (* Carriage return) (SETQ EATTOCRLF NIL) (CHAT.NEWLINE T)) (BS (* Back space) (CHAT.LEFT 1)) ((↑X ↑Z) (* Cancel --resets modes) (CHAT.CLEARMODES)) (↑N (DSPFONT SOFONT WINDOW) (SETQ CURRENTFONT (QUOTE SOFONT)) (* SO - character set switch) ) (↑O (DSPFONT SIFONT WINDOW) (SETQ CURRENTFONT (QUOTE SIFONT)) (* SI - character set switch) ) (↑%[ (* ESC Leadin) (SETQ ESCAPESEQUENCE 0) (SETQ CSTERM 48)) (COND ((IGEQ CHAR (CHARCODE SPACE)) (* Normal char) (COND (ESCAPESEQUENCE (VTCHAT.SEQUENCE CHAR SOCKET)) (T (SETQ EATLF (SETQ EATCRLF NIL)) (RETURN (COND ((AND (NEQ CHAR (CHARCODE DEL)) (NOT EATTOCRLF)) (* Print the char) (CHAT.PRINTCHAR CHAR)))))))))))) ) (DEFINEQ (CHAT.ADDCHAR [LAMBDA NIL (* bvm: "28-APR-82 21:46") (* Insert a space at cursor position, pushing rest of line to right) (PROG ((Y (IDIFFERENCE YPOS FONTDESCENT))) (BITBLT DSP XPOS Y DSP (IPLUS XPOS FONTWIDTH) Y (IPLUS (IDIFFERENCE TTYWIDTH XPOS) FONTWIDTH) FONTHEIGHT (QUOTE INPUT) (QUOTE REPLACE)) (* Blt remainder of line to the right by FONTWIDTH, then erase the character under the cursor) (CHAT.ERASEBITS XPOS Y FONTWIDTH FONTHEIGHT]) (CHAT.ADDLINE [LAMBDA (ATYPOS) (* bvm: "28-APR-82 18:19") (OR ATYPOS (SETQ ATYPOS YPOS)) (* To insert line at ATYPOS, we blt everything below it down one, then clear the line at ATYPOS) (BITBLT DSP 0 FONTHEIGHT DSP 0 0 TTYWIDTH (IDIFFERENCE ATYPOS FONTDESCENT) (QUOTE INPUT) (QUOTE REPLACE)) (CHAT.ERASEBITS 0 (IDIFFERENCE ATYPOS FONTDESCENT) TTYWIDTH FONTHEIGHT]) (CHAT.ADDRESS (LAMBDA (ROW COLUMN) (* ejs: " 6-NOV-82 18:27") (* Do absolute positioning) (COND (RELORIGIN (SETQ ROW (IPLUS ROW TOPMARGIN)) (COND ((ILESSP ROW TOPMARGIN) (SETQ ROW TOPMARGIN)) ((IGREATERP ROW BOTTOMMARGIN) (SETQ ROW BOTTOMMARGIN))))) (MOVETO (SETQ XPOS (IMIN (ITIMES (SUB1 COLUMN) FONTWIDTH) (IDIFFERENCE TTYWIDTH FONTWIDTH))) (SETQ YPOS (IMAX FONTDESCENT (IDIFFERENCE HOMEPOS (ITIMES (SUB1 ROW) FONTHEIGHT)))) DSP) T)) (CHAT.CLEAR [LAMBDA (SETROLL) (* bvm: "28-APR-82 16:26") (CLEARW WINDOW) (CHAT.CLEARMODES) (SETQ ROLLMODE SETROLL) (CHAT.HOME]) (CHAT.CLEARMODES [LAMBDA NIL (* bvm: "28-APR-82 16:32") (COND (BLINKMODE (* Restore normal font) (DSPFONT PLAINFONT DSP) (SETQ FONT PLAINFONT) (SETQ BLINKMODE))) (SETQ ROLLMODE (SETQ IDMODE (SETQ ADDRESSING]) (CHAT.DELCHAR [LAMBDA NIL (* bvm: "28-APR-82 21:48") (* Delete character under cursor, moving rest of line to left) (PROG ((Y (IDIFFERENCE YPOS FONTDESCENT))) (BITBLT DSP (IPLUS XPOS FONTWIDTH) Y DSP XPOS Y (IPLUS (IDIFFERENCE TTYWIDTH XPOS) FONTWIDTH) FONTHEIGHT (QUOTE INPUT) (QUOTE REPLACE)) (* Blt remainder of line to the left by FONTWIDTH, then erase the rightmost character position) (CHAT.ERASEBITS (IDIFFERENCE TTYWIDTH FONTWIDTH) Y FONTWIDTH FONTHEIGHT]) (CHAT.DELETELINE (LAMBDA (ATYPOS) (* ejs: " 8-NOV-82 07:41") (OR ATYPOS (SETQ ATYPOS YPOS)) (* To delete line at ATYPOS, we blt everything below it up one, then clear the bottom line) (BITBLT DSP 0 BOTTOMMARGIN DSP 0 (IPLUS BOTTOMMARGIN FONTHEIGHT) TTYWIDTH (IDIFFERENCE (IDIFFERENCE ATYPOS FONTDESCENT) BOTTOMMARGIN) (QUOTE INPUT) (QUOTE REPLACE)) (CHAT.ERASEBITS 0 BOTTOMMARGIN TTYWIDTH FONTHEIGHT))) (CHAT.DOWN (LAMBDA NIL (* ejs: " 7-NOV-82 16:39") (* Move down a line) (COND ((IGREATERP YPOS (IPLUS BOTTOMMARGIN FONTDESCENT)) (MOVETO XPOS (SETQ YPOS (IDIFFERENCE YPOS FONTHEIGHT)) DSP)) (T (* On bottom line in rollmode, scroll screen up one) (COND (SMOOTHSCROLL (CHAT.SMOOTHSCROLL (IDIFFERENCE TOPMARGIN FONTHEIGHT))) (T (CHAT.DELETELINE (IDIFFERENCE TOPMARGIN FONTHEIGHT)))))))) (CHAT.ERASE.TO.EOL [LAMBDA NIL (* bvm: "28-APR-82 21:16") (CHAT.ERASEBITS XPOS (IDIFFERENCE YPOS FONTDESCENT) (IDIFFERENCE TTYWIDTH XPOS) FONTHEIGHT]) (CHAT.ERASEBITS (LAMBDA (LEFT BOTTOM WIDTH HEIGHT) (* ejs: " 7-NOV-82 16:29") (BITBLT NIL NIL NIL DSP LEFT BOTTOM WIDTH HEIGHT (QUOTE TEXTURE) (QUOTE REPLACE) (COND (INVERTFLG BLACKSHADE) (T WHITESHADE))))) (CHAT.HOME [LAMBDA NIL (* bvm: "28-APR-82 16:42") (MOVETO (SETQ XPOS 0) (SETQ YPOS HOMEPOS) DSP]) (CHAT.LEFT (LAMBDA (RPT) (* ejs: " 6-NOV-82 15:00") (COND ((IGREATERP XPOS 0) (MOVETO (SETQ XPOS (IMAX 0 (IDIFFERENCE XPOS (ITIMES RPT FONTWIDTH)))) YPOS DSP))))) (CHAT.NEWLINE [LAMBDA (EXPLICIT) (* bvm: "28-APR-82 17:05") (* Do a CRLF. EXPLICIT = T means a CR was received, NIL means we did autowraparound) (MOVETO (SETQ XPOS 0) YPOS DSP) (* Do only the CR part now, saving the LF for when next char arrives) (SETQ AUTOLF T) (COND (EXPLICIT (SETQ EATLF T)) (T (SETQ EATCRLF T]) (CHAT.PRINTCHAR (LAMBDA (CHAR) (* ejs: " 8-NOV-82 09:30") (\OUTCHAR OUTSTREAM CHAR) (COND (UNDERLINEMODE (VTCHAT.UNDERLINE CHAR))) (COND ((IGEQ (add XPOS FONTWIDTH) TTYWIDTH) (* Have reached right margin, so wrap around) (COND (CHAT.AUTOCRLF (CHAT.NEWLINE)) (T (SETQ EATTOCRLF T))))))) (CHAT.RIGHT (LAMBDA (RPT) (* ejs: " 6-NOV-82 15:02") (COND ((ILESSP (IPLUS XPOS FONTWIDTH) TTYWIDTH) (SETQ XPOS (IMIN TTYWIDTH (IPLUS XPOS (ITIMES FONTWIDTH RPT)))) (MOVETO XPOS YPOS DSP))))) (CHAT.UP (LAMBDA (RPT) (* ejs: " 8-NOV-82 08:25") (COND ((ILESSP YPOS (IDIFFERENCE TOPMARGIN FONTHEIGHT)) (MOVETO XPOS (SETQ YPOS (IMIN (IDIFFERENCE TOPMARGIN FONTHEIGHT) (IPLUS YPOS (ITIMES FONTHEIGHT RPT)))) DSP))))) ) (RPAQ BITSARRAY (READARRAY 8 (QUOTE BYTE) 0)) (1 128 64 32 16 8 4 2 NIL ) (RPAQ TABARRAY (READARRAY 16 (QUOTE BYTE) 0)) (128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 128 NIL ) (DEFINEQ (CHAT.TYPESCRIPT [LAMBDA (CHATSTATE) (* bvm: "13-JUN-82 14:28") (NLSETQ (PROG ((FILE (PROCESS.READ PROMPTWINDOW "Typescript to file: " T)) OLDFILE) (COND ((AND FILE (NEQ (SETQ FILE (CAR FILE)) T)) (COND ([OR (NULL FILE) (NLSETQ (SETQ FILE (OPENFILE FILE (QUOTE OUTPUT) (QUOTE NEW] (COND ((SETQ OLDFILE (fetch TYPESCRIPTOFD of CHATSTATE)) (PRIN1 "Closing " PROMPTWINDOW) (PRINT (CLOSEF OLDFILE) PROMPTWINDOW))) [replace TYPESCRIPTOFD of CHATSTATE with (AND FILE (\GETOFD (PRIN2 FILE PROMPTWINDOW] (push (fetch UNUSUALQ of CHATSTATE) T)) (T (PRIN1 "failed" PROMPTWINDOW]) ) (* window stuff) (DEFINEQ (CREATEWINDOWFROMBOX (LAMBDA (WIDTH HEIGHT TITLE POSITION) (* ejs: "15-OCT-82 09:20") (* * This function creates a window, WIDTH by HEIGHT, at POS. If POSITION is NIL, prompts for a region using GETBOXPOSITION. Gives window title TITLE.) (PROG ((POS (OR POSITION (GETBOXPOSITION WIDTH HEIGHT)))) (RETURN (CREATEW (create REGION LEFT ←(fetch XCOORD of POS) BOTTOM ←(fetch YCOORD of POS) WIDTH ← WIDTH HEIGHT ← HEIGHT) TITLE))))) (GETCHATWINDOW (LAMBDA (HOST WINDOW) (* ejs: "14-APR-83 15:34") (* Return a window, possibly new, to run a chat connection to HOST. Uses WINDOW if possible) (PROG ((TITLE (CONCAT "Chat connection to " HOST)) DSP STATE) (COND ((AND (WINDOWP (OR WINDOW (SETQ WINDOW CHATWINDOW))) (OR (NOT (SETQ STATE (WINDOWPROP WINDOW (QUOTE CHATSTATE)))) (COND ((NOT (fetch RUNNING? of STATE)) (* Connection in CHATWINDOW is dead) (CHAT.CLOSE WINDOW) T)))) (* Old window not in use) (WINDOWPROP WINDOW (QUOTE TITLE) TITLE) (SETQ DSP (WINDOWPROP WINDOW (QUOTE DSP)))) (T (SETQ DSP (WINDOWPROP (SETQ WINDOW (CREATEWINDOWFROMBOX (ITIMES 81 (CHARWIDTH (CHARCODE A) CHATFONT)) (ITIMES 26 (FONTPROP CHATFONT (QUOTE HEIGHT))) TITLE)) (QUOTE DSP))) (DSPSCROLL T DSP) (DSPFONT CHATFONT DSP))) (DSPRESET DSP) (COND (CHATWINDOWLST (NCONC1 CHATWINDOWLST WINDOW)) (T (SETQ CHATWINDOWLST (LIST (WFROMDS (TTYDISPLAYSTREAM)) (SETQ CHATWINDOW WINDOW))))) (RETURN WINDOW)))) (CHAT.BUTTONFN [LAMBDA (WINDOW) (* bvm: " 9-AUG-81 15:16") (COND ((LASTMOUSESTATE RED) (CHAT.HOLD WINDOW)) ((LASTMOUSESTATE YELLOW) (CHAT.MENU WINDOW]) (CHAT.HOLD [LAMBDA (WINDOW) (* bvm: "23-SEP-81 12:14") (* * Toggle HOLD while button is down) (PROG [(STATE (WINDOWPROP WINDOW (QUOTE CHATSTATE] (TOTOPW WINDOW) (OR STATE (RETURN)) [COND ((NOT (fetch HELD of STATE)) (replace HELD of STATE with T) (UNINTERRUPTABLY (UNTILMOUSESTATE UP))] (replace HELD of STATE with NIL]) (CHAT.MENU (LAMBDA (WINDOW) (* ejs: "18-APR-83 14:08") (DECLARE (GLOBALVARS CHATMENU CHAT.REOPENMENU)) (* Called by YELLOW) (PROG ((SOCKET (WINDOWPROP WINDOW (QUOTE SOCKET))) STATE) (COND ((NOT SOCKET) (* No Connection here; try to reestablish) (RETURN (AND (SETQ STATE (WINDOWPROP WINDOW (QUOTE CHATHOST))) (MENU (OR CHAT.REOPENMENU (SETQ CHAT.REOPENMENU (create MENU ITEMS ←(QUOTE ((ReConnect T "Will reestablish this Chat connection"))))) )) (ADD.PROCESS (LIST (QUOTE CHAT) (KWOTE (CAR STATE)) (KWOTE (CDR STATE)) NIL WINDOW T)))))) (replace HELD of (SETQ STATE (WINDOWPROP WINDOW (QUOTE CHATSTATE))) with NIL) (BSPFORCEOUTPUT SOCKET) (replace HELD of STATE with T) (\DOWNCARET (fetch CARETSTATE of STATE)) (SELECTQ (MENU (OR CHATMENU (SETQ CHATMENU (create MENU ITEMS ←(QUOTE ((Close (QUOTE Close) "Closes the connection and returns") (Suspend (QUOTE Suspend) "Closes the connection but leaves window up") (New (QUOTE New) "Closes this connection and prompts for a new host") (Clear (QUOTE Clear) "Clears window, sets roll mode") (Freeze (QUOTE Freeze) "Holds typeout in this window until you bug it again") (Dribble (QUOTE Dribble) "Starts a typescript of window typeout") (Input (QUOTE Input) "Allows input from a file") (Keypad (QUOTE Keypad) "Brings up a VT100 Keypad window") (↑C's (QUOTE ↑C's) "Transmits several ↑C's"))))))) (Close (replace RUNNING? of STATE with (QUOTE CLOSE))) (New (replace RUNNING? of STATE with (QUOTE CLOSE)) (WINDOWPROP WINDOW (QUOTE KEEPCHAT) (QUOTE NEW))) (Suspend (replace RUNNING? of STATE with (QUOTE CLOSE)) (WINDOWPROP WINDOW (QUOTE KEEPCHAT) T)) (Clear (PROCESS.EVAL (fetch TYPEOUTPROC of STATE) (QUOTE (CHAT.CLEAR T)))) (↑C's (FRPTQ CTRLC.COUNT (BSPBOUT SOCKET (CHARCODE ↑C))) (BSPFORCEOUTPUT SOCKET)) (Freeze (* Leave in HELD state) (RETURN)) (Dribble (CHAT.TYPESCRIPT STATE)) (Keypad (GETKEYPAD)) (Input (PROG ((FILE (PROCESS.READ PROMPTWINDOW "Take input from file: " T))) (COND ((AND FILE (CAR FILE)) (SETQ FILE (CAR (COND ((NLSETQ (OPENFILE (CAR FILE) (QUOTE INPUT)))) (T (PRINT (ERRORSTRING (CAR (ERRORN))) PROMPTWINDOW) (PRINT (CADR (ERRORN)) PROMPTWINDOW) (RETURN))))))) (PROCESS.APPLY (WINDOWPROP WINDOW (QUOTE PROCESS)) (FUNCTION SET) (LIST (QUOTE STREAM) (\GETOFD FILE (QUOTE INPUT)))))) NIL) (replace HELD of STATE with NIL)))) (CHAT.RESHAPEWINDOW [LAMBDA (WINDOW OLDIMAGE OLDREGION) (* bvm: "15-JAN-82 15:24") (* RESHAPEFN for the chat window) (RESHAPEBYREPAINTFN WINDOW OLDIMAGE OLDREGION) (PROG [(SOCKET (WINDOWPROP WINDOW (QUOTE SOCKET] (COND (SOCKET (CHAT.SENDSCREENPARAMS SOCKET (WINDOWPROP WINDOW (QUOTE DSP))) (push (fetch UNUSUALQ of (WINDOWPROP WINDOW (QUOTE CHATSTATE))) T) (* Tell CHAT.TYPEOUT to reset parms) ]) (CHAT.RESET [LAMBDA (MAYBE) (* bvm: " 7-JUN-82 15:20") (* Called from RESETFORMS as a way of flushing bad stuff without using RESETLST) (COND ((OR (NOT MAYBE) (NOT #MYHANDLE#)) (CHAT.ENABLE.INTERRUPTS) (COND (CHATWINDOWLST (for W in (CDR CHATWINDOWLST) unless (EQ W CHATWINDOW) do (CLOSEW W)) (CHAT.CLOSE CHATWINDOW) (SETQ CHATWINDOWLST))) (MAP.PROCESSES (FUNCTION (LAMBDA (PROC NAME FORM) (SELECTQ (CAR FORM) ((CHAT.TYPEIN CHAT.TYPEOUT \RTP.SOCKET.PROCESS) (DEL.PROCESS PROC)) NIL]) (CHAT.BEFORE.LOGOUT [LAMBDA NIL (* bvm: "24-AUG-81 01:37") (* * called before logout, aborts chat connections) (while (CDR CHATWINDOWLST) do (CHAT.CLOSE (CADR CHATWINDOWLST) 0]) (CHATWINDOW.ENTRYFN (LAMBDA (WINDOW OLDWINDOW) (* ejs: "16-MAY-83 10:16") (* Switch to a chat window) (\CHECKCARET (TTYDISPLAYSTREAM)) (PROG ((STATE (WINDOWPROP WINDOW (QUOTE CHATSTATE)))) (COND (STATE (replace HELD of STATE with NIL))) (CHAT.DISABLE.INTERRUPTS) (KEYACTION (QUOTE -) (QUOTE ((45 96 NOLOCKSHIFT) . IGNORE))) (KEYACTION (QUOTE BS) (QUOTE ((127 127 NOLOCKSHIFT) . IGNORE))) (COND ((LASTMOUSESTATE YELLOW) (* Also do its new button function, so users don't have to bug twice) (CHAT.BUTTONFN WINDOW)))))) (CHATWINDOW.EXITFN (LAMBDA (CURWINDOW NEWWINDOW) (* ejs: "16-MAY-83 10:18") (PROG ((STATE (WINDOWPROP CURWINDOW (QUOTE CHATSTATE)))) (COND (STATE (* Switch from chat window) (\DOWNCARET (fetch CARETSTATE of STATE)))) (COND ((NOT (FMEMB NEWWINDOW (CDR CHATWINDOWLST))) (CHAT.ENABLE.INTERRUPTS) (KEYACTION (QUOTE -) (QUOTE ((45 24 NOLOCKSHIFT) . IGNORE))) (KEYACTION (QUOTE BS) (QUOTE ((1 1 LOCKSHIFT) . IGNORE)))))))) ) (* BSP hackers) (DEFINEQ (CHAT.ERRORHANDLER [LAMBDA (SOCKET ERRCODE) (* bvm: " 5-MAR-82 16:54") (SELECTQ ERRCODE (MARK.ENCOUNTERED -1) (COND ((BSPOPENP SOCKET (QUOTE BOTH)) (* non-fatal error?) (printout T "[" ERRCODE "]") -4) (T (replace RUNNING? of (GETBSPUSERINFO SOCKET) with NIL) (COND ((BSPOPENP SOCKET (QUOTE OUTPUT)) -2) (T -3]) (CHAT.HANDLEMARK [LAMBDA (SOCKET CHATSTATE TTYFILE) (* bvm: "23-SEP-81 11:59") (PROG ((MARK (BSPGETMARK SOCKET))) (SELECTC MARK (\MARK.TIMING (* For synchronization) (BSPPUTMARK SOCKET \MARK.TIMINGREPLY)) (\MARK.SYNC (* For use with Synch interrupt) (add (fetch SYNCHCOUNT of CHATSTATE) -1)) (PROGN (PRIN1 "[Mark " TTYFILE) (PRIN2 MARK TTYFILE) (PRIN1 "]" TTYFILE]) (CHAT.PUPHANDLER [LAMBDA (PUP SOCKET FILE) (* bvm: "21-SEP-81 23:57") (DECLARE (GLOBALVARS PUPTRACEFILE)) (* * called on error and non-bsp pups. CHAT.IMMEDIATE.PUPHANDLER has already filtered out interrupts and non-2 errors) (PROG (OFFSET) (COND ((SELECTC (fetch PUPTYPE of PUP) (\PT.ERROR (* For now don't filter out abort errors) (printout FILE T "[Error] ") (SETQ OFFSET 24)) (\PT.ABORT (printout FILE T "[Abort] ") (SETQ OFFSET 2)) (COND ((NEQ PUPTRACEFILE T) (PRIN1 "{Strange pup: " PUPTRACEFILE) (PRINTCONSTANT (fetch PUPTYPE of PUP) PUPTYPES PUPTRACEFILE) (PRIN1 "}" PUPTRACEFILE) NIL))) (printout FILE (\GETPUPSTRING PUP OFFSET) T))) (\RELEASE.PUP PUP]) (CHAT.IMMEDIATE.PUPHANDLER [LAMBDA (PUP SOCKET) (* bvm: "25-JUN-82 12:40") (DECLARE (GLOBALVARS PUPTRACEFILE)) (* * called on error, interrupt and non-bsp pups. Anything that we'd be inclined to print to T is queued up for CHAT.TYPEOUT to handle) (PROG ((INFO (GETBSPUSERINFO SOCKET))) (COND ((NULL INFO) (* CHAT has died. Synchrony problem that we got here at all) ) ((SELECTC (fetch PUPTYPE of PUP) (\PT.ERROR (* For now don't filter out abort errors) (COND ((EQ (fetch ERRORPUPCODE of PUP) 2) T) ((NEQ PUPTRACEFILE T) (PRINTERRORPUP PUP PUPTRACEFILE) NIL))) (\PT.INTERRUPT (* Synch. Means flush any output waiting to be processed up until the matching Synch Mark) (add (fetch SYNCHCOUNT of (GETBSPUSERINFO SOCKET)) 1) NIL) T) (change (fetch UNUSUALQ of INFO) (NCONC1 DATUM PUP))) (T (\RELEASE.PUP PUP]) ) (RPAQ? CHAT.CONTROLCHAR 193) (RPAQ? CHAT.METACHAR 195) (RPAQ? CHAT.INTERRUPTS ) (RPAQ? DEFAULTCHATHOST (QUOTE SDR2020)) (RPAQ? CHATDEBUGFLG ) (RPAQ? CTRLC.COUNT 4) (RPAQ? CHATWINDOWLST ) (RPAQ? CHAT.OLDINTERRUPTS ) (RPAQ? CHATWINDOW ) (RPAQ? CHAT.AUTOCRLF T) (RPAQ? CLOSECHATWINDOWFLG ) (RPAQ? CHAT.ALLHOSTS ) (RPAQQ BLINKMODE NIL) (RPAQQ CHATMENU NIL) (RPAQQ CHAT.REOPENMENU NIL) (RPAQQ CHAT.HOSTMENU NIL) (RPAQ CHATFONT (FONTCREATE (QUOTE (GACHA 12 MRR)))) (RPAQ GRAPHICSFONT CHATFONT) (RPAQQ CHAT.DISPLAYTYPE 18) (ADDTOVAR BEFORELOGOUTFORMS (CHAT.BEFORE.LOGOUT)) (ADDTOVAR RESETFORMS (CHAT.RESET T)) (* Caret stuff) (DEFINEQ (\DOWNCARET [LAMBDA (CARET) (* bvm: "21-SEP-81 22:47") (AND (fetch UP of CARET) (\FLIPCARET CARET T)) (* CARET:FORCEDDOWN is set so that caret will come up quickly.) (replace FORCEDDOWN of CARET with T]) (\FLIPCARET (LAMBDA (CARET FORCE) (* ejs: "31-MAR-83 16:40") (* changes the caret from on to off or off to on.) (COND ((AND (fetch CURSORBM of CARET) (OR FORCE (fetch FORCEDDOWN of CARET) (IGREATERP (CLOCK0 (fetch NOWTIME of CARET)) (fetch THENTIME of CARET)))) (UNINTERRUPTABLY (* note the time of the next change.) (* must be done without creating boxes because happens during keyboard wait.) (\BOXIPLUS (CLOCK0 (fetch THENTIME of CARET)) (fetch CARETRATE of CARET)) (replace UP of CARET with (NOT (fetch UP of CARET))) (* CARET:DOWN indicates whether caret is on or off. necessary so it can be turned off before the character is echoed) (* CARET:FORCEDDOWN indicates that the caret was taken down so that it will go back up quickly.) (replace FORCEDDOWN of CARET with NIL) (PROG ((DS (fetch CARETDS of CARET)) (CURS (fetch CURSORBM of CARET))) (BITBLT (fetch CURSORBITMAP of CURS) 0 0 DS (IDIFFERENCE (DSPXPOSITION NIL DS) (fetch CURSORHOTSPOTX of CURS)) (IDIFFERENCE (DSPYPOSITION NIL DS) (fetch CURSORHOTSPOTY of CURS)) CURSORWIDTH CURSORHEIGHT (QUOTE INPUT) (QUOTE INVERT)))))))) ) (DECLARE: EVAL@COMPILE DONTCOPY [DECLARE: EVAL@COMPILE (RECORD CARET (NOWTIME THENTIME FORCEDDOWN UP CARETDS CURSORBM CARETRATE) NOWTIME ←(CREATECELL \FIXP) THENTIME ←(CREATECELL \FIXP) CURSORBM ← \CARET CARETRATE ← \CARETRATE) ] ) (RPAQ ACCENTGRAVE (READBITMAP)) (8 14 "@@@@" "@@@@" "D@@@" "D@@@" "B@@@" "@@@@" "@@@@" "@@@@" "@@@@" "@@@@" "@@@@" "@@@@" "@@@@" "@@@@") (DECLARE: EVAL@COMPILE DONTCOPY [DECLARE: EVAL@COMPILE (RECORD CHATUSERSTATE (RUNNING? HELD CARETSTATE SYNCHCOUNT UNUSUALQ TYPESCRIPTOFD TYPEOUTPROC)) ] (RPAQQ WHPUPTYPES ((\PT.WHEREISUSER 152) (\PT.WHEREUSERRESPONSE 153) (\PT.WHEREUSERERROR 154))) (DECLARE: EVAL@COMPILE (RPAQQ \PT.WHEREISUSER 152) (RPAQQ \PT.WHEREUSERRESPONSE 153) (RPAQQ \PT.WHEREUSERERROR 154) (CONSTANTS (\PT.WHEREISUSER 152) (\PT.WHEREUSERRESPONSE 153) (\PT.WHEREUSERERROR 154)) ) (DECLARE: EVAL@COMPILE (RPAQQ \SOCKET.TELNET 1) (RPAQQ \SOCKET.MISCSERVICES 4) (CONSTANTS (\SOCKET.TELNET 1) (\SOCKET.MISCSERVICES 4)) ) (RPAQQ CHATMARKTYPES ((\MARK.SYNC 1) (\MARK.LINEWIDTH 2) (\MARK.PAGELENGTH 3) (\MARK.TERMTYPE 4) (\MARK.TIMING 5) (\MARK.TIMINGREPLY 6))) (DECLARE: EVAL@COMPILE (RPAQQ \MARK.SYNC 1) (RPAQQ \MARK.LINEWIDTH 2) (RPAQQ \MARK.PAGELENGTH 3) (RPAQQ \MARK.TERMTYPE 4) (RPAQQ \MARK.TIMING 5) (RPAQQ \MARK.TIMINGREPLY 6) (CONSTANTS (\MARK.SYNC 1) (\MARK.LINEWIDTH 2) (\MARK.PAGELENGTH 3) (\MARK.TERMTYPE 4) (\MARK.TIMING 5) (\MARK.TIMINGREPLY 6)) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (ADDTOVAR GLOBALVARS CHAT.CONTROLCHAR CHAT.METACHAR CHAT.DISPLAYTYPE CHAT.OLDINTERRUPTS CHATDEBUGFLG CHATMARKTYPES CHATMENU CHATWINDOW CHATWINDOWLST CTRLC.COUNT DEFAULTCHATHOST PUPTYPES CHAT.INTERRUPTS INVERTWINDOWFN WHITESHADE CHAT.AUTOCRLF CLOSECHATWINDOWFLG CHAT.HOSTMENU CHAT.ALLHOSTS) ) (ADDTOVAR PUPPRINTMACROS (152 CHARS) (154 CHARS)) (RPAQQ CHAT.INTERRUPTS ((7 HELP))) (DECLARE: DOEVAL@COMPILE DONTCOPY (LOCALVARS . T) ) ) (RPAQ? INVERTWINDOWFN (QUOTE INVERTW)) (FILESLOAD (SYSLOAD FROM VALUEOF LISPUSERSDIRECTORIES) BSP PROC VT100KP) (RPAQQ \BSP.MAXPUPS 12) (* Default is 20; this is too much) (DEFINEQ (CHAT.ADD.BACKGROUND.COMMAND [LAMBDA NIL (* edited: " 3-OCT-83 11:06") (DECLARE (GLOBALVARS BackgroundMenuCommands)) (OR (FASSOC (QUOTE CHAT) BackgroundMenuCommands) (push BackgroundMenuCommands (QUOTE (CHAT (COND [(THIS.PROCESS) (ADD.PROCESS (QUOTE (CHAT NIL NIL NIL NIL T] (T (ERROR "No Processes!" "" T))) "Runs a new CHAT process; prompts for host"]) ) (DECLARE: DONTEVAL@LOAD DOCOPY (CHAT.ADD.BACKGROUND.COMMAND) (PUTCHARBITMAP 96 CHATFONT ACCENTGRAVE) ) (RPAQQ VTCHATRECORDS (VT100SAVE)) [DECLARE: EVAL@COMPILE (RECORD VT100SAVE (CURSORPOS CHARATTR CHARSET)) ] (PUTPROPS VTCHAT COPYRIGHT ("sSCHLUMBERGER TECHNOLOGY CORPORATION" 1983)) (DECLARE: DONTCOPY (FILEMAP (NIL (3345 29275 (CHAT 3355 . 6797) (CHAT.GODOWN 6799 . 7205) (CHAT.SCROLLDOWN 7207 . 7665) ( CHAT.SMOOTHSCROLL 7667 . 7967) (CHAT.TAB 7969 . 8317) (CHAT.TAB.STOP? 8319 . 8619) (CHAT.TYPEIN 8621 . 11512) (CHAT.BIN 11514 . 11825) (BSPSOUT 11827 . 11987) (CHAT.CLOSE 11989 . 14276) ( CHAT.DISABLE.INTERRUPTS 14278 . 15036) (CHAT.ENABLE.INTERRUPTS 15038 . 15243) (CHAT.FLASHCARET 15245 . 15457) (CHAT.SENDSCREENPARAMS 15459 . 16356) (VTCHAT.ATTRIBUTES 16358 . 17039) (VTCHAT.DECLFONT 17041 . 17620) (VTCHAT.DOCOMMAND 17622 . 21975) (VTCHAT.ERASE.IN.DISPLAY 21977 . 22769) ( VTCHAT.ERASE.IN.LINE 22771 . 23433) (VTCHAT.ID 23435 . 23678) (VTCHAT.RESETMODE 23680 . 24300) ( VTCHAT.RESTORE 24302 . 24933) (VTCHAT.REVERSE.INDEX 24935 . 25279) (VTCHAT.SAVE 25281 . 25799) ( VTCHAT.SEQUENCE 25801 . 26982) (VTCHAT.SET.TAB 26984 . 27328) (VTCHAT.SETMARGINS 27330 . 27714) ( VTCHAT.SETMODE 27716 . 28335) (VTCHAT.STATUS 28337 . 29019) (VTCHAT.UNDERLINE 29021 . 29273)) (29326 35409 (CHAT.TYPEOUT 29336 . 33320) (CHAT.HANDLECHARACTER 33322 . 35407)) (35410 41919 (CHAT.ADDCHAR 35420 . 36098) (CHAT.ADDLINE 36100 . 36595) (CHAT.ADDRESS 36597 . 37217) (CHAT.CLEAR 37219 . 37421) ( CHAT.CLEARMODES 37423 . 37759) (CHAT.DELCHAR 37761 . 38469) (CHAT.DELETELINE 38471 . 38975) (CHAT.DOWN 38977 . 39522) (CHAT.ERASE.TO.EOL 39524 . 39751) (CHAT.ERASEBITS 39753 . 40014) (CHAT.HOME 40016 . 40184) (CHAT.LEFT 40186 . 40409) (CHAT.NEWLINE 40411 . 40947) (CHAT.PRINTCHAR 40949 . 41365) ( CHAT.RIGHT 41367 . 41626) (CHAT.UP 41628 . 41917)) (42113 42909 (CHAT.TYPESCRIPT 42123 . 42907)) ( 42935 51546 (CREATEWINDOWFROMBOX 42945 . 43489) (GETCHATWINDOW 43491 . 44763) (CHAT.BUTTONFN 44765 . 44994) (CHAT.HOLD 44996 . 45498) (CHAT.MENU 45500 . 48659) (CHAT.RESHAPEWINDOW 48661 . 49247) ( CHAT.RESET 49249 . 49954) (CHAT.BEFORE.LOGOUT 49956 . 50234) (CHATWINDOW.ENTRYFN 50236 . 50971) ( CHATWINDOW.EXITFN 50973 . 51544)) (51571 54693 (CHAT.ERRORHANDLER 51581 . 52032) (CHAT.HANDLEMARK 52034 . 52573) (CHAT.PUPHANDLER 52575 . 53479) (CHAT.IMMEDIATE.PUPHANDLER 53481 . 54691)) (55426 57246 (\DOWNCARET 55436 . 55777) (\FLIPCARET 55779 . 57244)) (59529 60019 (CHAT.ADD.BACKGROUND.COMMAND 59539 . 60017))))) STOP