(FILECREATED "24-Sep-86 02:24:14" {ERIS}<TEDIT>TEDITWINDOW.;51 150368 

      changes to:  (FNS TEDIT.DEACTIVATE.WINDOW)

      previous date: "11-Sep-86 21:04:42" {ERIS}<TEDIT>TEDITWINDOW.;50)


(* Copyright (c) 1983, 1984, 1985, 1986 by John Sybalsky & Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT TEDITWINDOWCOMS)

(RPAQQ TEDITWINDOWCOMS 
       [(FILES ATTACHEDWINDOW)
        (FNS TEDIT.CREATEW \TEDIT.CREATEW.FROM.REGION TEDIT.CURSORMOVEDFN TEDIT.CURSOROUTFN 
             TEDIT.WINDOW.SETUP TEDIT.MINIMAL.WINDOW.SETUP \TEDIT.ACTIVE.WINDOWP \TEDIT.BUTTONEVENTFN 
             \TEDIT.WINDOW.OPS \TEDIT.EXPANDFN \TEDIT.MAINW \TEDIT.PRIMARYW \TEDIT.COPYINSERTFN 
             \TEDIT.NEWREGIONFN \TEDIT.SET.WINDOW.EXTENT \TEDIT.SHRINK.ICONCREATE \TEDIT.SHRINKFN 
             \TEDIT.SPLITW \TEDIT.UNSPLITW \TEDIT.WINDOW.SETUP \SAFE.FIRST)
        (CURSORS BXCARET BXHICARET TEDIT.LINECURSOR \TEDIT.SPLITCURSOR \TEDIT.MOVESPLITCURSOR 
               \TEDIT.UNSPLITCURSOR \TEDIT.MAKESPLITCURSOR)
        (INITVARS (TEDIT.DEFAULT.WINDOW NIL))
        (GLOBALVARS TEDIT.DEFAULT.WINDOW)
        (COMS (* User-typein support)
              (FNS TEDIT.GETINPUT \TEDIT.MAKEFILENAME))
        (COMS (* Attached Prompt window support.)
              (FNS TEDIT.PROMPTPRINT TEDIT.PROMPTFLASH \TEDIT.PROMPT.PAGEFULLFN)
              (INITVARS (TEDIT.PROMPT.FONT (FONTCREATE 'GACHA 10))
                     (TEDIT.PROMPTWINDOW.HEIGHT NIL))
              (GLOBALVARS TEDIT.PROMPT.FONT TEDIT.PROMPTWINDOW.HEIGHT))
        (COMS (* Title creation and update)
              (FNS TEXTSTREAM.TITLE \TEDIT.ORIGINAL.WINDOW.TITLE \TEDIT.WINDOW.TITLE 
                   \TEXTSTREAM.FILENAME))
        (COMS (* Screen updating utilities)
              (FNS TEDIT.DEACTIVATE.WINDOW \TEDIT.REPAINTFN \TEDIT.RESHAPEFN \TEDIT.SCROLLFN))
        (COMS (* Process-world interfaces)
              (FNS \TEDIT.PROCIDLEFN \TEDIT.PROCENTRYFN \TEDIT.PROCEXITFN))
        (COMS (INITVARS (\CARETRATE 333))
              (* Caret handler; stolen from CHAT.)
              (FNS \EDIT.DOWNCARET \EDIT.FLIPCARET TEDIT.FLASHCARET \EDIT.UPCARET 
                   TEDIT.NORMALIZECARET \SETCARET \TEDIT.CARET)
              (DECLARE: EVAL@COMPILE DONTCOPY (RECORDS TEDITCARET)))
        [COMS (* Menu interfacing)
              (FNS TEDIT.ADD.MENUITEM TEDIT.DEFAULT.MENUFN TEDIT.REMOVE.MENUITEM \TEDIT.CREATEMENU 
                   \TEDIT.MENU.WHENHELDFN \TEDIT.MENU.WHENSELECTEDFN)
              (GLOBALVARS TEDIT.DEFAULT.MENU)
              [DECLARE: DONTEVAL@LOAD DOCOPY
                     (VARS (TEDIT.DEFAULT.MENU (\TEDIT.CREATEMENU (QUOTE ((Put (QUOTE Put)
                                                                               NIL
                                                                               (SUBITEMS Plain-Text 
                                                                                      Old-Format))
                                                                          (Get (QUOTE Get)
                                                                               NIL
                                                                               (SUBITEMS 
                                                                                     Unformatted% Get
                                                                                      ))
                                                                          Include Find Looks 
                                                                          Substitute Quit
                                                                          (Expanded% Menu
                                                                           (QUOTE Expanded% Menu)
                                                                           NIL
                                                                           (SUBITEMS Expanded% Menu 
                                                                                  Character% Looks 
                                                                                Paragraph% Formatting 
                                                                                  Page% Layout]
              (DECLARE: DONTEVAL@LOAD DOCOPY (P [OR (SASSOC (QUOTE TEdit)
                                                           BackgroundMenuCommands)
                                                    (NCONC1 BackgroundMenuCommands
                                                           (QUOTE (TEdit (QUOTE (TEDIT))
                                                                         
                                                                      "Opens a TEdit window for use."
                                                                         ]
                                                (SETQ BackgroundMenu NIL]
        (INITRECORDS TEDITCARET)
        (COMS (* titled icon info)
              (FILES ICONW)
              (BITMAPS TEDITICON TEDITMASK)
              (INITVARS (TEDIT.ICON.FONT (FONTCREATE (QUOTE HELVETICA)
                                                8
                                                (QUOTE BOLD)))
                     (TEDIT.ICON.TITLE.REGION (create REGION BOTTOM ← 4 LEFT ← 16 WIDTH ← 64 HEIGHT ← 
                                                     77))
                     (TEDIT.TITLED.ICON.TEMPLATE (create TITLEDICON ICON ← TEDITICON MASK ← TEDITMASK 
                                                        TITLEREG ← TEDIT.ICON.TITLE.REGION])
(FILESLOAD ATTACHEDWINDOW)
(DEFINEQ

(TEDIT.CREATEW
  [LAMBDA (PROMPT FILE PROPS)                                (* jds "23-May-85 15:19")
    (CLRPROMPT)
    (printout PROMPTWINDOW PROMPT T)
    (PROG ((PROMPT (LISTGET PROPS (QUOTE PROMPTWINDOW)))
	   (PHEIGHT 0)
	   PWINDOW REGION)
          [COND
	    ((EQ PROMPT (QUOTE DON'T)))
	    (PROMPT)
	    (T (SETQ PHEIGHT (HEIGHTIFWINDOW (ITIMES (OR (LISTGET PROPS (QUOTE PROMPTWINDOWHEIGHT))
							 TEDIT.PROMPTWINDOW.HEIGHT 1)
						     (FONTPROP TEDIT.PROMPT.FONT (QUOTE HEIGHT]
          (SETQ REGION (GETREGION 32 (IPLUS PHEIGHT 32)))
          (add (fetch HEIGHT of REGION)
	       (IMINUS PHEIGHT))
          (SETQ TEDIT.DEFAULT.WINDOW (CREATEW REGION (\TEDIT.ORIGINAL.WINDOW.TITLE FILE)))
          (CLRPROMPT)
          (OR PROMPT (GETPROMPTWINDOW TEDIT.DEFAULT.WINDOW (OR (LISTGET PROPS (QUOTE 
									       PROMPTWINDOWHEIGHT))
							       TEDIT.PROMPTWINDOW.HEIGHT 1)
				      TEDIT.PROMPT.FONT)))
    TEDIT.DEFAULT.WINDOW])

(\TEDIT.CREATEW.FROM.REGION
  [LAMBDA (REGION FILE PROPS)                                (* gbn "15-Nov-84 18:04")
    (PROG ((PROMPT (LISTGET PROPS (QUOTE PROMPTWINDOW)))
	   (PHEIGHT 0)
	   PWINDOW)
          [COND
	    ((EQ PROMPT (QUOTE DON'T)))
	    (PROMPT)
	    (T (SETQ PHEIGHT (HEIGHTIFWINDOW (ITIMES (OR (LISTGET PROPS (QUOTE PROMPTWINDOWHEIGHT))
							 TEDIT.PROMPTWINDOW.HEIGHT 1)
						     (FONTPROP TEDIT.PROMPT.FONT (QUOTE HEIGHT]
          (SETQ TEDIT.DEFAULT.WINDOW (CREATEW REGION (\TEDIT.ORIGINAL.WINDOW.TITLE FILE)))
          (WINDOWPROP TEDIT.DEFAULT.WINDOW (QUOTE TEDITCREATED)
		      T)
          (OR PROMPT (GETPROMPTWINDOW TEDIT.DEFAULT.WINDOW (OR (LISTGET PROPS (QUOTE 
									       PROMPTWINDOWHEIGHT))
							       TEDIT.PROMPTWINDOW.HEIGHT 1)
				      TEDIT.PROMPT.FONT)))
    TEDIT.DEFAULT.WINDOW])

(TEDIT.CURSORMOVEDFN
  [LAMBDA (W)                                                (* jds "31-Jul-85 20:34")
                                                             (* Watch the mouse and change the cursor to reflect the
							     region of the window it's in 
							     (line select, window split eventually?))
    (PROG ((X (LASTMOUSEX W))
	   (Y (LASTMOUSEY W))
	   (TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ)))
	   (CURSORREG (WINDOWPROP W (QUOTE TEDIT.CURSORREGION)))
	   LINE LEFT RIGHT)
          (COND
	    ((INSIDE? CURSORREG X Y)                         (* Do nothing)
	      NIL)
	    (T (SETQ LINE (\TEDIT.FIND.OVERLAPPING.LINE (for LINES inside (fetch LINES of TEXTOBJ)
							   as WINDOW inside (fetch \WINDOW
									       of TEXTOBJ)
							   when (EQ W WINDOW) do (RETURN LINES))
							Y))
	       [COND
		 (LINE (replace BOTTOM of CURSORREG with (fetch YBOT of LINE))
		       (replace HEIGHT of CURSORREG with (fetch LHEIGHT of LINE]
	       (SELECTQ (fetch MOUSEREGION of TEXTOBJ)
			[TEXT (COND
				((IGEQ X (SETQ LEFT (IDIFFERENCE (fetch WRIGHT of TEXTOBJ)
								 8)))
				  (CURSOR \TEDIT.SPLITCURSOR)
				  (replace MOUSEREGION of TEXTOBJ with (QUOTE WINDOW))
				  (replace LEFT of CURSORREG with LEFT)
				  (replace WIDTH of CURSORREG with 8))
				([ILESSP X (SETQ LEFT
					   (OR [AND LINE (COND
						      ((fetch FMTHARDCOPY
							  of (fetch LFMTSPEC of LINE))
							(FIXR (FQUOTIENT (fetch LEFTMARGIN
									    of LINE)
									 35.27778)))
						      (T (fetch LEFTMARGIN of LINE]
					       (IPLUS (fetch WLEFT of TEXTOBJ)
						      8]     (* In left margin; switch to the line-select cursor)
				  (CURSOR TEDIT.LINECURSOR)
				  (replace MOUSEREGION of TEXTOBJ with (QUOTE LINE))
				  (replace LEFT of CURSORREG with 0)
				  (replace WIDTH of CURSORREG with LEFT))
				(T (replace LEFT of CURSORREG with LEFT)
				   (replace WIDTH of CURSORREG with (IDIFFERENCE (fetch WRIGHT
										    of TEXTOBJ)
										 (IPLUS LEFT 8]
			[LINE (COND
				((IGEQ X (SETQ LEFT (IDIFFERENCE (fetch WRIGHT of TEXTOBJ)
								 8)))
				  (CURSOR \TEDIT.SPLITCURSOR)
				  (replace MOUSEREGION of TEXTOBJ with (QUOTE WINDOW))
				  (replace LEFT of CURSORREG with LEFT)
				  (replace WIDTH of CURSORREG with 8))
				[[IGEQ X (SETQ LEFT
					 (OR [AND LINE (COND
						    ((fetch FMTHARDCOPY of (fetch LFMTSPEC
									      of LINE))
						      (FIXR (FQUOTIENT (fetch LEFTMARGIN
									  of LINE)
								       35.27778)))
						    (T (fetch LEFTMARGIN of LINE]
					     (IPLUS (fetch WLEFT of TEXTOBJ)
						    8]
				  (CURSOR T)
				  (replace MOUSEREGION of TEXTOBJ with (QUOTE TEXT))
				  (replace LEFT of CURSORREG with LEFT)
				  (replace WIDTH of CURSORREG with (IDIFFERENCE (fetch WRIGHT
										   of TEXTOBJ)
										(IPLUS LEFT 8]
				(T (replace LEFT of CURSORREG with 0)
				   (replace WIDTH of CURSORREG with LEFT]
			[WINDOW (COND
				  ((IGEQ X (SETQ LEFT (IDIFFERENCE (fetch WRIGHT of TEXTOBJ)
								   8)))
				    (replace MOUSEREGION of TEXTOBJ with (QUOTE WINDOW))
				    (replace LEFT of CURSORREG with LEFT)
				    (replace WIDTH of CURSORREG with 8))
				  ([IGEQ X (SETQ LEFT
					   (OR [AND LINE (COND
						      ((fetch FMTHARDCOPY
							  of (fetch LFMTSPEC of LINE))
							(FIXR (FQUOTIENT (fetch LEFTMARGIN
									    of LINE)
									 35.27778)))
						      (T (fetch LEFTMARGIN of LINE]
					       (IPLUS (fetch WLEFT of TEXTOBJ)
						      8]
				    (CURSOR T)
				    (replace MOUSEREGION of TEXTOBJ with (QUOTE TEXT))
				    (replace LEFT of CURSORREG with LEFT)
				    (replace WIDTH of CURSORREG with (IDIFFERENCE (fetch WRIGHT
										     of TEXTOBJ)
										  LEFT)))
				  (T (CURSOR TEDIT.LINECURSOR)
				     (replace LEFT of CURSORREG with 0)
				     (replace WIDTH of CURSORREG with LEFT]
			NIL])

(TEDIT.CURSOROUTFN
  [LAMBDA (W)                                                (* jds "29-May-85 08:38")
                                                             (* Cursor leaves edit window;
							     make sure we think we're in the text region.)
    (PROG [(TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ]
          (CURSOR T)
          (replace MOUSEREGION of TEXTOBJ with (QUOTE TEXT])

(TEDIT.WINDOW.SETUP
  [LAMBDA (WINDOW TEXTOBJ TEXTSTREAM PROPS AFTERWINDOW)      (* jds " 2-Oct-85 12:34")
                                                             (* Set up the window and TEXTOBJ so they correspond, 
							     and the window is a TEDIT window.)
    (PROG ((SEL (fetch SEL of TEXTOBJ))
	   TEDITPROMPTWINDOW DS PROP TWIDTH THEIGHT)
          (OR WINDOW (\ILLEGAL.ARG WINDOW))
          (WINDOWPROP WINDOW (QUOTE BUTTONEVENTFN)
		      (FUNCTION \TEDIT.BUTTONEVENTFN))       (* Set the window up with the right mouse interfaces 
							     for TEDIT.)
          (WINDOWPROP WINDOW (QUOTE RIGHTBUTTONFN)
		      (FUNCTION \TEDIT.BUTTONEVENTFN))
          (WINDOWPROP WINDOW (QUOTE HARDCOPYFN)
		      (FUNCTION TEDIT.HARDCOPYFN))           (* Hook into the system standard hardcopy interface)
          (SETQ PROP (LISTGET PROPS (QUOTE MENU)))           (* The Command menu, or list of items for it)
          (COND
	    ((type? MENU PROP)                               (* It's a menu. just use it.)
	      (WINDOWPROP WINDOW (QUOTE TEDIT.MENU)
			  PROP))
	    (PROP                                            (* It's a list of menu items.
							     Force a new menu on next middle button.)
		  (WINDOWPROP WINDOW (QUOTE TEDIT.MENU.COMMANDS)
			      PROP)
		  (WINDOWPROP WINDOW (QUOTE TEDIT.MENU)
			      NIL)))
          (TEDIT.MINIMAL.WINDOW.SETUP WINDOW TEXTOBJ TEXTSTREAM PROPS AFTERWINDOW])

(TEDIT.MINIMAL.WINDOW.SETUP
  [LAMBDA (WINDOW TEXTOBJ TEXTSTREAM PROPS AFTERWINDOW)      (* jds " 2-Oct-85 13:09")
                                                             (* Do the absolute minimum setup so that TEXTOBJ and 
							     WINDOW know about each other.
							     Does NOT include mouse interface or scrolling.)

          (* If AFTERWINDOW is non-NIL, the new window will be placed after AFTERWINDOW in the TEXTOBJ's list.
	  This lists us maintain an ordering of windows, for splitting and unsplitting.)


    (PROG ((SEL (fetch SEL of TEXTOBJ))
	   TEDITPROMPTWINDOW DS PROP TWIDTH THEIGHT LINES OLDWINDOWS)
          (OR WINDOW (\ILLEGAL.ARG WINDOW))
          (replace (TEDITCARET TCCARETDS) of (COND
					       [(LISTP (fetch CARET of TEXTOBJ))
						 (CAR (FLAST (fetch CARET of TEXTOBJ]
					       (T (fetch CARET of TEXTOBJ)))
	     with (WINDOWPROP WINDOW (QUOTE DSP)))           (* The displaystream for flashing the caret)
          (replace SELWINDOW of TEXTOBJ with WINDOW)
          (WINDOWPROP WINDOW (QUOTE PROCESS)
		      NIL)                                   (* For the moment, this window has no process)
          (WINDOWPROP WINDOW (QUOTE TEDIT.PROPS)
		      PROPS)                                 (* Put the props on the window for others ...
							     **this should go**)
          (WINDOWPROP WINDOW (QUOTE TEXTSTREAM)
		      TEXTSTREAM)                            (* Save the text stream for the user to get at via the 
							     window.)
          (WINDOWPROP WINDOW (QUOTE TEXTOBJ)
		      TEXTOBJ)                               (* Give a handle on the TEXTOBJ for the text being 
							     edited.)
          (WINDOWPROP WINDOW (QUOTE TEDIT.CURSORREGION)
		      (LIST 0 0 0 0))                        (* Used by CursorMovedFn)
          (WINDOWPROP WINDOW (QUOTE CURSORMOVEDFN)
		      (FUNCTION TEDIT.CURSORMOVEDFN))
          (WINDOWPROP WINDOW (QUOTE CURSOROUTFN)
		      (FUNCTION TEDIT.CURSOROUTFN))
          (SETQ DS (WINDOWPROP WINDOW (QUOTE DSP)))
          (DSPRIGHTMARGIN 32767 DS)                          (* So we don't get spurious RETURNs printed out by the 
							     system)
          (SETQ OLDWINDOWS (fetch \WINDOW of TEXTOBJ))
          [replace \WINDOW of TEXTOBJ with (COND
					     [(LISTP OLDWINDOWS)
                                                             (* There are windows already.
							     Add this to the list.)
					       (COND
						 [AFTERWINDOW 
                                                             (* We know which window to put it after.
							     Put it there)
							      (RPLACD (FMEMB AFTERWINDOW OLDWINDOWS)
								      (CONS WINDOW
									    (CDR (FMEMB AFTERWINDOW 
										       OLDWINDOWS]
						 (T          (* Otherwise, just add it at the end of the list)
						    (NCONC1 OLDWINDOWS WINDOW]
					     (WINDOW (LIST WINDOW]
          (replace DISPLAYCACHE of TEXTOBJ with (CAR (\TEDIT.CREATE.LINECACHE 1)))
                                                             (* and a CACHE for creating line images for display)
          [replace DISPLAYCACHEDS of TEXTOBJ with (DSPCREATE (fetch LCBITMAP
								of (fetch DISPLAYCACHE of TEXTOBJ]
                                                             (* A displaystream for changeing the image caches)
          (DSPOPERATION (QUOTE PAINT)
			(fetch DISPLAYCACHEDS of TEXTOBJ))
          (DSPCLIPPINGREGION (create REGION
				     LEFT ← 0
				     BOTTOM ← 0
				     WIDTH ← 100
				     HEIGHT ← 15)
			     (fetch DISPLAYCACHEDS of TEXTOBJ))
                                                             (* Remember its size, too.)
          [COND
	    ((SETQ PROP (LISTGET PROPS (QUOTE REGION)))      (* The caller wants to set a region.
							     Use his)
	      (replace WTOP of TEXTOBJ with (fetch PTOP of PROP))
	      (replace WRIGHT of TEXTOBJ with (fetch RIGHT of PROP))
	      (replace WBOTTOM of TEXTOBJ with (fetch BOTTOM of PROP))
	      (replace WLEFT of TEXTOBJ with (fetch LEFT of PROP)))
	    (T                                               (* Otherwise, default to the whole window)
	       (replace WLEFT of TEXTOBJ with 0)
	       (replace WBOTTOM of TEXTOBJ with 0)
	       (replace WTOP of TEXTOBJ with (fetch HEIGHT of (DSPCLIPPINGREGION NIL DS)))
	       (replace WRIGHT of TEXTOBJ with (fetch WIDTH of (DSPCLIPPINGREGION NIL DS]
          (SETQ LINES (\SHOWTEXT TEXTOBJ NIL WINDOW))
          (WINDOWPROP WINDOW (QUOTE LINES)
		      LINES)                                 (* Display the text in the window, for later use.)
          [replace LINES of TEXTOBJ with (COND
					   [AFTERWINDOW (for LINE in (fetch LINES of TEXTOBJ)
							   as WINDOW in OLDWINDOWS
							   join (COND
								  ((EQ WINDOW AFTERWINDOW)
								    (LIST LINE LINES))
								  (T (LIST LINE]
					   ((LISTP (fetch LINES of TEXTOBJ))
					     (NCONC1 (fetch LINES of TEXTOBJ)
						     LINES))
					   (LINES (LIST LINES]
          (\FIXSEL SEL TEXTOBJ)
          (TEDIT.NORMALIZECARET TEXTOBJ SEL)
          (\SHOWSEL SEL NIL T)
          (\TEDIT.SET.WINDOW.EXTENT TEXTOBJ WINDOW)
          (\COPYSEL SEL TEDIT.SELECTION])

(\TEDIT.ACTIVE.WINDOWP
  [LAMBDA (W)                                                (* jds "16-Jul-85 15:23")

          (* Decides whether a TEdit window is really in use. The function TEDIT will set the TEXTOBJ prop of the window to T 
	  pro tem, to reserve a window. Once the TEdit has really started, the TEXTOBJ property will be a real textobj.)


    (PROG [(TEXTOBJ (OR (WINDOWPROP W (QUOTE TEXTOBJ))
			(AND (WINDOWPROP W (QUOTE TEXTSTREAM))
			     (TEXTOBJ (WINDOWPROP W (QUOTE TEXTSTREAM]
          (RETURN (COND
		    ((EQ TEXTOBJ T)                          (* Can have a TEXTOBJ of T as a placeholder during 
							     creation...)
		      T)
		    (TEXTOBJ (AND (NOT (fetch EDITFINISHEDFLG of TEXTOBJ))
				  (PROCESSP (WINDOWPROP W (QUOTE PROCESS])

(\TEDIT.BUTTONEVENTFN
  [LAMBDA (W STREAM)                                                   (* jds 
                                                                           " 9-Feb-86 15:15")
                                                                           (* Handle button 
                                                                           events for a TEdit 
                                                                           window)
    (AND STREAM (SETQ STREAM (TEXTOBJ STREAM)))
    (PROG*((OSEL NIL)
           (SEL NIL)
           [TEXTOBJ (OR STREAM (WINDOWPROP W (QUOTE TEXTOBJ]
           (DS (WINDOWPROP W (QUOTE DSP)))
           USERFN
           (GLOBALSEL TEDIT.SELECTION)
           (X (LASTMOUSEX W))
           (Y (LASTMOUSEY W))
           (CLIPREGION (DSPCLIPPINGREGION NIL W))
           (SELOPERATION (QUOTE NORMAL))
           (SELFN (TEXTPROP TEXTOBJ (QUOTE SELFN)))
           (EXTENDFLG NIL)
           (OLDX -32000)
           (OLDY -32000)
           SELFINALFN PROC NOSEL)
     (COND
        ((NOT (MOUSESTATE (OR LEFT MIDDLE RIGHT)))                         (* No button is down 
                                                                           -- we got control on 
                                                                           button-up transition, 
                                                                           so ignore it.)
         (RETURN))
        (TEDIT.SELPENDING                                                  (* There is already a 
                                                                           selection in progress.
                                                                           Don't allow another to 
                                                                           interfere.)
               (RETURN)))
     (replace CH# of TEDIT.SCRATCHSELECTION with 0)            (* Mark the 
                                                                           user-visible scratch 
                                                                           selection fresh, so 
                                                                           changes can be 
                                                                           detected...)
     (COND
        [[OR (NOT TEXTOBJ)
             (fetch EDITFINISHEDFLG of TEXTOBJ)
             (AND (NOT (WINDOWPROP W (QUOTE PROCESS)))
                  (NOT (TEXTPROP TEXTOBJ (QUOTE READONLY)))
                  (NOT (SHIFTDOWNP (QUOTE SHIFT)))
                  (NOT (SHIFTDOWNP (QUOTE CTRL)))
                  (NOT (SHIFTDOWNP (QUOTE META)))
                  (NOT (KEYDOWNP (QUOTE MOVE)))
                  (NOT (KEYDOWNP (QUOTE COPY]                              (* There's no edit 
                                                                           session behind this 
                                                                           window. You can only do 
                                                                           window ops, or 
                                                                           re-establish a session.)
         (TOTOPW W)
         (COND
            ((\TEDIT.MOUSESTATE RIGHT)                                     (* Right button gets 
                                                                           the window command menu)
             (DOWINDOWCOM W))
            ((AND TEXTOBJ (NOT (TEXTPROP TEXTOBJ (QUOTE READONLY)))
                  (NOT (TEXTPROP TEXTOBJ (QUOTE SELECTONLY)))
                  [NOT (PROCESSP (WINDOWPROP W (QUOTE PROCESS]
                  (\TEDIT.MOUSESTATE MIDDLE))                              (* Middle button on a 
                                                                           dead window gives a 
                                                                           menu for re-starting 
                                                                           TEDIT)
             (COND
                ((EQ (MENU TEDIT.RESTART.MENU)
                     (QUOTE NewEditProcess))
                 (replace EDITOPACTIVE of TEXTOBJ with NIL)
                 (TEDIT (fetch STREAMHINT of TEXTOBJ)
                        W]
        [(IGREATERP Y (fetch TOP of CLIPREGION))                   (* It's not inside 
                                                                           the window's REAL 
                                                                           region, so call on a 
                                                                           menu.)
         (TOTOPW W)
         (COND
            ((\TEDIT.MOUSESTATE RIGHT)
             (DOWINDOWCOM W))
            ((MOUSESTATE (OR LEFT MIDDLE))
             (AND TEXTOBJ (SETQ USERFN (WINDOWPROP W (QUOTE TEDIT.TITLEMENUFN)))
                  (NEQ USERFN (QUOTE DON'T))
                  (COND
                     ((AND (SETQ PROC (WINDOWPROP W (QUOTE PROCESS)))
                           (PROCESSP PROC))                                (* This window has a 
                                                                           live process behind it;
                                                                           go evaluate the button 
                                                                           fn there.)
                      (PROCESS.APPLY PROC USERFN (LIST W)))
                     (T                                                    (* Otherwise, create 
                                                                           a new process to handle 
                                                                           the menu.)
                        (ADD.PROCESS (LIST USERFN (KWOTE W]
        ((AND TEXTOBJ (EQ (fetch MOUSEREGION of TEXTOBJ)
                          (QUOTE WINDOW)))                                 (* We're in the 
                                                                           window-ops region of 
                                                                           the window. Do a window 
                                                                           split or something)
         (\TEDIT.WINDOW.OPS TEXTOBJ W))
        ((AND TEXTOBJ (NOT (fetch EDITOPACTIVE of TEXTOBJ)))       (* Usual case --
                                                                           he's really selecting 
                                                                           something. And there's 
                                                                           nothing else going on 
                                                                           now.)
         (TOTOPW W)                                                        (* Move the editing 
                                                                           window to the top, so 
                                                                           he can select wherever 
                                                                           he wants.)
         (\CARET.DOWN)                                                     (* Make sure the 
                                                                           caret isn't being 
                                                                           displayed.)
         [RESETLST (RESETSAVE TEDIT.SELPENDING TEXTOBJ)
            
            (* Tell all TEdits not to run, since there is a selection in progress.
            This is reset to NIL on return from here, to re-enable TEdit runs.)

                (RESETSAVE (for CARET inside (fetch CARET of TEXTOBJ)
                              do (replace TCCARET of CARET with (\CARET.CREATE 
                                                                                       BXHICARET)))
                       (LIST (QUOTE \TEDIT.CARET)
                             (fetch CARET of TEXTOBJ)))            (* Then make the 
                                                                           caret be the special, 
                                                                           tall one so he can see 
                                                                           it.)
                (COND
                   ((KEYDOWNP (QUOTE COPY))                                (* In a read-only 
                                                                           document, you can only 
                                                                           copy.)
                    (SETQ GLOBALSEL TEDIT.SHIFTEDSELECTION)
                    (SETQ OSEL (fetch SHIFTEDSEL of TEXTOBJ))
                    (SETQ SELOPERATION (QUOTE COPY)))
                   ((AND (KEYDOWNP (QUOTE MOVE))
                         (NOT (fetch TXTREADONLY of TEXTOBJ)))     (* The MOVE key is 
                                                                           down, so set MOVE mode.)
                    (SETQ GLOBALSEL TEDIT.MOVESELECTION)
                    (SETQ OSEL (fetch MOVESEL of TEXTOBJ))
                    (SETQ SELOPERATION (QUOTE MOVE)))
                   [(SHIFTDOWNP (QUOTE SHIFT))                             (* the SHIFT key is 
                                                                           down; mark this 
                                                                           selection for COPY or 
                                                                           MOVE.)
                    (COND
                       ((AND (SHIFTDOWNP (QUOTE CTRL))
                             (NOT (fetch TXTREADONLY of TEXTOBJ))) (* CTRL-SHIFT select 
                                                                           means MOVE.)
                        (SETQ GLOBALSEL TEDIT.MOVESELECTION)
                        (SETQ OSEL (fetch MOVESEL of TEXTOBJ))
                        (SETQ SELOPERATION (QUOTE MOVE)))
                       (T (SETQ GLOBALSEL TEDIT.SHIFTEDSELECTION)
                          (SETQ OSEL (fetch SHIFTEDSEL of TEXTOBJ))
                          (SETQ SELOPERATION (QUOTE COPY]
                   ((SHIFTDOWNP (QUOTE META))                              (* He's holding the 
                                                                           meta key down , do a 
                                                                           copylooks selection)
                    (SETQ GLOBALSEL TEDIT.COPYLOOKSSELECTION)
                    (SETQ OSEL (fetch SHIFTEDSEL of TEXTOBJ))
                    (SETQ SELOPERATION (QUOTE COPYLOOKS)))
                   ((AND (SHIFTDOWNP (QUOTE CTRL))
                         (NOT (fetch TXTREADONLY of TEXTOBJ)))     (* He's holding the 
                                                                           control key down;
                                                                           note the fact.)
                    (\SHOWSEL (fetch SEL of TEXTOBJ)
                           NIL NIL)
                    (SETQ GLOBALSEL TEDIT.DELETESELECTION)
                    [COND
                       ((fetch SET of (fetch DELETESEL of TEXTOBJ))
                                                                           (* There's a pending 
                                                                           delete selection.
                                                                           Use it, and turn off 
                                                                           the existing normal 
                                                                           selection.)
                        )
                       (T                                                  (* No existing delete 
                                                                           selection. Use the 
                                                                           normal selection as a 
                                                                           starting point.)
                          (\COPYSEL (fetch SEL of TEXTOBJ)
                                 (fetch DELETESEL of TEXTOBJ]
                    (replace SET of (fetch SEL of TEXTOBJ) with NIL)
                                                                           (* Remember to turn 
                                                                           off the normal 
                                                                           selection, since we'll 
                                                                           be moving it to a new 
                                                                           spot after the 
                                                                           deletion.)
                    (SETQ OSEL (fetch DELETESEL of TEXTOBJ))
                    (SETQ SELOPERATION (QUOTE DELETE))
                    (TEDIT.SET.SEL.LOOKS OSEL (QUOTE DELETE))
                    (replace BLUEPENDINGDELETE of TEXTOBJ with NIL))
                   (T (SETQ OSEL (fetch SEL of TEXTOBJ))
                      (replace BLUEPENDINGDELETE of TEXTOBJ with NIL)
                                                                           (* Reset the 
                                                                           pending-delete flag.)
                      ))
                (\COPYSEL OSEL GLOBALSEL)
                (bind (OSELOP ← SELOPERATION) while [OR (SHIFTDOWNP (QUOTE SHIFT))
                                                                (SHIFTDOWNP (QUOTE CTRL))
                                                                (SHIFTDOWNP (QUOTE META))
                                                                (KEYDOWNP (QUOTE MOVE))
                                                                (KEYDOWNP (QUOTE COPY))
                                                                (NOT (ZEROP (LOGAND LASTMOUSEBUTTONS 
                                                                                   7]
                   do                                                  (* Poll the selection 
                                                                           & display its current 
                                                                           state)
                         [COND
                            ((ZEROP (LOGAND LASTMOUSEBUTTONS 7))           (* No mouse buttons 
                                                                           are down; don't try 
                                                                           anything.)
                             (SETQ OLDX -32000)                            (* However, remember 
                                                                           that pushing a mouse 
                                                                           button is a change of 
                                                                           status that we should 
                                                                           notice.)
                             )
                            ((KEYDOWNP (QUOTE MOVE))                       (* the MOVE key is 
                                                                           down; mark this 
                                                                           selection for MOVE.)
                             (SETQ SELOPERATION (QUOTE MOVE)))
                            [(OR (SHIFTDOWNP (QUOTE SHIFT))
                                 (KEYDOWNP (QUOTE COPY)))                  (* the SHIFT key is 
                                                                           down; mark this 
                                                                           selection for COPY or 
                                                                           MOVE.)
                             (COND
                                ((SHIFTDOWNP (QUOTE CTRL))                 (* He's holding down 
                                                                           both ctrl and shift --
                                                                           do a move.)
                                 (SETQ SELOPERATION (QUOTE MOVE)))
                                (T                                         (* Just the SHIFT 
                                                                           key. It's a COPY)
                                   (SETQ SELOPERATION (QUOTE COPY]
                            ((SHIFTDOWNP (QUOTE META))                     (* He's holding the 
                                                                           meta key down;
                                                                           note the fact.)
                             (SETQ SELOPERATION (QUOTE COPYLOOKS)))
                            ((SHIFTDOWNP (QUOTE CTRL))                     (* He's holding only 
                                                                           the CTRL key --
                                                                           mark the selection for 
                                                                           deletion.)
                             (SETQ SELOPERATION (QUOTE DELETE)))
                            (T                                             (* No key being held 
                                                                           down; revert to normal 
                                                                           selection.)
                               (SETQ SELOPERATION (QUOTE NORMAL]
                         (COND
                            [(AND (OR [NOT (IEQP OLDX (SETQ X (LASTMOUSEX DS]
                                      [NOT (IEQP OLDY (SETQ Y (LASTMOUSEY DS]
                                      (NEQ OSELOP SELOPERATION))
                                  (INSIDEP CLIPREGION X Y))
            
            (* Only do selection if (1) the mouse is inside the window proper and
            (2) the mouse has moved, or the kind of selection has changed)
            
            (* Must precede the scroll-region test, so that we don't try to scroll 
            while the mouse is inside the main window, even if the scroll bar overlaps 
            the window (at left edge of screen, say))

                             (SETQ OLDX X)
                             (SETQ OLDY Y)
                             [COND
                                ((\TEDIT.MOUSESTATE LEFT)                  (* Left button is 
                                                                           character selection)
                                 (SETQ SEL (TEDIT.SELECT X Y TEXTOBJ (fetch MOUSEREGION
                                                                        of TEXTOBJ)
                                                  NIL SELOPERATION W))
                                 (SETQ EXTENDFLG NIL))
                                ((\TEDIT.MOUSESTATE MIDDLE)                (* Middle button is 
                                                                           word selection)
                                 (SETQ SEL (TEDIT.SELECT X Y TEXTOBJ (fetch MOUSEREGION
                                                                        of TEXTOBJ)
                                                  T SELOPERATION W))
                                 (SETQ EXTENDFLG NIL))
                                [(\TEDIT.MOUSESTATE RIGHT)                 (* RIght button 
                                                                           extends selections)
                                 (COND
                                    ((NEQ SELOPERATION OSELOP)
            
            (* Things changed since the last selection.
            Grab the prior selection info, so that the extension is taken from the 
            selection NOW being made, rather than the last existing old-type 
            selection.)

                                     (\COPYSEL OSEL GLOBALSEL)))
                                 (COND
                                    ((fetch SET of GLOBALSEL)
                                     (AND TEDIT.EXTEND.PENDING.DELETE (EQ SELOPERATION (QUOTE NORMAL)
                                                                          )
                                          (SETQ SELOPERATION (QUOTE PENDINGDEL))
                                          (replace BLUEPENDINGDELETE of TEXTOBJ with
                                                                                        T))
                                                                           (* If 
                                                                           TeditBluePendingDelete 
                                                                           flag is set, then 
                                                                           simulate Laurel's 
                                                                           blue-pending-delete 
                                                                           feature.)
                                     (SETQ SEL (TEDIT.EXTEND.SEL X Y GLOBALSEL TEXTOBJ SELOPERATION W
                                                      ))
                                     (SETQ EXTENDFLG T]
                                (T                                         (* The mouse buttons 
                                                                           are up, leaving us with 
                                                                           a pro-tem "permanent" 
                                                                           selection)
                                   (\COPYSEL OSEL GLOBALSEL)               (* And SEL is NOT SET 
                                                                           ANY LONGER, so it won't 
                                                                           get copied into OSEL 
                                                                           down below)
                                   (AND SEL (replace SET of SEL with NIL]
                             [COND
                                ((AND SEL (fetch SET of SEL)
                                      SELFN)                               (* The selection was 
                                                                           set, but there's a 
                                                                           SELFN that has veto 
                                                                           authority)
                                 (COND
                                    ((EQ (APPLY* SELFN TEXTOBJ SEL SELOPERATION (QUOTE TENTATIVE))
                                         (QUOTE DON'T))                    (* The selfn vetoed 
                                                                           this selection, so mark 
                                                                           it un-set.)
                                     (replace SET of SEL with NIL]
                             (COND
                                ((\TEDIT.SEL.CHANGED? SEL OSEL OSELOP SELOPERATION)
                                                                           (* Something 
                                                                           interesting about the 
                                                                           selection changed.
                                                                           We have to re-display 
                                                                           its image.)
                                 (COND
                                    ((OR (EQ SELOPERATION (QUOTE NORMAL))
                                         (EQ SELOPERATION (QUOTE PENDINGDEL)))
                                                                           (* For a normal 
                                                                           selection, set the 
                                                                           "window last selected in" 
                                                                           for the TEXTOBJ)
                                     (replace SELWINDOW of TEXTOBJ with W)))
                                 (SETQ OSEL (\TEDIT.REFRESH.SHOWSEL TEXTOBJ SEL OSEL OSELOP 
                                                   SELOPERATION EXTENDFLG))
                                 (SETQ OSELOP SELOPERATION))
                                ([AND OSEL (fetch SET of OSEL)
                                      (EQ (fetch SELKIND of OSEL)
                                          (QUOTE VOLATILE))
                                      (OR (NOT SEL)
                                          (NOT (fetch SET of SEL]
            
            (* There is an old selection around, but it is VOLATILE --
            i.e., it shouldn't last longer than something is pointing at it.
            Turn it off.)

                                 (\SHOWSEL OSEL NIL NIL)
                                 (replace SET of OSEL with NIL]
                            ((IN/SCROLL/BAR? W LASTMOUSEX LASTMOUSEY)      (* If he moves to the 
                                                                           scroll bar, let him 
                                                                           scroll without trouble)
                             (SCROLL.HANDLER W)))
                         (BLOCK)                                           (* Give other 
                                                                           processes a chance)
                         (GETMOUSESTATE)                                   (* And get the new 
                                                                           mouse info)
                         (TEDIT.CURSORMOVEDFN W))
                (\COPYSEL OSEL GLOBALSEL)
                (COND
                   ((fetch SET of OSEL)                            (* Only if a 
                                                                           selection REALLY got 
                                                                           made should we do 
                                                                           this....)
                    (SELECTQ SELOPERATION
                        (COPY                                              (* A COPY selection 
                                                                           -- set the copy flag, 
                                                                           and see if this is a 
                                                                           copy to a non-TEdit 
                                                                           window)
                              (SETQ TEDIT.COPY.PENDING T)
                              (replace SET of OSEL with NIL)   (* And turn off OSEL, 
                                                                           to avoid spurious 
                                                                           highlighting)
                              (\TEDIT.FOREIGN.COPY? GLOBALSEL)             (* Maybe copy into 
                                                                           the SYSBUF, if the 
                                                                           recipient isn't a TEdit 
                                                                           window.)
                              )
                        (COPYLOOKS                                         (* A COPYLOOKS 
                                                                           selection)
                                   (SETQ TEDIT.COPYLOOKS.PENDING T)        (* And turn off OSEL, 
                                                                           to avoid spurious 
                                                                           highlighting)
                                   (replace SET of OSEL with NIL))
                        (MOVE                                              (* A MOVE selection 
                                                                           -- set the flag to 
                                                                           signal the TEdit 
                                                                           command loop,)
                              (SETQ TEDIT.MOVE.PENDING T)                  (* And turn off OSEL, 
                                                                           to avoid spurious 
                                                                           highlighting)
                              (replace SET of OSEL with NIL))
                        (DELETE (SETQ TEDIT.DEL.PENDING T)
                                (replace SET of OSEL with NIL) (* And turn off OSEL, 
                                                                           to avoid spurious 
                                                                           highlighting)
                                )
                        (NORMAL                                            (* This is a normal 
                                                                           selection; set the 
                                                                           caret looks)
                                (replace CARETLOOKS of TEXTOBJ with (
                                                                          \TEDIT.GET.INSERT.CHARLOOKS
                                                                                 TEXTOBJ OSEL)))
                        NIL)))
                (AND SELFN (APPLY* SELFN TEXTOBJ GLOBALSEL SELOPERATION (QUOTE FINAL)))
                                                                           (* Give a user exit 
                                                                           routine control, 
                                                                           perhaps for logging of 
                                                                           selections.)
                (for CARET inside (fetch CARET of TEXTOBJ)
                   do (OR (fetch TCUP of CARET)
                              (\EDIT.FLIPCARET CARET T]
         (AND OSEL (fetch SET of OSEL)
              (fetch SELOBJ of OSEL)
              (SETQ SELFINALFN (IMAGEOBJPROP (fetch SELOBJ of OSEL)
                                      (QUOTE WHENOPERATEDONFN)))
              (APPLY* SELFINALFN (fetch SELOBJ of OSEL)
                     (WINDOWPROP W (QUOTE DSP))
                     (QUOTE SELECTED)
                     OSEL
                     (fetch STREAMHINT of TEXTOBJ])

(\TEDIT.WINDOW.OPS
  [LAMBDA (TEXTOBJ WINDOWTOSPLIT)                            (* jds "29-May-85 08:39")

          (* * Do window operations for TEdit, e.g., splitting a window, moving the split location, or unsplitting.)


    (PROG ([WINDOWOPREGION (create REGION
				   LEFT ←(DIFFERENCE (fetch WRIGHT of TEXTOBJ)
						     8)
				   BOTTOM ← 0
				   WIDTH ← 8
				   HEIGHT ←(fetch HEIGHT of (WINDOWPROP WINDOWTOSPLIT (QUOTE REGION]
	   Y OPERATION)
          [while [AND (MOUSESTATE (OR LEFT MIDDLE RIGHT))
		      (INSIDE? WINDOWOPREGION (LASTMOUSEX WINDOWTOSPLIT)
			       (SETQ Y (LASTMOUSEY WINDOWTOSPLIT]
	     do (COND
		  ((MOUSESTATE MIDDLE)
		    (CURSOR \TEDIT.MAKESPLITCURSOR)
		    (SETQ OPERATION (QUOTE SPLIT)))
		  ((MOUSESTATE LEFT)
		    (CURSOR \TEDIT.MOVESPLITCURSOR)
		    (SETQ OPERATION (QUOTE MOVE)))
		  ((MOUSESTATE RIGHT)
		    (CURSOR \TEDIT.UNSPLITCURSOR)
		    (SETQ OPERATION (QUOTE UNSPLIT]
          (COND
	    ((INSIDE? WINDOWOPREGION (LASTMOUSEX WINDOWTOSPLIT)
		      (SETQ Y (LASTMOUSEY WINDOWTOSPLIT)))
	      (CURSOR \TEDIT.SPLITCURSOR)
	      (SELECTQ OPERATION
		       (SPLIT (\TEDIT.SPLITW WINDOWTOSPLIT Y))
		       (UNSPLIT (\TEDIT.UNSPLITW WINDOWTOSPLIT))
		       (MOVE (TEDIT.PROMPTPRINT TEXTOBJ "Can't move the split point yet." T))
		       (SHOULDNT)))
	    (T (CURSOR T])

(\TEDIT.EXPANDFN
  [LAMBDA (W)                                                (* jds " 7-May-85 15:56")
                                                             (* steals back the tty for us when the TEdit window is 
							     expanded.)
    (COND
      ((WINDOWPROP W (QUOTE PROCESS))                        (* There's a process to go with this edit window.
							     Give it the TTY.)
	(TTY.PROCESS (WINDOWPROP W (QUOTE PROCESS])

(\TEDIT.MAINW
  [LAMBDA (TEXTSTREAM)                                       (* gbn " 8-Oct-84 23:31")
                                                             (* Get the MAIN edit window for this edit session 
							     (i.e., the one with the title, and all the props & 
							     stuff))
    (PROG ((TEXTOBJ (TEXTOBJ TEXTSTREAM))
	   WINDOWS WINDOW)
          (SETQ WINDOWS (fetch \WINDOW of (TEXTOBJ TEXTSTREAM)))
          (SETQ WINDOW (COND
	      ((LISTP WINDOWS)                               (* how do we know we can just take the first window as 
							     the main one?)
		(CAR WINDOWS))
	      (T WINDOWS)))
          (RETURN (COND
		    ((AND (fetch MENUFLG of TEXTOBJ)
			  (WINDOWPROP WINDOW (QUOTE MAINWINDOW)))
                                                             (* If this is a menu window, and it's attached to a 
							     main TEdit window, then look to the main TEdit window.)
		      (WINDOWPROP WINDOW (QUOTE MAINWINDOW)))
		    (T WINDOW])

(\TEDIT.PRIMARYW
  [LAMBDA (TEXTSTREAM)                                       (* jds "19-Jun-84 01:57")

          (* Given an edit session with possibly several PANES on the same document, give me the PRINCIPAL one of them--i.e., 
	  the original edit window that has all the back pointers, props &c on it.)


    (PROG ((TEXTOBJ (TEXTOBJ TEXTSTREAM))
	   WINDOWS WINDOW)
          (SETQ WINDOWS (fetch \WINDOW of (TEXTOBJ TEXTSTREAM)))
                                                             (* The edit window (s) associated with this edit 
							     session)
          (SETQ WINDOW (COND
	      ((LISTP WINDOWS)                               (* If there are several panes, the first one in the 
							     list is the original window)
		(CAR WINDOWS))
	      (T                                             (* If there's only the one window, that's the guy.)
		 WINDOWS)))
          (RETURN WINDOW])

(\TEDIT.COPYINSERTFN
  [LAMBDA (INSERTIONS WW)                                    (* jds "20-Jul-84 10:59")
                                                             (* Given a string, an imageobj, or a list of any of 
							     them, insert it in the tedit window WW.)
    (PROG [[TEXTSTREAM (TEXTSTREAM (WINDOWPROP WW (QUOTE MAINWINDOW]
	   (SEL (fetch SEL of (TEXTOBJ (WINDOWPROP WW (QUOTE MAINWINDOW]
          (for INSERTION inside INSERTIONS do (COND
						((STRINGP INSERTION)
						  (TEDIT.INSERT TEXTSTREAM INSERTION SEL))
						((IMAGEOBJP INSERTION)
						  (TEDIT.INSERT.OBJECT INSERTION TEXTSTREAM SEL])

(\TEDIT.NEWREGIONFN
  [LAMBDA (FIXEDPOINT MOVINGPOINT WINDOW)                    (* jds "24-FEB-83 17:43")

          (* This function is called whenever a new region for the window is needed. It constrains the size of the window so 
	  that the menu and/or titles will fit)


    (COND
      ((NULL MOVINGPOINT)                                    (* This is true only the first time the function is 
							     called)
	FIXEDPOINT)
      (T (PROG (#OFMENUITEMS MENUWIDTH XDELTA YDELTA)

          (* The NEWREGIONFNARG can be either a window or a list consisting of the number of items in the menu and the minimum
	  width of the window neede to hold the menu an titles)


	       (SETQ XDELTA (IDIFFERENCE (fetch (POSITION XCOORD) of MOVINGPOINT)
					 (fetch (POSITION XCOORD) of FIXEDPOINT)))
	       (SETQ YDELTA (IDIFFERENCE (fetch (POSITION YCOORD) of MOVINGPOINT)
					 (fetch (POSITION YCOORD) of FIXEDPOINT)))
	       [COND
		 [(IGEQ XDELTA 0)
		   (replace (POSITION XCOORD) of MOVINGPOINT with (IPLUS (fetch (POSITION XCOORD)
									    of FIXEDPOINT)
									 (IMAX 32 XDELTA]
		 (T (replace (POSITION XCOORD) of MOVINGPOINT with (IPLUS (fetch (POSITION XCOORD)
									     of FIXEDPOINT)
									  (IMIN -32 XDELTA]
	       [COND
		 [(IGEQ YDELTA 0)
		   (replace (POSITION YCOORD) of MOVINGPOINT with (IPLUS (fetch (POSITION YCOORD)
									    of FIXEDPOINT)
									 (IMAX 32 YDELTA]
		 (T (replace (POSITION YCOORD) of MOVINGPOINT with (IPLUS (fetch (POSITION YCOORD)
									     of FIXEDPOINT)
									  (IMIN -32 YDELTA]
	       (RETURN MOVINGPOINT])

(\TEDIT.SET.WINDOW.EXTENT
  [LAMBDA (TEXTOBJ WINDOWS)                                  (* jds " 8-May-85 17:46")
                                                             (* Set the window's EXTENT property according to 1st 
							     and last char on screen.)
    (for WINDOW inside WINDOWS do (PROG* ((REGION (DSPCLIPPINGREGION NIL WINDOW))
					  (WHEIGHT (fetch HEIGHT of REGION))
					  (LINES (WINDOWPROP WINDOW (QUOTE LINES)))
					  (TEXTLEN (fetch TEXTLEN of TEXTOBJ))
					  TOPCHAR BOTCHAR PREVLINE EXTHEIGHT EXTBOT YBOT)
				         (COND
					   ((TEXTPROP TEXTOBJ (QUOTE NOEXTENT))
                                                             (* If he doesn't want the extent set, don't bother 
							     him.)
					     (RETURN)))
				         (OR WINDOW (RETURN))
                                                             (* Do nothing if there's no window to do it in.)
				         (while (AND LINES (IGEQ (fetch YBOT of LINES)
								 WHEIGHT))
					    do               (* Run thru the lines looking for the first one on the 
							     screen.)
					       (SETQ LINES (fetch NEXTLINE of LINES)))
				         (COND
					   (LINES 

          (* IF there are lines on the screen, then get the CH# of the start of the first line -- notionally, the CH at the 
	  top of the screen.)


						  (SETQ TOPCHAR (fetch CHAR1 of LINES)))
					   (T                (* Otherwise, everything is scrolled off the top, so 
							     we're at the end.)
					      (SETQ TOPCHAR TEXTLEN)))
				         (while (AND LINES (IGEQ (fetch YBOT of LINES)
								 (fetch WBOTTOM of TEXTOBJ)))
					    do               (* Then go looking for the last line on the screen)
					       (SETQ PREVLINE LINES)
					       (SETQ LINES (fetch NEXTLINE of LINES)))
				         (COND
					   (PREVLINE 

          (* There IS a last line on the screen. Grab its last character as the bottom character on the screen, and set the 
	  lowest-Y position to the bottom of that line)


						     (SETQ BOTCHAR (IMIN TEXTLEN
									 (fetch CHARLIM of PREVLINE)))
						     (SETQ YBOT (fetch YBOT of PREVLINE)))
					   (T 

          (* Everything is off the top of the screen. Bottom character is also the last char in the document, and the lowest Y
	  we encountered is the top of the edit window.)


					      (SETQ BOTCHAR TEXTLEN)
					      (SETQ YBOT WHEIGHT)))
				         [COND
					   ((AND (IEQP BOTCHAR TEXTLEN)
						 (IEQP TOPCHAR TEXTLEN))
                                                             (* If we're really at the bottom of the document)
					     (SETQ EXTBOT (SUB1 YBOT))
                                                             (* Set up the extent bottom and height fields to 
							     account for that.)
					     (SETQ EXTHEIGHT WHEIGHT))
					   (T 

          (* Otherwise, set the bottom in proportion to what is left below the bottom of the screen, and the extent height in 
	  proportion to how much text appears in the window)


					      [SETQ EXTHEIGHT (FIXR (FQUOTIENT (ITIMES (IDIFFERENCE
											 WHEIGHT YBOT)
										       TEXTLEN)
									       (IMAX (IDIFFERENCE
										       BOTCHAR 
										       TOPCHAR)
										     1]
					      (SETQ EXTBOT
						(IDIFFERENCE YBOT
							     (FIXR (FQUOTIENT (ITIMES (IDIFFERENCE
											WHEIGHT YBOT)
										      (IDIFFERENCE
											TEXTLEN 
											BOTCHAR))
									      (IMAX (IDIFFERENCE
										      BOTCHAR TOPCHAR)
										    1]
				         (WINDOWPROP WINDOW (QUOTE EXTENT)
						     (create REGION
							     BOTTOM ← EXTBOT
							     HEIGHT ←(IMAX 1 EXTHEIGHT)
							     WIDTH ←(fetch WIDTH of REGION)
							     LEFT ← 0])

(\TEDIT.SHRINK.ICONCREATE
  [LAMBDA (W ICON ICONW)                                     (* jds "30-Sep-85 16:40")
                                                             (* Create the icon that represents this window.)
    [PROG [(ICON (WINDOWPROP W (QUOTE ICON)))
	   (ICONTITLE (WINDOWPROP W (QUOTE TEDIT.ICON.TITLE)))
	   (SHRINKFN (WINDOWPROP W (QUOTE SHRINKFN]
          (COND
	    ((NOT (WINDOWPROP W (QUOTE TEXTOBJ)))            (* This isn't really a TEdit window any more.
							     Don't do anything)
	      NIL)
	    ((WINDOWPROP W (QUOTE TEDITMENU))                (* This is a text menu, and shrinks without trace.)
	      NIL)
	    ((OR (IGREATERP (FLENGTH SHRINKFN)
			    3)
		 (AND (NOT (FMEMB (QUOTE SHRINKATTACHEDWINDOWS)
				  SHRINKFN))
		      (IGREATERP (FLENGTH SHRINKFN)
				 2)))                        (* There are other functions that expect to handle 
							     this. Don't bother.)
	      NIL)
	    ((OR [AND ICONTITLE (EQUAL ICONTITLE (TEXTSTREAM.TITLE (TEXTSTREAM W]
		 (AND (NOT ICONTITLE)
		      ICON))                                 (* we built this and the title is the same, or he has 
							     already put an icon on this.
							     Do nothing)
	      NIL)
	    (ICON                                            (* There's an existing icon window;
							     change the title in it)
		  [WINDOWPROP W (QUOTE TEDIT.ICON.TITLE)
			      (SETQ ICONTITLE (TEXTSTREAM.TITLE (TEXTSTREAM W]
		  (ICONTITLE ICONTITLE NIL NIL ICON))
	    (T                                               (* install a new icon)
	       [WINDOWPROP W (QUOTE TEDIT.ICON.TITLE)
			   (SETQ ICONTITLE (TEXTSTREAM.TITLE (TEXTSTREAM W]
	       (WINDOWPROP W (QUOTE ICON)
			   (TITLEDICONW TEDIT.TITLED.ICON.TEMPLATE ICONTITLE TEDIT.ICON.FONT NIL T 
					NIL (QUOTE FILE]
    (WINDOWPROP W (QUOTE ICON])

(\TEDIT.SHRINKFN
  [LAMBDA (W ICON ICONW)                                     (* jds "14-Dec-84 08:56")
                                                             (* hands off the tty to the exec process)
    (COND
      ((AND (EQ (WINDOWPROP W (QUOTE PROCESS))
		(TTY.PROCESS)))
	(TTY.PROCESS T)                                      (* per bvm, this means 
							     "Hand the TTY to some other process". It tries EXEC 
							     first; if that's not found, it hands it to MOUSE.)
	])

(\TEDIT.SPLITW
  [LAMBDA (WINDOW Y)                                         (* jds " 2-Oct-85 12:51")
                                                             (* SPLIT WINDOW W AT W-RELATIVE Y.)
    (PROG* ((WREG (WINDOWPROP WINDOW (QUOTE REGION)))
	    (TEXTOBJ (WINDOWPROP WINDOW (QUOTE TEXTOBJ)))
	    (OLDWINDOWS (COPY (fetch \WINDOW of TEXTOBJ)))
	    (ATTACHEDWINDOWS (WINDOWPROP WINDOW (QUOTE ATTACHEDWINDOWS)
					 NIL))
	    NEWW OLDW OTITLE OLDCARET NEWCARET OLINES)
           (SETQ Y (OR Y (LASTMOUSEY WINDOW)))
           (SHAPEW WINDOW (create REGION using WREG BOTTOM ←(IPLUS (fetch BOTTOM of WREG)
								   Y)
					       HEIGHT ←(IDIFFERENCE (fetch HEIGHT of WREG)
								    Y)))
           (ATTACHWINDOW (SETQ NEWW (CREATEW (create REGION using WREG HEIGHT ← Y)
					     NIL NIL NIL))
			 WINDOW
			 (QUOTE BOTTOM)
			 (QUOTE JUSTIFY)
			 (QUOTE MAIN))
           [WINDOWPROP WINDOW (QUOTE ATTACHEDWINDOWS)
		       (APPEND ATTACHEDWINDOWS (WINDOWPROP WINDOW (QUOTE ATTACHEDWINDOWS]
           (WINDOWPROP NEWW (QUOTE TEDITCREATED)
		       T)
           (DSPFONT (fetch CLFONT of (fetch CARETLOOKS of TEXTOBJ))
		    NEWW)                                    (* Set the font on the display stream to be the current
							     one from CARETLOOKS)
           (SETQ OLDW (fetch \WINDOW of TEXTOBJ))
           (SETQ OTITLE (\TEDIT.WINDOW.TITLE TEXTOBJ))
           (SETQ OLDCARET (fetch CARET of TEXTOBJ))
           (SETQ NEWCARET (create TEDITCARET
				  TCCARETDS ←(WINDOWPROP NEWW (QUOTE DSP))
				  TCFORCEUP ← T))
           [replace CARET of TEXTOBJ with (COND
					    ((LISTP OLDCARET)
					      (NCONC1 OLDCARET NEWCARET))
					    (T (LIST OLDCARET NEWCARET]
           (for SEL in (LIST (fetch SEL of TEXTOBJ)
			     (fetch SCRATCHSEL of TEXTOBJ)
			     (fetch MOVESEL of TEXTOBJ)
			     (fetch SHIFTEDSEL of TEXTOBJ)
			     (fetch DELETESEL of TEXTOBJ))
	      do (replace L1 of SEL with (NCONC1 (fetch L1 of SEL)
						 NIL))
		 (replace LN of SEL with (NCONC1 (fetch LN of SEL)
						 NIL)))
           (SETQ OLINES (fetch LINES of TEXTOBJ))
           (\TEDIT.WINDOW.SETUP NEWW TEXTOBJ (fetch STREAMHINT of TEXTOBJ)
				(APPEND (QUOTE (NOTITLE T PROMPTWINDOW DON'T))
					(fetch EDITPROPS of TEXTOBJ))
				WINDOW)
           [for CARET in (fetch CARET of TEXTOBJ) as WINDOW in (fetch \WINDOW of TEXTOBJ)
	      do (replace TCCARETDS of CARET with (WINDOWPROP WINDOW (QUOTE DSP]
           (replace WINDOWTITLE of TEXTOBJ with OTITLE)
           (WINDOWPROP NEWW (QUOTE PROCESS)
		       (WINDOWPROP WINDOW (QUOTE PROCESS])

(\TEDIT.UNSPLITW
  [LAMBDA (WINDOW Y)                                         (* jds " 2-Oct-85 12:46")

          (* * Re-attach two panes of a split editing window, to make a single larger pane.)


    (PROG* ([WREG (COPY (WINDOWPROP WINDOW (QUOTE REGION]
	    (TEXTOBJ (WINDOWPROP WINDOW (QUOTE TEXTOBJ)))
	    (WINDOWS (fetch \WINDOW of TEXTOBJ))
	    [MAINW (CADR (FMEMB WINDOW (REVERSE WINDOWS]
	    (SEL (fetch SEL of TEXTOBJ))
	    (SCRATCHSEL (fetch SCRATCHSEL of TEXTOBJ))
	    NEWW OLDW OTITLE ATTACHEDWINDOWS LINES CARETS)
           (COND
	     ((NOT MAINW)
	       (TEDIT.PROMPTPRINT TEXTOBJ "Can't UNSPLIT the main window." T)
	       (RETURN)))
           (DETACHWINDOW WINDOW)                             (* Detach the pane)
           (for CARET in (SETQ CARETS (fetch CARET of TEXTOBJ)) as LINE
	      in (SETQ LINES (fetch LINES of TEXTOBJ)) as OLDW in WINDOWS when (EQ WINDOW OLDW)
	      do                                             (* Remove the caret from our list, and the starting 
							     line)
		 (replace CARET of TEXTOBJ with (DREMOVE CARET CARETS))
		 (replace LINES of TEXTOBJ with (DREMOVE LINE LINES)))
                                                             (* Close the pane)
           (replace SELWINDOW of TEXTOBJ with MAINW)         (* Forget that we ever selected in the alternate 
							     window)
           (replace \WINDOW of TEXTOBJ with (SETQ WINDOWS (DREMOVE WINDOW WINDOWS)))
                                                             (* Have TEdit forget the window as well)
           (replace L1 of SEL with (CDR (fetch L1 of SEL)))
           (replace LN of SEL with (CDR (fetch LN of SEL)))
           (replace L1 of SCRATCHSEL with (CDR (fetch L1 of SCRATCHSEL)))
           (replace LN of SCRATCHSEL with (CDR (fetch LN of SCRATCHSEL)))
           (for REMAININGWINDOW inside WINDOWS
	      do                                             (* Run thru the remaining panes for this edit, fixing 
							     things up in the selections)
		 (\FIXSEL (fetch SEL of TEXTOBJ)
			  TEXTOBJ REMAININGWINDOW))
           (TEDIT.DEACTIVATE.WINDOW WINDOW T T)              (* Disable all the TEdit-related stuff on the window)
           (CLOSEW WINDOW)
           (SETQ ATTACHEDWINDOWS (WINDOWPROP MAINW (QUOTE ATTACHEDWINDOWS)
					     NIL))
           [SHAPEW MAINW (UNIONREGIONS WREG (WINDOWPROP MAINW (QUOTE REGION]
           (WINDOWPROP MAINW (QUOTE ATTACHEDWINDOWS)
		       ATTACHEDWINDOWS])

(\TEDIT.WINDOW.SETUP
  [LAMBDA (WINDOW TEXTOBJ TEXTSTREAM PROPS AFTERWINDOW)      (* jds " 4-Oct-85 16:59")
                                                             (* Set up the window and TEXTOBJ so they correspond, 
							     and the window is a TEDIT window.)
    (PROG ((ICONFN (WINDOWPROP WINDOW (QUOTE ICONFN)))
	   TEDITPROMPTWINDOW)
          (OR WINDOW (\ILLEGAL.ARG WINDOW))
          (TEDIT.WINDOW.SETUP WINDOW TEXTOBJ TEXTSTREAM PROPS AFTERWINDOW)
                                                             (* Do the general-purpose window setting up--the kind 
							     that every user will want. Then do the stuff that a 
							     TEdit session needs as well.)
          (WINDOWADDPROP WINDOW (QUOTE RESHAPEFN)
			 (FUNCTION \TEDIT.RESHAPEFN))
          (WINDOWADDPROP WINDOW (QUOTE NEWREGIONFN)
			 (FUNCTION \TEDIT.NEWREGIONFN))
          (OR (WINDOWPROP WINDOW (QUOTE SCROLLFN))
	      (WINDOWPROP WINDOW (QUOTE SCROLLFN)
			  (FUNCTION \TEDIT.SCROLLFN)))
          (WINDOWPROP WINDOW (QUOTE REPAINTFN)
		      (FUNCTION \TEDIT.REPAINTFN))
          [OR (WINDOWPROP WINDOW (QUOTE TEDIT.TITLEMENUFN))
	      (WINDOWPROP WINDOW (QUOTE TEDIT.TITLEMENUFN)
			  (OR (LISTGET PROPS (QUOTE TITLEMENUFN))
			      (QUOTE TEDIT.DEFAULT.MENUFN]   (* Only put our menu function on the window if the 
							     originator didn't supply one.)
          (WINDOWADDPROP WINDOW (QUOTE CLOSEFN)
			 (FUNCTION TEDIT.DEACTIVATE.WINDOW)
			 T)                                  (* To clean up when the window is closed)
          (WINDOWPROP WINDOW (QUOTE WINDOWENTRYFN)
		      (FUNCTION \TEDIT.PROCIDLEFN))          (* For grabbing the TTY when the mouse clicks in the 
							     window)
          (OR ICONFN (WINDOWPROP WINDOW (QUOTE ICONFN)
				 (FUNCTION \TEDIT.SHRINK.ICONCREATE)))
                                                             (* Only set up to create a shrink icon if nobody else 
							     has.)
          (WINDOWADDPROP WINDOW (QUOTE SHRINKFN)
			 (FUNCTION \TEDIT.SHRINKFN))         (* But always give up control of the keyboard on 
							     shrinking.)
          (WINDOWADDPROP WINDOW (QUOTE EXPANDFN)
			 (FUNCTION \TEDIT.EXPANDFN))         (* And grab it back on expansion)
          (WINDOWPROP WINDOW (QUOTE TEDIT.CURSORREGION)
		      (LIST 0 0 0 0))                        (* Used by CursorMovedFn)
          (COND
	    ((NOT AFTERWINDOW)                               (* Only set the window's title if we aren't splitting 
							     windows.)
	      (\TEDIT.WINDOW.TITLE TEXTOBJ (\TEDIT.ORIGINAL.WINDOW.TITLE WINDOW (fetch (TEXTOBJ
											 \DIRTY)
										   of TEXTOBJ)))
	      (COND
		((EQ (QUOTE DON'T)
		     (LISTGET PROPS (QUOTE PROMPTWINDOW)))   (* He said not to provide a feedback region, so don't.)
		  )
		((AND (NOT (LISTGET PROPS (QUOTE READONLY)))
		      [NOT (replace PROMPTWINDOW of TEXTOBJ with (LISTGET PROPS (QUOTE PROMPTWINDOW]
		      (NOT (fetch MENUFLG of TEXTOBJ)))      (* The window is read-write, so give it a feedback 
							     region)
		  (SETQ TEDITPROMPTWINDOW (GETPROMPTWINDOW WINDOW (OR (LISTGET PROPS (QUOTE 
									       PROMPTWINDOWHEIGHT))
								      TEDIT.PROMPTWINDOW.HEIGHT 1)
							   TEDIT.PROMPT.FONT))
		  (replace PROMPTWINDOW of TEXTOBJ with TEDITPROMPTWINDOW)
		  (WINDOWPROP TEDITPROMPTWINDOW (QUOTE TEDIT.PROMPTWINDOW)
			      T)                             (* And remember that this is a TEdit-supplied prompt 
							     window)
		  (WINDOWPROP TEDITPROMPTWINDOW (QUOTE PAGEFULLFN)
			      (FUNCTION \TEDIT.PROMPT.PAGEFULLFN])

(\SAFE.FIRST
  [LAMBDA (LIST.OR.ATOM)                                     (* gbn "18-Apr-84 21:13")
                                                             (* gives the first element whether the arg is a list or
							     an atom. Should be a macro eventually)
    (SELECTQ (TYPENAME LIST.OR.ATOM)
	     (LISTP (CAR LIST.OR.ATOM))
	     LIST.OR.ATOM])
)
(RPAQ BXCARET (CURSORCREATE (READBITMAP) NIL 3 4))
(16 16
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"A@@@"
"CH@@"
"CH@@"
"FL@@"
"FL@@"
"LF@@")(RPAQ BXHICARET (CURSORCREATE (READBITMAP) NIL 4 7))
(16 16
"A@@@"
"A@@@"
"A@@@"
"A@@@"
"A@@@"
"A@@@"
"A@@@"
"A@@@"
"CH@@"
"GL@@"
"FL@@"
"LF@@"
"HB@@"
"@@@@"
"@@@@"
"@@@@")(RPAQ TEDIT.LINECURSOR (CURSORCREATE (READBITMAP) NIL 15 15))
(16 16
"@@@A"
"@@@C"
"@@@G"
"@@@O"
"@@AO"
"@@CO"
"@@GO"
"@@@O"
"@@AK"
"@@AI"
"@@C@"
"@@C@"
"@@F@"
"@@F@"
"@@L@"
"@@L@")(RPAQ \TEDIT.SPLITCURSOR (CURSORCREATE (READBITMAP) NIL 4 4))
(16 16
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"OO@@"
"HA@@"
"HA@@"
"HA@@"
"HA@@"
"HA@@"
"HA@@"
"OO@@")(RPAQ \TEDIT.MOVESPLITCURSOR (CURSORCREATE (READBITMAP) NIL 4 4))
(16 16
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"OO@@"
"HA@@"
"HA@@"
"OO@@"
"OO@@"
"HA@@"
"HA@@"
"OO@@")(RPAQ \TEDIT.UNSPLITCURSOR (CURSORCREATE (READBITMAP) NIL 4 4))
(16 16
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"OO@@"
"HA@@"
"JE@@"
"II@@"
"II@@"
"JE@@"
"HA@@"
"OO@@")(RPAQ \TEDIT.MAKESPLITCURSOR (CURSORCREATE (READBITMAP) NIL 4 4))
(16 16
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"@@@@"
"OO@@"
"HA@@"
"HA@@"
"MK@@"
"MK@@"
"HA@@"
"HA@@"
"OO@@")
(RPAQ? TEDIT.DEFAULT.WINDOW NIL)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS TEDIT.DEFAULT.WINDOW)
)



(* User-typein support)

(DEFINEQ

(TEDIT.GETINPUT
  [LAMBDA (STREAM PROMPTSTRING DEFAULTSTRING DELIMITER.LIST)
                                                             (* jds "13-Nov-84 11:18")
                                                             (* Ask for input (file names, &c) for TEdit, perhaps 
							     with a default.)
    (PROG [(TEXTOBJ (TEXTOBJ STREAM))
	   (TPROMPT (OR (fetch PROMPTWINDOW of (TEXTOBJ STREAM))
			(GETPROMPTWINDOW (\TEDIT.MAINW STREAM)
					 NIL NIL T]
          (COND
	    (TPROMPT                                         (* If it's our own promptwindow, just clear it.)
		     (CLEARW (fetch PROMPTWINDOW of TEXTOBJ)))
	    (T                                               (* If it's the system's window, just move to a new 
							     line.)
	       (FRESHLINE PROMPTWINDOW)))
          (RETURN (PROG1 (PROMPTFORWORD PROMPTSTRING DEFAULTSTRING NIL (OR TPROMPT PROMPTWINDOW)
					NIL
					(QUOTE TTY)
					(OR DELIMITER.LIST (CHARCODE (EOL LF TAB ESCAPE)))
					NIL)                 (* Get what the guy wants to tell us)
			 (WINDOWPROP (OR (fetch PROMPTWINDOW of TEXTOBJ)
					 PROMPTWINDOW)
				     (QUOTE PROCESS)
				     NIL)                    (* Now detach the prompt window from its process, to 
							     avoid a circularity.)
			 ])

(\TEDIT.MAKEFILENAME
  [LAMBDA (STRING)                                           (* jds " 8-Feb-85 11:25")
                                                             (* Takes a string, removes leading and trailing spaces,
							     and converts it to an ATOM.)
    (PROG ((FIRSTNONSPACE (STRPOSL (QUOTE (% ))
				   STRING NIL T))
	   (LASTNONSPACE (STRPOSL (QUOTE (% ))
				  STRING NIL T T)))
          (COND
	    ((AND FIRSTNONSPACE LASTNONSPACE)
	      (RETURN (MKATOM (SUBSTRING STRING FIRSTNONSPACE LASTNONSPACE])
)



(* Attached Prompt window support.)

(DEFINEQ

(TEDIT.PROMPTPRINT
  [LAMBDA (TEXTSTREAM MSG CLEAR?)                          (* jds "11-Oct-85 17:32")
                                                             (* Print a message in the editor's prompt window 
							     (if none, use the global promptwindow). Optionally 
							     clear the window first.)
    (PROG (WINDOW PWINDOW (TEXTOBJ (TEXTOBJ TEXTSTREAM))
		    MAINTEXTOBJ)
	    (COND
	      [(AND TEXTOBJ (fetch MENUFLG of TEXTOBJ))
                                                             (* There is a known textobj, and it's a menu.
							     Go use the main editor's promptwindow.)
		(SETQ MAINTEXTOBJ (WINDOWPROP (\TEDIT.MAINW TEXTOBJ)
						  (QUOTE TEXTOBJ)))
                                                             (* Find the TEXTOBJ for the main edit window, and use 
							     ITS prompting window.)
		(SETQ WINDOW (AND MAINTEXTOBJ (fetch PROMPTWINDOW of MAINTEXTOBJ]
	      ((AND TEXTOBJ (SETQ WINDOW (fetch PROMPTWINDOW of TEXTOBJ)))
                                                             (* There IS an editor window to get to;
							     use its prompt window)
		)
	      ([SETQ WINDOW (CAR (NLSETQ (GETPROMPTWINDOW (\TEDIT.MAINW TEXTSTREAM)
								  NIL NIL T]
                                                             (* Failing that, try any prompt window attached to the
							     edit window.)
		))                                           (* Try to find an editor's prompt window for our 
							     message)
	    (COND
	      (WINDOW                                        (* We found a window to use.
							     Print the message.)
		      (RESETLST (RESETSAVE (TTYDISPLAYSTREAM WINDOW))
				  (COND
				    (CLEAR? (CLEARW WINDOW)))
				  (PRIN1 MSG WINDOW)))
	      (T                                             (* Failing all else, use PROMPTWINDOW.)
		 (FRESHLINE PROMPTWINDOW)
		 (printout PROMPTWINDOW MSG])

(TEDIT.PROMPTFLASH
  [LAMBDA (TEXTSTREAM)                                       (* jds " 8-Feb-85 11:01")
                                                             (* Flash the TEdit prompt window, or the global 
							     promptwindow, if TEdit has none.)
    (PROG (WINDOW PWINDOW (TEXTOBJ (TEXTOBJ TEXTSTREAM))
		  MAINTEXTOBJ)
          (COND
	    [(AND TEXTOBJ (fetch MENUFLG of TEXTOBJ))        (* There is a known textobj, and it's a menu.
							     Go use the main editor's promptwindow.)
	      (SETQ MAINTEXTOBJ (WINDOWPROP (\TEDIT.MAINW TEXTOBJ)
					    (QUOTE TEXTOBJ)))
                                                             (* Find the TEXTOBJ for the main edit window, and use 
							     ITS prompting window.)
	      (SETQ WINDOW (AND MAINTEXTOBJ (fetch PROMPTWINDOW of MAINTEXTOBJ]
	    ((AND TEXTOBJ (SETQ WINDOW (fetch PROMPTWINDOW of TEXTOBJ)))
                                                             (* There IS an editor window to get to;
							     use its prompt window)
	      )
	    ((SETQ WINDOW (GETPROMPTWINDOW (\TEDIT.MAINW TEXTSTREAM)
					   NIL NIL T))       (* Failing that, try any prompt window attached to the 
							     edit window.)
	      ))                                             (* Try to find an editor's prompt window for our 
							     message)
          (FLASHWINDOW (OR WINDOW PROMPTWINDOW)
		       2])

(\TEDIT.PROMPT.PAGEFULLFN
  [LAMBDA (WW)                                               (* jds " 2-Oct-85 18:34")
                                                             (* Given a TEdit promptwindow, expand it to be a line 
							     taller--called when a message overflows the window.)
    (PROG [(#LINES (ADD1 (OR (WINDOWPROP WW (QUOTE TEDIT.NLINES))
			     1]
          (GETPROMPTWINDOW (WINDOWPROP WW (QUOTE MAINWINDOW))
			   #LINES)
          (WINDOWPROP WW (QUOTE TEDIT.NLINES)
		      #LINES])
)

(RPAQ? TEDIT.PROMPT.FONT (FONTCREATE 'GACHA 10))

(RPAQ? TEDIT.PROMPTWINDOW.HEIGHT NIL)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS TEDIT.PROMPT.FONT TEDIT.PROMPTWINDOW.HEIGHT)
)



(* Title creation and update)

(DEFINEQ

(TEXTSTREAM.TITLE
  [LAMBDA (STREAM)                                           (* gbn "19-Apr-84 13:26")
                                                             (* returns a string with which you can talk to the user
							     about this stream)
    (PROG ((TEXTOBJ (TEXTOBJ STREAM))
	   TXTFILE)
          (SETQ TXTFILE (fetch TXTFILE of TEXTOBJ))
          (RETURN (OR (SELECTQ (TYPENAME TXTFILE)
			       (STRINGP TXTFILE)
			       (STREAM (fetch FULLNAME of TXTFILE))
			       (ATOMP TXTFILE)
			       TXTFILE)
		      ""])

(\TEDIT.ORIGINAL.WINDOW.TITLE
  [LAMBDA (FILE DIRTY?)                                      (* jds "14-Jun-85 15:27")
                                                             (* Given a file name, derive a title for the TEdit 
							     window that is editing it.)
    (PROG (TITLE)
          (RETURN (COND
		    ((NULL FILE)                             (* Just calling (TEDIT) should give a 
							     "Text Editor Window")
		      (CONCAT (COND
				(DIRTY? "* ")
				(T ""))
			      "Text Editor Window"))
		    ((AND (STRINGP FILE)
			  (ZEROP (NCHARS FILE)))             (* So should editing an empty string)
		      (CONCAT (COND
				(DIRTY? "* ")
				(T ""))
			      "Text Editor Window"))
		    ((WINDOWP FILE)
		      (COND
			((SETQ TITLE (WINDOWPROP FILE (QUOTE TITLE)))
                                                             (* if \TEDIT.WINDOW.SETUP has assigned a title, use it)
			  TITLE)
			(T "Text Editor Window")))
		    (T                                       (* Strings use the string itself, otherwise grab the 
							     full file name.)
		       (CONCAT (COND
				 (DIRTY? "* ")
				 (T ""))
			       "Edit Window for:  "
			       (SELECTQ (TYPENAME FILE)
					(STRINGP FILE)
					(STREAM (fetch FULLNAME of FILE))
					(ATOMP FILE)
					FILE])

(\TEDIT.WINDOW.TITLE
  [LAMBDA (TEXTSTREAM NEW.TITLE)                             (* jds "23-May-85 15:20")
    (PROG ((TEXTOBJ (TEXTOBJ TEXTSTREAM))
	   W)
          (RETURN (COND
		    ((AND (SETQ W (\TEDIT.PRIMARYW TEXTOBJ))
			  (NOT (TEXTPROP TEXTOBJ (QUOTE NOTITLE)))
			  (TEXTPROP TEXTOBJ (QUOTE TEDITCREATEDWINDOW)))
                                                             (* Only change the title if there IS a window, and he 
							     isn't suppressing title changes.)
		      (COND
			(NEW.TITLE (WINDOWPROP W (QUOTE TITLE)
					       NEW.TITLE))
			(T (WINDOWPROP W (QUOTE TITLE])

(\TEXTSTREAM.FILENAME
  [LAMBDA (TEXTSTREAM)                                       (* jds "15-Jan-85 13:11")

          (* * returns the name of the file associated with this stream if there is one. NIL otherwise.
	  Version numbers suppressed)


    (PROG ((TEXTOBJ (TEXTOBJ TEXTSTREAM))
	   OFILE)
          [COND
	    ((type? STREAM (fetch TXTFILE of TEXTOBJ))
	      [SETQ OFILE (UNPACKFILENAME (fetch FULLFILENAME (fetch TXTFILE of TEXTOBJ]
	      (AND OFILE (LISTPUT OFILE (QUOTE VERSION)
				  NIL))
	      (SETQ OFILE (AND OFILE (PACKFILENAME OFILE]
          (RETURN OFILE])
)



(* Screen updating utilities)

(DEFINEQ

(TEDIT.DEACTIVATE.WINDOW
  [LAMBDA (W FORCEFLG DISCONNECTONLYFLG)                     (* jds "23-Sep-86 23:19")
                                                             (* Deactivate the various button fns 
                                                             for this window)
    (PROG [(TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ]            (* Can't be a call to TEXTOBJ, since 
                                                             window may NOT have a textobj on it.)
          [COND
             ((AND TEXTOBJ (fetch EDITOPACTIVE of TEXTOBJ))  (* If something is going on, DON'T 
                                                             CLOSE THE WINDOW)
              (TEDIT.PROMPTPRINT TEXTOBJ "Not closed; edit operation in progress" T)
              (RETURN DON'T))
             ((AND TEXTOBJ (PROCESSP (WINDOWPROP W (QUOTE PROCESS)))
                   (NOT (fetch EDITFINISHEDFLG of TEXTOBJ))
                   (NOT (fetch TXTREADONLY of TEXTOBJ))
                   (NOT FORCEFLG))                           (* This is an un-quit TEdit window.
                                                             Try to QUIT out of TEdit.)
              (COND
                 ((\TEDIT.QUIT W T))
                 (T 
          
          (* Always return DON'T: If we didn't quit, we don't want to close the window;
          if we did quit, the window is closed already, and will be reopened to reclose 
          it.)

                    (RETURN (QUOTE DON'T]
          (COND
             ([AND TEXTOBJ (OR FORCEFLG (fetch EDITFINISHEDFLG of TEXTOBJ)
                               (NOT (PROCESSP (WINDOWPROP W (QUOTE PROCESS]
                                                             (* Only do this if it's a TEdit 
                                                             window, and has been QUIT out of.)
              [COND
                 ((AND (fetch PROMPTWINDOW of TEXTOBJ)
                       (OPENWP (fetch PROMPTWINDOW of TEXTOBJ)))
                  (CLEARW (fetch PROMPTWINDOW of TEXTOBJ]
              (\SHOWSEL (fetch SEL of TEXTOBJ)
                     NIL NIL)                                (* Before the window is closed, make 
                                                             SURE that the caret is down, or the 
                                                             window will reappear.)
              (COND
                 ((AND (\TEDIT.WINDOW.TITLE TEXTOBJ)
                       (OPENWP (fetch PROMPTWINDOW of TEXTOBJ))
                       (OPENWP W)
                       (EQ W (CAR (fetch \WINDOW of TEXTOBJ)))
                       (NOT DISCONNECTONLYFLG))
                  (\TEDIT.WINDOW.TITLE TEXTOBJ "Edit Window [Inactive]")
                                                             (* Reset the window's title to a known 
                                                             "inactive" value)
                  ))
              (COND
                 ((NOT DISCONNECTONLYFLG)
                  (for PANE in (REVERSE (CDR (fetch \WINDOW of TEXTOBJ))) do 
                                                             (* Run thru any split-off sub-panes, 
                                                             and reattach them, so we get a whole 
                                                             window back before the end of the 
                                                             world.)
                                                                             (\TEDIT.UNSPLITW PANE))
                  (replace \WINDOW of TEXTOBJ with NIL)))
              [COND
                 ((type? STREAM (fetch TXTFILE of TEXTOBJ))  (* Close the file that this window was 
                                                             open on.)
                  (COND
                     ((NOT (WINDOWPROP W (QUOTE TEDIT-CLOSING-FILE)
                                  T))
                      (CLOSEF? (fetch TXTFILE of TEXTOBJ))
                      (WINDOWPROP W (QUOTE TEDIT-CLOSING-FILE)
                             NIL]
              (WINDOWPROP W (QUOTE TEXTOBJ)
                     NIL)                                    (* Detach the edit data structures 
                                                             from the window)
              (WINDOWPROP W (QUOTE TEXTSTREAM)
                     NIL)
              (WINDOWPROP W (QUOTE LINES)
                     NIL)
              (WINDOWPROP W (QUOTE THISLINE)
                     NIL)
              (WINDOWPROP W (QUOTE PROCESS.EXITFN)
                     NIL)
              (WINDOWPROP W (QUOTE PROCESS.IDLEFN)
                     NIL)
              (WINDOWPROP W (QUOTE CURSOROUTFN)
                     NIL)
              (WINDOWPROP W (QUOTE CURSORMOVEDFN)
                     NIL)
              (WINDOWPROP W (QUOTE BUTTONEVENTFN)
                     (QUOTE TOTOPW))                         (* And the button functions)
              (WINDOWPROP W (QUOTE RIGHTBUTTONFN)
                     (QUOTE DOWINDOWCOM))
              (WINDOWDELPROP W (QUOTE CLOSEFN)
                     (QUOTE TEDIT.DEACTIVATE.WINDOW))
              (WINDOWPROP W (QUOTE SCROLLFN)
                     NIL)
              (WINDOWDELPROP W (QUOTE RESHAPEFN)
                     (QUOTE \EDITRESHAPEFN))
              (AND (NOT DISCONNECTONLYFLG)
                   (\TEDIT.INTERRUPT.SETUP W T))             (* Make sure any disarmed interrupts 
                                                             are restored.)
              (for MENUW in (ATTACHEDWINDOWS W) when (AND (WINDOWPROP MENUW (QUOTE TEDITMENU))
                                                          (WINDOWPROP MENUW (QUOTE TEXTOBJ)))
                 do                                          (* Detach all the TEDITMENU windows 
                                                             that belong to this window.)
                    (replace EDITFINISHEDFLG of (TEXTOBJ MENUW) with T) 
                                                             (* Mark it finished)
                    (WINDOWPROP MENUW (QUOTE TEDITMENU)
                           NIL)                              (* And mark it no longer a menu window)
                    (GIVE.TTY.PROCESS MENUW)                 (* Then give it a chance to kill 
                                                             itself off)
                    (DISMISS 300))
              (COND
                 ((NOT DISCONNECTONLYFLG)
                  (GIVE.TTY.PROCESS W)
                  (DISMISS 300)))
              [replace \WINDOW of TEXTOBJ with (COND
                                                  ((LISTP (fetch \WINDOW of TEXTOBJ))
                                                             (* It's a list; remove this window)
                                                   (DREMOVE W (fetch \WINDOW of TEXTOBJ]
                                                             (* Disconnect the window from the edit 
                                                             data structures as well.)
              ])

(\TEDIT.REPAINTFN
  [LAMBDA (W)                                                (* jds " 3-Jun-85 16:37")
                                                             (* Will eventually do the right thing w/r/t text 
							     margins. For now, it's a place holder.)
    (PROG ((TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ)))
	   (TEXTSTREAM (WINDOWPROP W (QUOTE TEXTSTREAM)))
	   (WREG (DSPCLIPPINGREGION NIL W))
	   (CH# 0)
	   WHEIGHT FIRSTCH# LINES LINE WWIDTH)
          (OR TEXTOBJ (RETURN))                              (* If this window has no TEXTOBJ on it yet, just 
							     leave.)
          (\SHOWSEL (fetch SEL of TEXTOBJ)
		    NIL NIL)                                 (* Turn off the selection while we make changes)
          (SETQ WHEIGHT (fetch PTOP of WREG))                (* Old window height)
          (OR (SETQ LINES (WINDOWPROP W (QUOTE LINES)))
	      (RETURN))                                      (* If no text has been displayed yet, just leave)
          (SETQ LINE LINES)
          (while LINE
	     do 

          (* Now hunt for the first line that had been visible, so we can find the CH# that has to appear at the top of the 
	  window.)


		(COND
		  ((ILESSP (fetch YBOT of LINE)
			   WHEIGHT)                          (* This line was visible)
		    (SETQ FIRSTCH# (fetch CHAR1 of LINE))    (* Note its first character #)
		    (RETURN)))
		(SETQ LINE (fetch NEXTLINE of LINE)))
          (COND
	    (LINE                                            (* You can only do this if there IS text on the screen 
							     to start with.)
		  (\DISPLAYLINE TEXTOBJ LINE W)              (* Actually display it)
		  (\FILLWINDOW (fetch YBOT of LINE)
			       LINE TEXTOBJ NIL W)           (* Fill out the window with more lines, to fill or to 
							     EOF)
		  ))
          (\FIXSEL (fetch SEL of TEXTOBJ)
		   TEXTOBJ)                                  (* Fix up the selection to account for the line 
							     shuffling)
          (\SHOWSEL (fetch SEL of TEXTOBJ)
		    NIL T)                                   (* And highlight it)
      ])

(\TEDIT.RESHAPEFN
  [LAMBDA (W BITS OLDREGION)                                 (* jds "24-Oct-84 17:38")
                                                             (* Will eventually do the right thing w/r/t text 
							     margins. For now, it's a place holder.)
    (PROG ((TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ)))
	   (TEXTSTREAM (WINDOWPROP W (QUOTE TEXTSTREAM)))
	   (NEWWHEIGHT (fetch HEIGHT of (DSPCLIPPINGREGION NIL W)))
	   (NEWWWIDTH (fetch WIDTH of (DSPCLIPPINGREGION NIL W)))
	   (NEWLEFT 0)
	   (NEWBOTTOM 0)
	   (CH# 0)
	   WHEIGHT FIRSTCH# LINES LINE WWIDTH)
          (OR TEXTOBJ (RETURN))                              (* If this window has no TEXTOBJ on it yet, just 
							     leave.)
          (\SHOWSEL (fetch SEL of TEXTOBJ)
		    NIL NIL)                                 (* Turn off the selection while we make changes)
          (SETQ WHEIGHT (fetch HEIGHT of OLDREGION))         (* Old window height)
          (replace WTOP of TEXTOBJ with NEWWHEIGHT)          (* Save new height/width for later use)
          (replace WRIGHT of TEXTOBJ with NEWWWIDTH)
          (replace WBOTTOM of TEXTOBJ with NEWBOTTOM)
          (replace WLEFT of TEXTOBJ with NEWLEFT)
          (OR (SETQ LINES (WINDOWPROP W (QUOTE LINES)))
	      (RETURN))                                      (* If no text has been displayed yet, just leave)
          (SETQ LINE LINES)
          (while LINE
	     do 

          (* Now hunt for the first line that had been visible, so we can find the CH# that has to appear at the top of the 
	  window.)


		(COND
		  ((ILESSP (fetch YBOT of LINE)
			   WHEIGHT)                          (* This line was visible)
		    (SETQ FIRSTCH# (fetch CHAR1 of LINE))    (* Note its first character #)
		    (RETURN))
		  (T (replace YBOT of LINE with NEWWHEIGHT)))
		(SETQ LINE (fetch NEXTLINE of LINE)))
          (AND FIRSTCH# (SETQ LINE (\TEDIT.FIND.FIRST.LINE TEXTOBJ NEWWHEIGHT FIRSTCH# W)))
          (COND
	    (LINE                                            (* You can only do this if there IS text on the screen 
							     to start with.)
		  (COND
		    ((NEQ LINE LINES)
		      (replace NEXTLINE of LINES with LINE)
		      (replace PREVLINE of LINE with LINES)))
                                                             (* Forget the old chain of line descriptors)
		  (replace YBOT of LINE with (IDIFFERENCE NEWWHEIGHT (fetch LHEIGHT of LINE)))
                                                             (* Fix the line to appear at the top of the window)
		  (replace YBASE of LINE with (IPLUS (fetch YBOT of LINE)
						     (fetch DESCENT of LINE)))
		  (\DISPLAYLINE TEXTOBJ LINE W)              (* Actually display it)
		  (\FILLWINDOW (fetch YBOT of LINE)
			       LINE TEXTOBJ NIL W)           (* Fill out the window with more lines, to fill or to 
							     EOF)
		  ))
          (\FIXSEL (fetch SEL of TEXTOBJ)
		   TEXTOBJ)                                  (* Fix up the selection to account for the line 
							     shuffling)
          (\SHOWSEL (fetch SEL of TEXTOBJ)
		    NIL T)                                   (* And highlight it)
      ])

(\TEDIT.SCROLLFN
  [LAMBDA (W DX DY)                                          (* jds " 2-Oct-85 14:27")
                                                             (* Handle scrolling of the edit window)
    (PROG* (WHEIGHT (TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ)))
		    (PRIORCR 0)
		    SELWASON SHIFTEDSELWASON MOVESELWASON DELETESELWASON (WREG (DSPCLIPPINGREGION
										 NIL W))
		    LINES TRUEY TRUEX WWIDTH SEL (PREVLINE NIL)
		    (PRESCROLLFN (TEXTPROP TEXTOBJ (QUOTE PRESCROLLFN)))
		    (POSTSCROLLFN (TEXTPROP TEXTOBJ (QUOTE POSTSCROLLFN)))
		    TEXTLEN THEIGHT TOPLINE RHEIGHT LOWESTY YBOT LINE CH# CHNO CH)
           (COND
	     ((ZEROP (SETQ TEXTLEN (fetch TEXTLEN of TEXTOBJ)))
                                                             (* Don't scroll a zero-length file)
	       (RETURN))
	     ((fetch EDITOPACTIVE of TEXTOBJ)                (* Don't scroll while something interesting is 
							     happening!)
	       (TEDIT.PROMPTPRINT TEXTOBJ "Edit operation in progress." T)
	       (RETURN)))                                    (* Displaystream for the window)
           (SETQ WHEIGHT (fetch HEIGHT of WREG))             (* Height of the window)
           (SETQ LOWESTY WHEIGHT)                            (* Lowest Y of a line-bottom yet seet)
           (SETQ WWIDTH (fetch WIDTH of WREG))               (* Width of the window)
           (SETQ LINES (WINDOWPROP W (QUOTE LINES)))         (* List of formatted lines)
           (AND PRESCROLLFN (DOUSERFNS PRESCROLLFN W))       (* If there's a pre-scroll fn, execute it now.)
           (COND
	     ((fetch SET of (SETQ SEL (fetch SEL of TEXTOBJ)))
                                                             (* Turn off the selection during the scroll.)
	       (SETQ SELWASON (fetch ONFLG of SEL))
	       (\SHOWSEL SEL NIL NIL)))
           (SETQ SHIFTEDSELWASON (fetch ONFLG of (fetch SHIFTEDSEL of TEXTOBJ)))
           (\SHOWSEL (fetch SHIFTEDSEL of TEXTOBJ)
		     NIL NIL)
           (SETQ MOVESELWASON (fetch ONFLG of (fetch MOVESEL of TEXTOBJ)))
           (\SHOWSEL (fetch MOVESEL of TEXTOBJ)
		     NIL NIL)
           (SETQ DELETESELWASON (fetch ONFLG of (fetch DELETESEL of TEXTOBJ)))
           (\SHOWSEL (fetch DELETESEL of TEXTOBJ)
		     NIL NIL)
           (COND
	     [(AND (FIXP DY)
		   (NOT (ZEROP DY)))                         (* Regular up/down scrolling)
	       (SETQ TRUEY (IDIFFERENCE WHEIGHT (IABS DY)))
	       (COND
		 [(ILESSP 0 DY)                              (* Scroll text up)
		   (SETQ LINE LINES)
		   (while (AND LINE (IGEQ (fetch YBOT of LINE)
					  WHEIGHT))
		      do (SETQ LINE (fetch NEXTLINE of LINE)))
		   (first [COND
			    ((AND LINE (ILESSP (fetch YBOT of LINE)
					       TRUEY))       (* Make sure we scroll up at least one line.)
			      (replace YBASE of LINE with (IPLUS (fetch DESCENT of LINE)
								 (replace YBOT of LINE with WHEIGHT)))
			      (SETQ LINE (fetch NEXTLINE of LINE]
		      while LINE
		      do                                     (* Find the line whose top is to move to the top of the
							     window)
			 [COND
			   ((ILESSP (fetch YBOT of LINE)
				    TRUEY)
			     (RETURN))
			   (T (replace YBASE of LINE with (IPLUS (fetch DESCENT of LINE)
								 (replace YBOT of LINE with WHEIGHT]
			 (SETQ PREVLINE LINE)
			 (SETQ LINE (fetch NEXTLINE of LINE)))
		   [COND
		     (LINE                                   (* There is a line to go to the top)
			   (SETQ RHEIGHT (IPLUS (fetch YBASE of LINE)
						(fetch ASCENT of LINE)))
                                                             (* Find the Ypos of the top of the line's image)
			   (BITBLT W 0 0 W 0 (IDIFFERENCE WHEIGHT RHEIGHT)
				   WWIDTH RHEIGHT (QUOTE INPUT)
				   (QUOTE REPLACE))
			   (BITBLT NIL 0 0 W 0 0 WWIDTH (IDIFFERENCE WHEIGHT RHEIGHT)
				   (QUOTE TEXTURE)
				   (QUOTE REPLACE)
				   WHITESHADE)
			   [bind NL (PL ← PREVLINE) for I from 1 to 50 while PL
			      do                             (* Let him keep 50 lines above what he can see on the 
							     screen)
				 (SETQ PL (fetch PREVLINE of PL))
			      finally (COND
					((AND PL (NEQ PL LINES))
                                                             (* There were more than 50 lines 
							     (and we aren't pointing at the root), so lop the spare 
							     ones off.)
					  (SETQ NL (fetch NEXTLINE of LINES))
					  (UNINTERRUPTABLY
                                              (replace NEXTLINE of LINES with PL)
					      (replace PREVLINE of PL with LINES))
					  (bind NNL while (AND NL (NEQ NL PL))
					     do (SETQ NNL NL)
						(SETQ NL (fetch NEXTLINE of NL))
						(replace NEXTLINE of NNL with NIL]
			   (while (AND LINE (IGEQ (fetch YBOT of LINE)
						  (fetch BOTTOM of WREG)))
			      do                             (* Update the bottom and baseline)
				 (replace YBOT of LINE with (IPLUS (fetch YBOT of LINE)
								   (IDIFFERENCE WHEIGHT RHEIGHT)))
				 (replace YBASE of LINE with (IPLUS (fetch YBOT of LINE)
								    (fetch DESCENT of LINE)))
				 (SETQ PREVLINE LINE)
				 (SETQ LINE (fetch NEXTLINE of LINE]
		   (COND
		     ((AND LINE (IGEQ (fetch YBOT of LINE)
				      (fetch BOTTOM of WREG)))
                                                             (* Fill the rest of the window)
		       (\FILLWINDOW (fetch YBOT of LINE)
				    LINE TEXTOBJ NIL W))
		     (PREVLINE (\FILLWINDOW (fetch YBOT of PREVLINE)
					    PREVLINE TEXTOBJ NIL W]
		 (T                                          (* Scroll text down in window, adding lines at top to 
							     fill.)
		    (SETQ PREVLINE (SETQ TOPLINE LINES))     (* Find the top line on the screen:)
		    [while TOPLINE
		       do                                    (* Run thru the lines, until we hit the first one that 
							     is below the top of the edit window)
			  (COND
			    ((ILESSP (fetch YBOT of TOPLINE)
				     WHEIGHT)
			      (RETURN))
			    (T (SETQ PREVLINE TOPLINE)
			       (SETQ TOPLINE (fetch NEXTLINE of TOPLINE]
		    [COND
		      ((AND (EQ PREVLINE LINES)
			    (OR (NOT (fetch NEXTLINE of PREVLINE))
				(IGREATERP (fetch CHAR1 of (fetch NEXTLINE of PREVLINE))
					   1)))              (* There's nothing between us and start of file that's 
							     formatted; start by making some.)
			(SETQ PREVLINE (\BACKFORMAT LINES TEXTOBJ WHEIGHT]
		    (SETQ THEIGHT 0)                         (* Accumulates the heights of the lines we've backed 
							     over. When this exceeds the scrolling distance, we've 
							     found the line.)
		    (bind (FIRSTTIME ← T) while (OR FIRSTTIME (AND (ILESSP THEIGHT (IABS DY))
								   (IGEQ (fetch CHAR1 of PREVLINE)
									 1)))
		       do                                    (* Starting with PREVLINE, accumulate LHEIGHTs until we
							     hit top of text or have accumulated enough lines to 
							     fill the screen)
			  (add THEIGHT (fetch LHEIGHT of PREVLINE))
			  (SETQ PREVLINE (fetch PREVLINE of PREVLINE))
			  [COND
			    ((OR (NOT PREVLINE)
				 (ILESSP (fetch CHAR1 of PREVLINE)
					 1))                 (* We need to format some lines above where we are -- 
							     go do it.)
			      (SETQ PREVLINE (\BACKFORMAT LINES TEXTOBJ WHEIGHT]
			  (SETQ FIRSTTIME NIL))
		    [COND
		      ([OR (EQ TOPLINE (fetch NEXTLINE of PREVLINE))
			   (EQ TOPLINE (fetch NEXTLINE of (fetch NEXTLINE of PREVLINE]
                                                             (* Always move at least one line backward.
							     So if we're about to move no lines, force a single 
							     line.)
			)
		      ((ILESSP (IABS DY)
			       THEIGHT)                      (* BACK UP ONE LINE TO GET TO THE ONE WHICH PUSHED US 
							     OVER TOP)
			(SETQ PREVLINE (fetch NEXTLINE of PREVLINE))
			(SETQ THEIGHT (IDIFFERENCE THEIGHT (fetch LHEIGHT of PREVLINE]
		    [COND
		      ((NEQ TOPLINE (fetch NEXTLINE of PREVLINE))
			(SETQ PREVLINE (fetch NEXTLINE of PREVLINE]
                                                             (* Move to the first line to be formatted.-)
		    (BITBLT W 0 THEIGHT W 0 0 WWIDTH (IDIFFERENCE WHEIGHT THEIGHT)
			    (QUOTE INPUT)
			    (QUOTE REPLACE))
		    (BITBLT NIL 0 0 W 0 (IDIFFERENCE WHEIGHT THEIGHT)
			    WWIDTH THEIGHT (QUOTE TEXTURE)
			    (QUOTE REPLACE)
			    WHITESHADE)
		    (bind (LINE ← TOPLINE) while LINE
		       do (COND
			    ((IGEQ (fetch YBOT of LINE)
				   (IPLUS (fetch BOTTOM of WREG)
					  THEIGHT))          (* This line will be on screen.
							     Adjust its YBOT/YBASE)
			      (replace YBOT of LINE with (IDIFFERENCE (fetch YBOT of LINE)
								      THEIGHT))
			      (replace YBASE of LINE with (IDIFFERENCE (fetch YBASE of LINE)
								       THEIGHT))
			      (SETQ LOWESTY (fetch YBOT of LINE)))
			    (T (replace YBOT of LINE with (SUB1 (fetch BOTTOM of WREG)))
			       (replace NEXTLINE of (fetch PREVLINE of LINE) with NIL)
			       (SETQ LINE (fetch PREVLINE of LINE))
			       (RETURN)))
			  (SETQ LINE (fetch NEXTLINE of LINE)) 
                                                             (* Clear anything below us))
		    (BITBLT NIL 0 0 W 0 (fetch BOTTOM of WREG)
			    WWIDTH
			    (IDIFFERENCE LOWESTY (fetch BOTTOM of WREG))
			    (QUOTE TEXTURE)
			    (QUOTE REPLACE)
			    WHITESHADE)
		    (SETQ YBOT WHEIGHT)
		    (while (AND PREVLINE (NEQ PREVLINE TOPLINE))
		       do                                    (* Move down lines to be added, adjusting YBOT/YBASE 
							     and DISPALYLINE-ing them, until the next line to do EQ 
							     TOPLINE)
			  [replace YBOT of PREVLINE
			     with (COND
				    [(AND (fetch PREVLINE of PREVLINE)
					  (IGREATERP (fetch CHAR1 of PREVLINE)
						     0)
					  (fetch FMTBASETOBASE of (fetch LFMTSPEC of PREVLINE)))
				      (SETQ YBOT (IDIFFERENCE (IPLUS YBOT
								     (fetch DESCENT
									of (fetch PREVLINE
									      of PREVLINE)))
							      (IPLUS (fetch FMTBASETOBASE
									of (fetch LFMTSPEC
									      of PREVLINE))
								     (fetch DESCENT of PREVLINE]
				    (T (SETQ YBOT (IDIFFERENCE YBOT (fetch LHEIGHT of PREVLINE]
			  (replace YBASE of PREVLINE with (IPLUS (fetch YBOT of PREVLINE)
								 (fetch DESCENT of PREVLINE)))
			  (\DISPLAYLINE TEXTOBJ PREVLINE W)
			  (SETQ PREVLINE (fetch NEXTLINE of PREVLINE]
	     ((FLOATP DY)                                    (* Do a thumbing-type scroll)
	       (SETQ CH# (IMAX (IMIN (SUB1 TEXTLEN)
				     (FIXR (FTIMES TEXTLEN DY)))
			       1))
	       (SETQ LINE (fetch NEXTLINE of LINES))
	       [while (AND LINE (ILESSP (fetch CHARLIM of LINE)
					CH#))
		  do (SETQ LINE (fetch NEXTLINE of LINE))
		  finally (COND
			    ((AND LINE (IGREATERP (fetch CHAR1 of LINE)
						  CH#))
			      (SETQ LINE NIL]                (* find out if any line currently formatted includes 
							     the target char)
	       (COND
		 ((AND LINE (fetch NEXTLINE of LINE)
		       (IGEQ (fetch CHAR1 of LINE)
			     1))                             (* If so, let's do this as a fast scroll, rather than a
							     complete repaint of the screen)
		   [SETQ DY (COND
		       [(ILEQ WHEIGHT (fetch YBOT of LINE))
                                                             (* this line is off the top of the window)
			 (IMINUS (for (DESCENDLINE ←(fetch NEXTLINE of LINE))
				    by (fetch NEXTLINE of DESCENDLINE)
				    while (AND DESCENDLINE (ILEQ WHEIGHT (fetch YBOT of DESCENDLINE)))
				    sum                      (* sum the heights of all the lines in between the new 
							     top line and the present top line)
					(fetch LHEIGHT of DESCENDLINE]
		       (T (IDIFFERENCE (IDIFFERENCE WHEIGHT (fetch YBOT of LINE))
				       (fetch LHEIGHT of LINE]
		   (\TEDIT.SCROLLFN W 0 DY)                  (* recurse telling to normally scroll instead of thumb 
							     scroll so that the screen is not blanked and 
							     reformatted unnecessarily)
		   )
		 (T [for LINE inside (fetch L1 of SEL) when LINE
		       do (replace YBOT of LINE with (SUB1 (fetch BOTTOM of WREG]
                                                             (* Make sure it thinks the old selection is off-screen 
							     for now)
		    [for LINE inside (fetch LN of SEL) when LINE
		       do (replace YBOT of LINE with (SUB1 (fetch BOTTOM of WREG]
		    (BITBLT NIL 0 0 W 0 (fetch BOTTOM of WREG)
			    WWIDTH
			    (IDIFFERENCE WHEIGHT (fetch BOTTOM of WREG))
			    (QUOTE TEXTURE)
			    (QUOTE REPLACE)
			    WHITESHADE)
		    (SETQ LINE (\TEDIT.FIND.FIRST.LINE TEXTOBJ WHEIGHT CH# W))
                                                             (* Find the first line to go in the window)
		    (replace YBOT of LINE with (IDIFFERENCE WHEIGHT (fetch LHEIGHT of LINE)))
                                                             (* Set it up as the top line.)
		    (replace YBASE of LINE with (IPLUS (fetch YBOT of LINE)
						       (fetch DESCENT of LINE)))
		    (\DISPLAYLINE TEXTOBJ LINE W)
		    (\FILLWINDOW (fetch YBOT of LINE)
				 LINE TEXTOBJ NIL W)))       (* And fill out the window from there.)
	       ))
           (AND POSTSCROLLFN (DOUSERFNS POSTSCROLLFN W))     (* For user subsystem cleanup)
           [COND
	     ((fetch SET of SEL)
	       (\FIXSEL SEL TEXTOBJ)
	       (AND SELWASON (\SHOWSEL SEL NIL T]
           [COND
	     ((fetch SET of (fetch SHIFTEDSEL of TEXTOBJ))
	       (\FIXSEL (fetch SHIFTEDSEL of TEXTOBJ)
			TEXTOBJ)
	       (AND SHIFTEDSELWASON (\SHOWSEL (fetch SHIFTEDSEL of TEXTOBJ)
					      NIL T]
           [COND
	     ((fetch SET of (fetch MOVESEL of TEXTOBJ))
	       (\FIXSEL (fetch MOVESEL of TEXTOBJ)
			TEXTOBJ)
	       (AND MOVESELWASON (\SHOWSEL (fetch MOVESEL of TEXTOBJ)
					   NIL T]
           [COND
	     ((fetch SET of (fetch DELETESEL of TEXTOBJ))
	       (\FIXSEL (fetch DELETESEL of TEXTOBJ)
			TEXTOBJ)
	       (AND DELETESELWASON (\SHOWSEL (fetch DELETESEL of TEXTOBJ)
					     NIL T]
           (\TEDIT.SET.WINDOW.EXTENT TEXTOBJ W])
)



(* Process-world interfaces)

(DEFINEQ

(\TEDIT.PROCIDLEFN
  [LAMBDA (WINDOW)                                           (* jds "26-Sep-85 16:42")
                                                             (* TEDIT's PROC.IDLEFN for regaining control.
							     If the shift key is down, we're not trying to restart 
							     this window, just to copy from it.)
    (GETMOUSESTATE)
    (COND
      [[AND (INSIDE? (DSPCLIPPINGREGION NIL WINDOW)
		     (LASTMOUSEX WINDOW)
		     (LASTMOUSEY WINDOW))
	    [NOT (OR (SHIFTDOWNP (QUOTE SHIFT))
		     (SHIFTDOWNP (QUOTE META))
		     (KEYDOWNP (QUOTE MOVE))
		     (KEYDOWNP (QUOTE COPY]
	    (PROCESSP (WINDOWPROP WINDOW (QUOTE PROCESS]     (* No SHIFT key down; let's regain control.)
	(TTY.PROCESS (WINDOWPROP WINDOW (QUOTE PROCESS)))
	(COND
	  ((fetch MENUFLG of (WINDOWPROP (WHICHW)
					 (QUOTE TEXTOBJ)))   (* This is a MENU -- always select.)
	    (\TEDIT.BUTTONEVENTFN WINDOW]
      (T                                                     (* Otherwise, let him select.)
	 (\TEDIT.BUTTONEVENTFN WINDOW])

(\TEDIT.PROCENTRYFN
  [LAMBDA (NEWPROCESS OLDPROCESS)                            (* jds "15-Feb-84 16:59")
                                                             (* TEDIT's PROCESS.ENTRYFN, which disarms any dangerous
							     interrupts within the editing world)
    (\TEDIT.INTERRUPT.SETUP NEWPROCESS])

(\TEDIT.PROCEXITFN
  [LAMBDA (THISP NEWP)                                       (* jds " 5-Apr-84 10:40")
                                                             (* Re-arm any interrupts that TEdit turned off, so the 
							     poor user has them available in other parts of the 
							     system.)
    (AND (WINDOWPROP (PROCESSPROP THISP (QUOTE WINDOW))
		     (QUOTE TEXTOBJ))
	 (\TEDIT.INTERRUPT.SETUP THISP T])
)

(RPAQ? \CARETRATE 333)



(* Caret handler; stolen from CHAT.)

(DEFINEQ

(\EDIT.DOWNCARET
  [LAMBDA (CARET)                                            (* jds "16-Jul-85 13:56")
                                                             (* Put the caret down -- i.e., MAKE IT VISIBLE -- as 
							     fast as possible)
    (replace TCCARETX of CARET with (DSPXPOSITION NIL (fetch (TEDITCARET TCCARETDS) of CARET)))
    (replace TCCARETY of CARET with (DSPYPOSITION NIL (fetch (TEDITCARET TCCARETDS) of CARET)))
    (replace TCFORCEUP of CARET with NIL)
    (\CARET.FLASH? (fetch (TEDITCARET TCCARETDS) of CARET)
		   (fetch TCCARET of CARET)
		   10 NIL (fetch TCCARETX of CARET)
		   (fetch TCCARETY of CARET))

          (* (replace TCFORCEUP of CARET with NIL) (* Turn off any enforced UPness) (AND (fetch TCUP of CARET) 
	  (\EDIT.FLIPCARET CARET T)) (* CARET:FORCEDDOWN is set so that caret will come up quickly.) (replace TCFORCEDDOWN of 
	  CARET with T))


    ])

(\EDIT.FLIPCARET
  [LAMBDA (CARET FORCE)                                                (* jds 
                                                                           " 9-Feb-86 15:21")
                                                                           (* changes the caret 
                                                                           from on to off or off 
                                                                           to on.)
            
            (* (COND ((OR FORCE (fetch TCFORCEDDOWN of CARET)
            (AND (IGREATERP (CLOCK0 (fetch TCNOWTIME of CARET))
            (fetch TCTHENTIME of CARET)) (NOT (fetch TCFORCEUP of CARET))))
            (UNINTERRUPTABLY (* note the time of the next change.)
            (* must be done without creating boxes because happens during keyboard 
            wait.) (\BOXIPLUS (CLOCK0 (fetch TCTHENTIME of CARET))
            (fetch TCCARETRATE of CARET)) (* Set the time for the next caret 
            transition) (replace TCUP of CARET with
            (NOT (fetch TCUP of CARET))) (* Invert the sense of the caret's UPness)
            (replace TCFORCEDDOWN of CARET with NIL)
            (* Turn off the force-down & Force-up flags)
            (replace TCFORCEUP of CARET with NIL) (PROG
            ((DS (fetch TCCARETDS of CARET)) (CURS
            (fetch TCCURSORBM of CARET))) (COND ((fetch TCUP of CARET))
            (T (* We're putting the caret down -- set the new X,Y position)
            (replace TCCARETX of CARET with (DSPXPOSITION NIL DS))
            (replace TCCARETY of CARET with (DSPYPOSITION NIL DS))))
            (BITBLT (fetch (CURSOR CUIMAGE) of CURS) 0 0 DS
            (IDIFFERENCE (fetch TCCARETX of CARET)
            (fetch (CURSOR CUHOTSPOTX) of CURS)) (IDIFFERENCE
            (fetch TCCARETY of CARET) (fetch (CURSOR CUHOTSPOTY) of CURS)) CURSORWIDTH 
            CURSORHEIGHT (QUOTE INPUT) (QUOTE INVERT)))))))

    ])

(TEDIT.FLASHCARET
  [LAMBDA (CARETS)                                           (* jds "16-Jul-85 12:35")
                                                             (* Unless the caret is constrained to be INVISIBLE, 
							     give it a chance to flash.)
    (bind (FIRSTTIME ← T) for CARET inside CARETS do (COND
						       ((NOT (fetch TCFORCEUP of CARET))
                                                             (* The caret need not stay invisible.)
                                                             (* (\EDIT.FLIPCARET CARET))
							 (COND
							   (FIRSTTIME (SETQ FIRSTTIME NIL)
								      (\CARET.FLASH? (fetch TCCARETDS
											of CARET)
										     (fetch TCCARET
											of CARET)
										     NIL NIL
										     (fetch TCCARETX
											of CARET)
										     (fetch TCCARETY
											of CARET)))
							   (T (\CARET.FLASH.AGAIN (fetch TCCARET
										     of CARET)
										  (fetch TCCARETDS
										     of CARET)
										  (fetch TCCARETX
										     of CARET)
										  (fetch TCCARETY
										     of CARET])

(\EDIT.UPCARET
  [LAMBDA (CARET)                                            (* jds "12-Jul-85 09:50")
                                                             (* Take the caret up -- i.e., MAKE IT INVISIBLE -- and 
							     keep it up)
    (\CARET.DOWN (fetch TCCARETDS of CARET))                 (* (OR (fetch TCUP of CARET) 
							     (\EDIT.FLIPCARET CARET T)))
                                                             (* CARET:FORCEUP is set so that caret will stay up.)
    (replace TCFORCEUP of CARET with T])

(TEDIT.NORMALIZECARET
  [LAMBDA (TEXTOBJ SEL)                                      (* jds "16-Jun-85 13:21")
                                                             (* Scroll the text window so that the caret is visible 
							     in it.)
    (SETQ TEXTOBJ (TEXTOBJ TEXTOBJ))
    (PROG* ((SEL (OR SEL (fetch SEL of TEXTOBJ)))
	    [WINDOW (OR (fetch SELWINDOW of TEXTOBJ)
			(CAR (fetch \WINDOW of TEXTOBJ]
	    (WREG (AND WINDOW (DSPCLIPPINGREGION NIL WINDOW)))
	    (WHEIGHT (AND WREG (fetch PTOP of WREG)))
	    (WBOTTOM (AND WREG (fetch BOTTOM of WREG)))
	    CH# Y LINE)
           (OR WINDOW (RETURN))
           (OR (fetch SET of SEL)
	       (RETURN))                                     (* If there is no selection set, don't bother.)
           (for WW inside (fetch \WINDOW of TEXTOBJ) as L1 inside (fetch L1 of SEL) as LN
	      inside (fetch LN of SEL) when (EQ WW WINDOW)
	      do 

          (* Get to the line info for the SELWINDOW. (failing that, the main/only edit window) Use that info to decide where 
	  the caret is.)


		 (SELECTQ (fetch POINT of SEL)
			  [LEFT                              (* The caret is at the left end of the selection;
							     hunt for the first selected character)
				(SETQ CH# (fetch CH# of SEL))
				(SETQ Y (OR (AND L1 (fetch YBOT of L1))
					    (fetch Y0 of SEL]
			  [RIGHT                             (* The caret is at the right end of the selection;
							     hunt for the last selected character)
				 (SETQ CH# (SUB1 (fetch CHLIM of SEL)))
				 (SETQ Y (OR (AND LN (fetch YBOT of LN))
					     (fetch YLIM of SEL]
			  NIL))
           (COND
	     ((AND (OR (IGEQ Y WHEIGHT)
		       (ILESSP Y WBOTTOM))
		   (NOT (fetch TXTNEEDSUPDATE of TEXTOBJ)))
                                                             (* The caret is off-screen. Scroll to get it on)
	       (for LINE inside (fetch L1 of SEL) when LINE do (replace YBOT of LINE
								  with (SUB1 WBOTTOM)))
                                                             (* Make sure it thinks the old selection is off-screen 
							     for now)
	       (for LINE inside (fetch LN of SEL) when LINE do (replace YBOT of LINE
								  with (SUB1 WBOTTOM)))
	       (SETQ LINE (\TEDIT.FIND.FIRST.LINE TEXTOBJ WHEIGHT
						  (IMAX 1 (IMIN CH# (fetch TEXTLEN of TEXTOBJ)))
						  WINDOW))   (* Find the first line to go in the window)
	       (replace YBOT of LINE with (IDIFFERENCE WHEIGHT (fetch LHEIGHT of LINE)))
                                                             (* Set it up as the top line.)
	       (replace YBASE of LINE with (IPLUS (fetch YBOT of LINE)
						  (fetch DESCENT of LINE)))
	       (\DISPLAYLINE TEXTOBJ LINE WINDOW)
	       (\FILLWINDOW (fetch YBOT of LINE)
			    LINE TEXTOBJ NIL WINDOW)         (* And fill out the window from there.)
	       (\FIXSEL SEL TEXTOBJ)
	       (\TEDIT.SET.WINDOW.EXTENT TEXTOBJ WINDOW])

(\SETCARET
  [LAMBDA (X Y DS TEXTOBJ CARET)                             (* jds "14-Jun-85 14:22")
    (PROG ((CLIPREGION (DSPCLIPPINGREGION NIL DS)))
          (COND
	    [(AND (ILESSP Y (fetch PTOP of CLIPREGION))
		  (IGEQ Y (fetch BOTTOM of CLIPREGION)))
	      (MOVETO X Y DS)
	      (COND
		((NOT (fetch TXTREADONLY of TEXTOBJ))
		  (\EDIT.DOWNCARET CARET]
	    (T                                               (* The caret is off screen. Do a MOVETO so the system 
							     carets don't appear at odd times.)
	       (MOVETO (IPLUS (fetch PTOP of CLIPREGION)
			      12)
		       0 DS)))                               (* Only put down the caret the line it points to is 
							     on-screen)
      ])

(\TEDIT.CARET
  [LAMBDA (CARETS)                                           (* jds "12-Jul-85 11:18")
                                                             (* Reset the caret to its normal state state, from the 
							     selection caret)
    (for CARET inside CARETS do (replace TCCARET of CARET with (\CARET.CREATE BXCARET])
)
(DECLARE: EVAL@COMPILE DONTCOPY 
[DECLARE: EVAL@COMPILE 

(DATATYPE TEDITCARET (TCNOWTIME                              (* Used to hold the current time, when 
                                                             checking to see if a transition is due)
                            TCTHENTIME                       (* Time when the next transition is to 
                                                             take place)
                            TCFORCEDDOWN                     (* TCFORCEDOWN = T means
                                                             (Make the caret visible at the next 
                                                             call to \EDIT.FLIPCARET.))
                            TCUP                             (* TCUP = T => The caret is NOT 
                                                             VISIBLE. Used to track the current 
                                                             state of the caret)
                            TCCARETDS                        (* The display stream that the caret 
                                                             appears in)
                            TCCURSORBM                       (* The CURSOR representing the caret)
                            TCCARETRATE                      (* # of MSEC between caret up/down 
                                                             transitions)
                            TCFORCEUP                        (* T => The caret is not allowed to 
                                                             become visible. Used to keep the caret 
                                                             up during screen updates)
                            TCCARETX                         (* X position in the window that the 
                                                             caret appears at)
                            TCCARETY                         (* Y position in the window where the 
                                                             caret appears)
                            TCCARET                          (* A lisp CARET to be flashed
                                                             (eventually))
                            )
                     TCNOWTIME ← (CREATECELL \FIXP)
                     TCTHENTIME ← (CREATECELL \FIXP)
                     TCCURSORBM ← BXCARET TCCARETRATE ← \CARETRATE TCUP ← T TCCARET ← (\CARET.CREATE
                                                                                       BXCARET))
]
(/DECLAREDATATYPE (QUOTE TEDITCARET)
       (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
                     POINTER))
       (QUOTE ((TEDITCARET 0 POINTER)
               (TEDITCARET 2 POINTER)
               (TEDITCARET 4 POINTER)
               (TEDITCARET 6 POINTER)
               (TEDITCARET 8 POINTER)
               (TEDITCARET 10 POINTER)
               (TEDITCARET 12 POINTER)
               (TEDITCARET 14 POINTER)
               (TEDITCARET 16 POINTER)
               (TEDITCARET 18 POINTER)
               (TEDITCARET 20 POINTER)))
       (QUOTE 22))
)



(* Menu interfacing)

(DEFINEQ

(TEDIT.ADD.MENUITEM
  [LAMBDA (MENU ITEM)                                        (* jds " 9-AUG-83 09:55")
                                                             (* Adds ITEM to the MENU, and updates all the stuff.)
    (PROG (OLDITM)
          (COND
	    ((MEMBER ITEM (fetch ITEMS of MENU))             (* Do nothing--it's already in the menu)
	      )
	    ([AND (LISTP ITEM)
		  (SETQ OLDITM (SASSOC (CAR ITEM)
				       (fetch ITEMS of MENU]
                                                             (* The menu item exists. Make sure the thing behind it 
							     is right.)
	      (RPLACD OLDITM (CDR ITEM)))
	    (T                                               (* It isn't in the menu, so go ahead and add it.)
	       (replace ITEMS of MENU with (NCONC1 (fetch ITEMS of MENU)
						   ITEM))
	       (COND
		 ((EQ (fetch MENUCOLUMNS of MENU)
		      1)                                     (* If there is only one column, force a re-figuring of 
							     the number of rows)
		   (replace MENUROWS of MENU with NIL))
		 ((EQ (fetch MENUROWS of MENU)
		      1)                                     (* There's only one row, so recompute # of columns.)
		   (replace MENUCOLUMNS of MENU with NIL)))
	       (replace ITEMWIDTH of MENU with 10000)
	       (replace ITEMHEIGHT of MENU with 10000)
	       (replace IMAGE of MENU with NIL)              (* Force it to create a new menu image.)
	       (UPDATE/MENU/IMAGE MENU])

(TEDIT.DEFAULT.MENUFN
  [LAMBDA (W)                                                (* jds "17-Jul-85 11:40")
                                                             (* Default User Fn for editor windows--displays a menu 
							     of items & acts on the commands received.)
    (PROG ((TEXTOBJ (WINDOWPROP W (QUOTE TEXTOBJ)))
	   (WMENU (WINDOWPROP W (QUOTE TEDIT.MENU)))
	   THISMENU CH OFILE OCURSOR PCTB LINES SEL ITEM)
          (COND
	    ((EQ (fetch EDITOPACTIVE of TEXTOBJ)
		 T)                                          (* We're busy doing something, but not sure what.
							     Give a general "please wait" msg)
	      (TEDIT.PROMPTPRINT TEXTOBJ "Edit operation in progress; please wait." T)
	      (RETURN))
	    ((fetch EDITOPACTIVE of TEXTOBJ)                 (* We know specifically what's happening.
							     Tell him)
	      (TEDIT.PROMPTPRINT TEXTOBJ (CONCAT (fetch EDITOPACTIVE of TEXTOBJ)
						 " in progress; please wait.")
				 T)
	      (RETURN)))
          (SETQ PCTB (fetch PCTB of TEXTOBJ))
          (SETQ THISMENU (COND
	      (WMENU)
	      ((SETQ WMENU (WINDOWPROP W (QUOTE TEDIT.MENU.COMMANDS)))
		(PROG1 (SETQ WMENU (\TEDIT.CREATEMENU WMENU))
		       (WINDOWPROP W (QUOTE TEDIT.MENU)
				   WMENU)))
	      (TEDIT.DEFAULT.MENU)))
          (SETQ ITEM (MENU THISMENU))
          (ERSETQ (RESETLST [RESETSAVE (\TEDIT.MARKACTIVE TEXTOBJ)
				       (QUOTE (AND (\TEDIT.MARKINACTIVE OLDVALUE]
			    (replace EDITOPACTIVE of TEXTOBJ with (OR (CAR ITEM)
								      T))
                                                             (* So we ca ntell the guy WHAT op is active.)
			    (SELECTQ (CAR ITEM)
				     [Put (TEDIT.PUT TEXTOBJ NIL NIL (TEXTPROP TEXTOBJ (QUOTE 
											 CLEARPUT]
				     (Plain-Text (TEDIT.PUT TEXTOBJ NIL NIL T))
				     (Old-Format             (* Write out the file in the OLD TEdit format.)
						 (TEDIT.PUT TEXTOBJ NIL NIL NIL T))
				     [Get                    (* Get a new file (overwriting the one being edited.))
					  (TEDIT.GET TEXTOBJ NIL (TEXTPROP TEXTOBJ (QUOTE CLEARGET]
				     (Unformatted% Get (TEDIT.GET TEXTOBJ NIL T))
				     (Include                (* Insert a file where the caret is)
					      (TEDIT.INCLUDE TEXTOBJ))
				     (Quit                   (* Stop this session.)
					   (\TEDIT.QUIT W))
				     [Substitute             (* Search-and-replace)
						 (RESETLST (RESETSAVE (CURSOR WAITINGCURSOR))
							   (TEDIT.SUBSTITUTE (fetch STREAMHINT
										of TEXTOBJ]
				     (Find                   (* Case sensitive search, with * and # wildcards)
					   [SETQ OFILE (TEDIT.GETINPUT TEXTOBJ "Text to find: "
								       (WINDOWPROP W (QUOTE 
									   TEDIT.LAST.FIND.STRING))
								       (CHARCODE (EOL LF ESC]
					   [COND
					     (OFILE (SETQ SEL (fetch SEL of TEXTOBJ))
						    (\SHOWSEL SEL NIL NIL)
						    (TEDIT.PROMPTPRINT TEXTOBJ "Searching..." T)
						    (SETQ CH (TEDIT.FIND TEXTOBJ (MKSTRING OFILE)
									 NIL NIL T))
						    (COND
						      (CH    (* We found the target text.)
							  (TEDIT.PROMPTPRINT TEXTOBJ "Done.")
							  (replace CH# of SEL with (CAR CH))
                                                             (* Set up SELECTION to be the found text)
							  (replace CHLIM of SEL
							     with (ADD1 (CADR CH)))
							  [replace DCH of SEL
							     with (ADD1 (IDIFFERENCE (CADR CH)
										     (CAR CH]
							  (replace POINT of SEL with (QUOTE RIGHT))
							  (replace CARETLOOKS of TEXTOBJ
							     with (\TEDIT.GET.INSERT.CHARLOOKS 
											  TEXTOBJ SEL)
								   )
							  (TEDIT.RESET.EXTEND.PENDING.DELETE SEL)
                                                             (* And never pending a deletion.)
							  (\FIXSEL SEL TEXTOBJ)
							  (TEDIT.NORMALIZECARET TEXTOBJ)
							  (\SHOWSEL SEL NIL T)
							  (WINDOWPROP W (QUOTE TEDIT.LAST.FIND.STRING)
								      OFILE)
                                                             (* And get it into the window)
							  )
						      (T (TEDIT.PROMPTPRINT TEXTOBJ "(not found)")
							 (\SHOWSEL SEL NIL T]
					   (replace \INSERTPCVALID of TEXTOBJ with NIL)
                                                             (* Doing a FIND invalidates the insertion-piece cahce? 
							     I don't understand this. Check it.)
					   )
				     (Looks                  (* He wants to set the font for the current selection)
					    (\TEDIT.LOOKS TEXTOBJ))
				     (Hardcopy               (* Print this document)
					       (TEDIT.HARDCOPY TEXTOBJ))
				     (Press% File            (* Make a hardcopy file with this document in it.)
						  (TEDIT.HCPYFILE TEXTOBJ))
				     (Expanded% Menu         (* Open the expanded operations menu.)
						     (\TEDIT.EXPANDED.MENU TEXTOBJ))
				     (Character% Looks       (* Open the menu for setting character looks)
						       (\TEDIT.EXPANDEDCHARLOOKS.MENU TEXTOBJ))
				     (Paragraph% Formatting 
                                                             (* Open the paragraph formatting menu)
							    (\TEDIT.EXPANDEDPARA.MENU TEXTOBJ))
				     (Page% Layout           (* Open the page-layout menu)
						   (\TEXTMENU.START (COPYTEXTSTREAM 
									  TEDIT.EXPANDED.PAGEMENU T)
								    (\TEDIT.PRIMARYW TEXTOBJ)
								    "Page Layout Menu" 150))
				     (COND
				       ((CAR ITEM)           (* This is a user-supplied entry.
							     Get the function, and apply it to the TEXTSTREAM for 
							     him)
					 (APPLY* (CAR ITEM)
						 (fetch STREAMHINT of TEXTOBJ])

(TEDIT.REMOVE.MENUITEM
  [LAMBDA (MENU ITEM)                                        (* gbn "26-Apr-84 04:06")
    (PROG (ITEMLIST)
          [COND
	    ((OR (LITATOM ITEM)
		 (STRINGP ITEM))
	      (for X in (fetch ITEMS of MENU) do (COND
						   ((AND (LISTP X)
							 (EQUAL (CAR X)
								ITEM))
						     (RETURN (SETQ ITEM X]
          (RETURN (COND
		    ((MEMBER ITEM (SETQ ITEMLIST (fetch ITEMS of MENU)))
		      (replace ITEMS of MENU with (REMOVE ITEM ITEMLIST))
		      (replace MENUCOLUMNS of MENU with NIL)
		      (replace MENUROWS of MENU with NIL)
		      (UPDATE/MENU/IMAGE MENU))
		    (T NIL])

(\TEDIT.CREATEMENU
  [LAMBDA (ITEMS)                                            (* jds " 3-AUG-83 10:23")
                                                             (* Create a TEdit command menu, given a list of menu 
							     items.)
    (create MENU
	    ITEMS ← ITEMS
	    CENTERFLG ← T
	    MENUFONT ←(FONTCREATE (QUOTE HELVETICA)
				  10
				  (QUOTE BOLD))
	    WHENHELDFN ←(QUOTE \TEDIT.MENU.WHENHELDFN)
	    WHENSELECTEDFN ←(QUOTE \TEDIT.MENU.WHENSELECTEDFN])

(\TEDIT.MENU.WHENHELDFN
  [LAMBDA (ITEM MENU BUTTON)                                 (* jds "10-Apr-84 15:14")
    (COND
      ((ATOM ITEM)
	(CLRPROMPT)
	(PROMPTPRINT (SELECTQ ITEM
			      (Put "Sends the document to a file")
			      (Get "Gets a new file as the document to edit.")
			      (Looks "Changes the font/size/etc. of characters")
			      (Find "Searches for a string")
			      (Quit "Ends the edit session")
			      (Hardcopy "Formats and sends the file to a printer.")
			      (Press% File "Creates a PRESS or INTERPRESS file of the document.")
			      "")))
      (T (DEFAULTMENUHELDFN ITEM])

(\TEDIT.MENU.WHENSELECTEDFN
  [LAMBDA (ITEM MENU BUTTON)                                 (* jds "28-APR-83 18:09")
                                                             (* A Selection fn for preserving the button pressed, 
							     for special handling in PUT, e.g.)
    (CONS (DEFAULTWHENSELECTEDFN ITEM MENU BUTTON)
	  BUTTON])
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS TEDIT.DEFAULT.MENU)
)
(DECLARE: DONTEVAL@LOAD DOCOPY 

(RPAQ TEDIT.DEFAULT.MENU [\TEDIT.CREATEMENU (QUOTE ((Put (QUOTE Put)
                                                         NIL
                                                         (SUBITEMS Plain-Text Old-Format))
                                                    (Get (QUOTE Get)
                                                         NIL
                                                         (SUBITEMS Unformatted% Get))
                                                    Include Find Looks Substitute Quit
                                                    (Expanded% Menu (QUOTE Expanded% Menu)
                                                           NIL
                                                           (SUBITEMS Expanded% Menu Character% Looks 
                                                                  Paragraph% Formatting Page% Layout])
)
(DECLARE: DONTEVAL@LOAD DOCOPY 
[OR (SASSOC (QUOTE TEdit)
           BackgroundMenuCommands)
    (NCONC1 BackgroundMenuCommands (QUOTE (TEdit (QUOTE (TEDIT))
                                                 "Opens a TEdit window for use."]
(SETQ BackgroundMenu NIL)
)
(/DECLAREDATATYPE (QUOTE TEDITCARET)
       (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
                     POINTER))
       (QUOTE ((TEDITCARET 0 POINTER)
               (TEDITCARET 2 POINTER)
               (TEDITCARET 4 POINTER)
               (TEDITCARET 6 POINTER)
               (TEDITCARET 8 POINTER)
               (TEDITCARET 10 POINTER)
               (TEDITCARET 12 POINTER)
               (TEDITCARET 14 POINTER)
               (TEDITCARET 16 POINTER)
               (TEDITCARET 18 POINTER)
               (TEDITCARET 20 POINTER)))
       (QUOTE 22))



(* titled icon info)

(FILESLOAD ICONW)

(RPAQ TEDITICON (READBITMAP))
(87 95
"OOOOOOOOOOOOOOOOON@@@@@@"
"OOOOOOOOOOOOOOOOON@@@@@@"
"OOOOOOOOOOOOOOOOON@@@@@@"
"O@AA@@CH@@@H@H@@@G@@@@@@"
"OOOOOOOOOOOOOOOOOOH@@@@@"
"OH@MJH@@F@@@@@@@B@N@@@@@"
"OOOOOOOOOOOHGOOOOOOH@@@@"
"MO@@@@@F@@@OL@@C@@@OH@@@"
"LOOOOOOOOOOOOOOOOOOOON@@"
"LGOOOOOOOOOOOOOOOOOOON@@"
"LAOOOOOOOOOOOOOOOOOOON@@"
"L@CN@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"LD@N@@@@@@@@@@@@@@@@@N@@"
"MLDN@@@@@@@@@@@@@@@@@N@@"
"LGBN@@@@@@@@@@@@@@@@@N@@"
"LDNN@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"M@@N@@@@@@@@@@@@@@@@@N@@"
"LGBN@@@@@@@@@@@@@@@@@N@@"
"LDNN@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"MH@N@@@@@@@@@@@@@@@@@N@@"
"MFBN@@@@@@@@@@@@@@@@@N@@"
"LELN@@@@@@@@@@@@@@@@@N@@"
"LDBN@@@@@@@@@@@@@@@@@N@@"
"LBBN@@@@@@@@@@@@@@@@@N@@"
"LALN@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"MH@N@@@@@@@@@@@@@@@@@N@@"
"M@DN@@@@@@@@@@@@@@@@@N@@"
"MDBN@@@@@@@@@@@@@@@@@N@@"
"MCBN@@@@@@@@@@@@@@@@@N@@"
"MNBN@@@@@@@@@@@@@@@@@N@@"
"MCJN@@@@@@@@@@@@@@@@@N@@"
"L@FN@@@@@@@@@@@@@@@@@N@@"
"L@BN@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"MH@N@@@@@@@@@@@@@@@@@N@@"
"M@@N@@@@@@@@@@@@@@@@@N@@"
"M@@N@@@@@@@@@@@@@@@@@N@@"
"ML@N@@@@@@@@@@@@@@@@@N@@"
"MCJN@@@@@@@@@@@@@@@@@N@@"
"M@FN@@@@@@@@@@@@@@@@@N@@"
"MHBN@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"L@@N@@@@@@@@@@@@@@@@@N@@"
"N@@N@@@@@@@@@@@@@@@@@N@@"
"G@@N@@@@@@@@@@@@@@@@@N@@"
"GH@N@@@@@@@@@@@@@@@@@N@@"
"CN@N@@@@@@@@@@@@@@@@@N@@"
"AOHN@@@@@@@@@@@@@@@@@N@@"
"@GOOOOOOOOOOOOOOOOOOON@@"
"@AOOOOOOOOOOOOOOOOOOON@@"
"@@COOOOOOOOOOOOOOOOOON@@")

(RPAQ TEDITMASK (READBITMAP))
(87 95
"OOOOOOOOOOOOOOOOON@@@@@@"
"OOOOOOOOOOOOOOOOON@@@@@@"
"OOOOOOOOOOOOOOOOON@@@@@@"
"OOOOOOOOOOOOOOOOOO@@@@@@"
"OOOOOOOOOOOOOOOOOOH@@@@@"
"OOOOOOOOOOOOOOOOOON@@@@@"
"OOOOOOOOOOOOOOOOOOOH@@@@"
"OOOOOOOOOOOOOOOOOOOOH@@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"OOOOOOOOOOOOOOOOOOOOON@@"
"GOOOOOOOOOOOOOOOOOOOON@@"
"GOOOOOOOOOOOOOOOOOOOON@@"
"COOOOOOOOOOOOOOOOOOOON@@"
"AOOOOOOOOOOOOOOOOOOOON@@"
"@GOOOOOOOOOOOOOOOOOOON@@"
"@AOOOOOOOOOOOOOOOOOOON@@"
"@@COOOOOOOOOOOOOOOOOON@@")

(RPAQ? TEDIT.ICON.FONT (FONTCREATE (QUOTE HELVETICA)
                              8
                              (QUOTE BOLD)))

(RPAQ? TEDIT.ICON.TITLE.REGION 
       (create REGION BOTTOM ← 4 LEFT ← 16 WIDTH ← 64 HEIGHT ← 77))

(RPAQ? TEDIT.TITLED.ICON.TEMPLATE (create TITLEDICON ICON ← TEDITICON MASK ← TEDITMASK TITLEREG ← 
                                         TEDIT.ICON.TITLE.REGION))
(PUTPROPS TEDITWINDOW COPYRIGHT ("John Sybalsky & Xerox Corporation" 1983 1984 1985 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (5602 76603 (TEDIT.CREATEW 5612 . 6699) (\TEDIT.CREATEW.FROM.REGION 6701 . 7642) (
TEDIT.CURSORMOVEDFN 7644 . 12323) (TEDIT.CURSOROUTFN 12325 . 12763) (TEDIT.WINDOW.SETUP 12765 . 14336)
 (TEDIT.MINIMAL.WINDOW.SETUP 14338 . 20207) (\TEDIT.ACTIVE.WINDOWP 20209 . 21088) (
\TEDIT.BUTTONEVENTFN 21090 . 52861) (\TEDIT.WINDOW.OPS 52863 . 54367) (\TEDIT.EXPANDFN 54369 . 54856) 
(\TEDIT.MAINW 54858 . 55961) (\TEDIT.PRIMARYW 55963 . 56961) (\TEDIT.COPYINSERTFN 56963 . 57673) (
\TEDIT.NEWREGIONFN 57675 . 59529) (\TEDIT.SET.WINDOW.EXTENT 59531 . 63641) (\TEDIT.SHRINK.ICONCREATE 
63643 . 65710) (\TEDIT.SHRINKFN 65712 . 66255) (\TEDIT.SPLITW 66257 . 69322) (\TEDIT.UNSPLITW 69324 . 
72205) (\TEDIT.WINDOW.SETUP 72207 . 76209) (\SAFE.FIRST 76211 . 76601)) (78002 79998 (TEDIT.GETINPUT 
78012 . 79414) (\TEDIT.MAKEFILENAME 79416 . 79996)) (80043 84250 (TEDIT.PROMPTPRINT 80053 . 82142) (
TEDIT.PROMPTFLASH 82144 . 83681) (\TEDIT.PROMPT.PAGEFULLFN 83683 . 84248)) (84480 87901 (
TEXTSTREAM.TITLE 84490 . 85096) (\TEDIT.ORIGINAL.WINDOW.TITLE 85098 . 86522) (\TEDIT.WINDOW.TITLE 
86524 . 87218) (\TEXTSTREAM.FILENAME 87220 . 87899)) (87940 117727 (TEDIT.DEACTIVATE.WINDOW 87950 . 
95392) (\TEDIT.REPAINTFN 95394 . 97740) (\TEDIT.RESHAPEFN 97742 . 101319) (\TEDIT.SCROLLFN 101321 . 
117725)) (117765 119759 (\TEDIT.PROCIDLEFN 117775 . 118953) (\TEDIT.PROCENTRYFN 118955 . 119288) (
\TEDIT.PROCEXITFN 119290 . 119757)) (119833 129286 (\EDIT.DOWNCARET 119843 . 120872) (\EDIT.FLIPCARET 
120874 . 122838) (TEDIT.FLASHCARET 122840 . 124066) (\EDIT.UPCARET 124068 . 124652) (
TEDIT.NORMALIZECARET 124654 . 128086) (\SETCARET 128088 . 128904) (\TEDIT.CARET 128906 . 129284)) (
132588 142721 (TEDIT.ADD.MENUITEM 132598 . 134262) (TEDIT.DEFAULT.MENUFN 134264 . 140423) (
TEDIT.REMOVE.MENUITEM 140425 . 141190) (\TEDIT.CREATEMENU 141192 . 141706) (\TEDIT.MENU.WHENHELDFN 
141708 . 142354) (\TEDIT.MENU.WHENSELECTEDFN 142356 . 142719)))))
STOP