Browse Source

* updated to latest ncrt package from Ken

peter 25 years ago
parent
commit
5ecf9b9cd0

+ 1 - 2
packages/ncurses/Makefile

@@ -185,14 +185,13 @@ endif
 # Targets
 
 override UNITOBJECTS+=ncurses panel ncrt ocrt
-override EXAMPLEOBJECTS+=firework testn ocrt_demo edit_demo
+override EXAMPLEOBJECTS+=firework testn ocrt_demo edit_demo db_demo
 
 # Clean
 
 
 # Install
 
-EXAMPLESUBDIR=ncurses
 ZIPTARGET=install
 
 # Defaults

+ 2 - 4
packages/ncurses/Makefile.fpc

@@ -4,14 +4,12 @@
 
 [targets]
 units=ncurses panel ncrt ocrt
-examples=firework testn ocrt_demo edit_demo
-
-[install]
-examplesubdir=ncurses
+examples=firework testn ocrt_demo edit_demo db_demo
 
 [dirs]
 fpcdir=../..
 
+
 [rules]
 testn$(EXEEXT): testn$(PASEXT) ncurses$(PPUEXT)
 

+ 97 - 20
packages/ncurses/edit_demo.pp

@@ -1,7 +1,7 @@
 Program Edit_Demo;
 {---------------------------------------------------------------------------
                                  CncWare
-                           (c) Copyright 1999
+                         (c) Copyright 1999-2000
  ---------------------------------------------------------------------------
   Filename..: edit_demo.pp
   Programmer: Ken J. Wright, [email protected]
@@ -14,46 +14,120 @@ Program Edit_Demo;
 -------+----------+-----+-----------------------------------------------------
   1.00 | 12/12/99 | kjw | Initial Release.
   1.01 | 12/13/99 | kjw | Changed to use oCrt.
+  1.02 | 06/16/00 | kjw | Added help & goto line pop-up screens.
+                        | Changes for control keys.
 ------------------------------------------------------------------------------
 }
 uses oCrt;
 var
    ss : array[1..25] of string[80];
-   xp,yp,
-   s : string;
+   xp,yp : string;
    c : char;
    win1,status : tnWindow;
    idx : integer;
    Finished : boolean;
 
+Procedure Help;
+Var
+   hwin : pnWindow;
 Begin
-   Status.Init(1,25,80,25,63,false,0);
-   Status.FWrite(1,1,63,80,' [F1-InsLn]  [F2-DelLn]  [F10-Exit]');
+   New(hwin,Init(1,1,40,20,62,true,49));
+   With hwin^ Do Begin
+      Align(center,center);
+      PutHeader('Edit_Demo Help',15,center);
+      FWrite(2, 2,63,0,'Ctrl/Q    - Move to column 1');
+      FWrite(2, 3,63,0,'Ctrl/W    - Move to end of line');
+      FWrite(2, 4,63,0,'Ctrl/A    - Move to previous word');
+      FWrite(2, 5,63,0,'Ctrl/F    - Move to next word');
+      FWrite(2, 6,63,0,'Ctrl/G    - Delete character');
+      FWrite(2, 7,63,0,'Ctrl/H    - Destructive Backspace');
+      FWrite(2, 8,63,0,'Ctrl/D    - Move forward one column');
+      FWrite(2, 9,63,0,'Ctrl/S    - Move back one column');
+      FWrite(2,10,63,0,'Ctrl/I    - Toggle Insert/Overwrite');
+      FWrite(2,11,63,0,'Ctrl/P    - Embed control character');
+      FWrite(2,12,63,0,'Ctrl/L    - Goto line number');
+      FWrite(2,13,63,0,'Ctrl/N    - Insert new line');
+      FWrite(2,14,63,0,'Ctrl/Y    - Delete current line');
+      FWrite(2,15,63,0,'Ctrl/X    - Move down one line');
+      FWrite(2,16,63,0,'Ctrl/E    - Move up one line');
+      FWrite(2,17,63,0,'Esc/1..0  - F1..F10');
+      Show;
+      Repeat Until Keypressed;
+      While KeyPressed Do ReadKey;
+      Hide;
+   End;
+   Dispose(hwin,Done);
+End;
+
+Procedure GotoLine(var i : integer);
+Var
+   gwin : pnWindow;
+   ii : integer;
+   esc : boolean;
+Begin
+   New(gwin,Init(1,1,40,3,62,true,49));
+   With gwin^ Do Begin
+      Align(center,center);
+      PutHeader('Goto Line Number',15,center);
+      FWrite(2,1,63,0,'Line: ');
+      Show;
+      ii := i;
+      ec.ClearMode := true;
+      i := EditNumber(8,1,63,2,0,'',i,1,win1.rows,esc);
+      If esc or not (i in [1..win1.rows]) Then i := ii;
+      Hide;
+   End;
+   Dispose(gwin,Done);
+End;
+
+Begin
+   Status.Init(1,nStdScr.Rows,nStdScr.Cols,nStdScr.Rows,63,false,0);
+   nFWrite(1,1,63,80,' [F1-InsLn]  [F2-DelLn]  [F3-Help]  [F10-Exit]');
    Status.Show;
    fillchar(ss,sizeof(ss),#0);
-   win1.Init(1,1,80,24,31,true,31);
-   win1.PutHeader(' nCrt Editor Demonstration ',15,center);
-   win1.Show;
-   win1.GotoXY(1,1);
-   {--------------------------------------------------------------------
-     The next line causes sedit to exit after every keystroke so we can
-     capture the insert mode and cursor positions.
-    --------------------------------------------------------------------}
-   win1.ec.ExitMode := true;
+   With win1 Do Begin
+      Init(1,1,nStdScr.Cols,nStdScr.Rows-1,31,true,31);
+      PutHeader(' nCrt Editor Demonstration ',15,center);
+      Show;
+      GotoXY(1,1);
+      {--------------------------------------------------------------------
+        The next line causes sedit to exit after every keystroke so we can
+        capture the insert mode and cursor positions for display update.
+        Alternatively, we could setup an ec.Special string to exit only on
+        certain keystrokes of interest.
+       --------------------------------------------------------------------}
+      ec.ExitMode := true;
+      { too re-assign a built-in key, put it in ec.special,
+        then use it in the case statement below
+
+      win1.ec.Special := win1.ec.Special + #5;
+      }
+      { now let's bind some keystrokes to the editor screen }
+      ec.AddChMap(^a#0#0+char(nKeyCtrlLeft));
+      ec.AddChMap(^s#0#0+char(nKeyLeft));
+      ec.AddChMap(^f#0#0+char(nKeyCtrlRight));
+      ec.AddChMap(^d#0#0+char(nKeyRight));
+      ec.AddChMap(^e#0#0+char(nKeyUp));
+      ec.AddChMap(^x#0#0+char(nKeyDown));
+      ec.AddChMap(^q#0#0+char(nKeyHome));
+      ec.AddChMap(^w#0#0+char(nKeyEnd));
+   End;
    idx := 1;
    Finished := false;
    Repeat
       With win1 Do Begin
          Case ec.InsMode of
-            true : Status.FWrite(40,1,48,0,'Ins');
-            false: Status.FWrite(40,1,48,0,'Ovr');
+            true : Status.FWrite(50,1,48,0,'Ins');
+            false: Status.FWrite(50,1,48,0,'Ovr');
          End;
          Str(WhereX:0,xp);
          Str(WhereY:0,yp);
-         Status.FWrite(50,1,48,80,'X='+xp+', Y='+yp);
-         ss[idx] := SEdit(1,idx,30,Cols,WhereX,ss[idx],c);
+         Status.FWrite(60,1,48,80,'X='+xp+', Y='+yp);
+         ss[idx] := Edit(1,idx,30,Cols,WhereX,ss[idx],c);
          Case ord(c) of
-            nKeyUp : dec(idx);
+                  12 : GotoLine(idx);
+            {5,}
+            nKeyUp   : dec(idx);
             nKeyDown : inc(idx);
             nKeyPgUp : idx := 1;
             nKeyPgDn : idx := Rows;
@@ -61,16 +135,19 @@ Begin
                           inc(idx);
                           GotoXY(1,WhereY);
                        End;
+            14, { ctrl/n }
             nKeyF1   : Begin
                           InsLine;
                           system.move(ss[idx],ss[idx+1],(rows-idx)*81);
                           ss[idx] := '';
                        End;
+            25, { ctrl/y }
             nKeyF2   : Begin
                           DelLine;
                           system.move(ss[idx+1],ss[idx],(rows-idx)*81);
                           ss[rows] := '';
                        End;
+            nKeyF3   : Help;
             nKeyEsc,
             nKeyF10  : Finished := true;
          End;
@@ -81,5 +158,5 @@ Begin
    Until Finished;
    win1.Done;
    Status.Done;
-   halt(1);
+   ClrScr;
 End.

+ 102 - 25
packages/ncurses/ncrt.inc

@@ -1,6 +1,6 @@
 {---------------------------------------------------------------------------
                                  CncWare
-                           (c) Copyright 1999
+                         (c) Copyright 1999-2000
                    Portions copyright the FreePascal Team
  ---------------------------------------------------------------------------
   Filename..: ncrt.inc
@@ -36,6 +36,23 @@
                         | 2) Added prev_textattr to detect a change in
                         | TextAttr value so current color gets updated.
                         | 3) See ocrt.pp
+  2.08 | 06/09/00 | kjw | See ocrt.pp
+
+  2.08.01 | 06/11/2000 | kjw | See ocrt.pp
+  2.09.00 | 06/16/2000 | kjw | See ocrt.pp
+  2.10.00 | 06/16/2000 | kjw | See ocrt.pp
+  2.11.00 | 06/27/2000 | kjw
+          | 1) See ocrt.pp
+          | 2) Now uses ncurses for CrtRead so console control characters
+          | work correctly (i.e., <ctrl/h>, <backspace>, etc.).
+  2.12.00 | 06/29/2000 | kjw | See ocrt.pp
+  2.13.00 | 06/30/2000 | kjw
+          | Added nStop and nStart procedures.
+  2.14.00 | 07/05/2000 | kjw
+          | 1) Added nCursor and nEscDelay functions.
+          | 2) Added nInit and moved code from ncrt.pp & ocrt.pp to it.
+          | 3) KEY_ALTMINUS & KEYALTEQUAL were reversed, but mapping ended
+          | up correct.
 ------------------------------------------------------------------------------
 }
 
@@ -60,13 +77,17 @@ Procedure TextMode(mode : word);
  Function WhereX : integer;
  Function WhereY : integer;
 Procedure Window(x,y,x1,y1 : integer);
+Procedure nStop;
+Procedure nStart;
+ Function nCursor(c : integer) : integer;
+ Function nEscDelay(d : longint) : longint;
 
 Const
 
    NCRT_VERSION_MAJOR = 2;
-   NCRT_VERSION_MINOR = 7;
+   NCRT_VERSION_MINOR = 14;
    NCRT_VERSION_PATCH = 0;
-   NCRT_VERSION = '2.07.00';
+   NCRT_VERSION = '2.14.00';
 
  { CRT modes }
    BW40          = 0;            { 40x25 B/W on Color Adapter }
@@ -141,10 +162,15 @@ Const
    KEY_ALT8 = 498; { alt/8 }
    KEY_ALT9 = 499; { alt/9 }
    KEY_ALT0 = 500; { alt/0 }
-   KEY_ALTEQUAL = 501; { alt/- }
-   KEY_ALTMINUS = 502; { alt/= }
+   KEY_ALTMINUS = 501; { alt/- }
+   KEY_ALTEQUAL = 502; { alt/= }
    KEY_ALTTAB   = 503; { alt/tab }
 
+   { cursor type }
+   cOFF = 0; { invisible cursor }
+   cON  = 1; { normal cursor }
+   cBIG = 2; { very visible cursor }
+
  var
    CheckBreak,
    CheckEOF,
@@ -237,17 +263,17 @@ Begin
       { alt/a .. atl/z }
       for i := ord('a') to ord('z') do Begin
          s := #27+chr(i)+#0;
-         define_key(@s[1],400+i-32);
+         define_key(@s[1],(KEY_ALTA-97)+i);
       End;
       { alt/1 .. alt/9 }
       for i := 1 to 9 do Begin
          s := #27+chr(i)+#0;
-         define_key(@s[1],490+i);
+         define_key(@s[1],(KEY_ALT1-1)+i);
       End;
-      s := #27+'0'+#0; define_key(@s[1],500); { alt/0 }
-      s := #27+'-'+#0; define_key(@s[1],501); { alt/- }
-      s := #27+'='+#0; define_key(@s[1],502); { alt/= }
-      s := #27+#9+#0;  define_key(@s[1],503); { alt/tab }
+      s := #27+'0'+#0; define_key(@s[1],KEY_ALT0);     { alt/0 }
+      s := #27+'-'+#0; define_key(@s[1],KEY_ALTMINUS); { alt/- }
+      s := #27+'='+#0; define_key(@s[1],KEY_ALTEQUAL); { alt/= }
+      s := #27+#9+#0;  define_key(@s[1],KEY_ALTTAB);   { alt/tab }
    End;
 End;
 
@@ -262,6 +288,25 @@ Begin
    tcSetAttr(STDIN,TCSANOW,tios);
 End;
 
+{--------------------------------------------------------
+  This disables any curses activity until a refresh.
+  Use this BEFORE any shelling (shell,exec,execv,etc)
+  to put the terminal temporarily back into cooked mode.
+ --------------------------------------------------------}
+Procedure nStop;
+Begin
+   endwin;
+End;
+
+{---------------------------------------------
+  Simply a refresh to re-establish the curses
+  terminal settings following an nStop.
+ ---------------------------------------------}
+Procedure nStart;
+Begin
+   refresh;
+End;
+
 { see if the specified attribute is high intensity }
 Function IsBold(att : integer) : boolean;
 Begin
@@ -494,8 +539,8 @@ Begin
          KEY_ALT8  : c := #127; { alt/8 }
          KEY_ALT9  : c := #128; { alt/9 }
          KEY_ALT0  : c := #129; { alt/0 }
-         KEY_ALTEQUAL : c := #130; { alt/- }
-         KEY_ALTMINUS : c := #131; { alt/= }
+         KEY_ALTMINUS : c := #130; { alt/- }
+         KEY_ALTEQUAL : c := #131; { alt/= }
          KEY_ALTTAB : c := #15; { alt/tab }
       Else
          Begin
@@ -583,23 +628,21 @@ Function CrtRead(Var F: TextRec): Integer;
 {
   Read from CRT associated file.
 }
-var
-  i : longint;
 Begin
-  F.BufEnd:=fdRead(F.Handle, F.BufPtr^, F.BufSize);
-{ fix #13 only's -> #10 to overcome terminal setting }
-  for i:=1to F.BufEnd do
-   begin
-     if (F.BufPtr^[i-1]=#13) and (F.BufPtr^[i]<>#10) then
-      F.BufPtr^[i-1]:=#10;
-   end;
-  F.BufPos:=F.BufEnd;
-  CrtWrite(F);
+  { let's use ncurses instead! }
+  FillChar(F.BufPtr^, F.BufSize, #0);
+  wgetnstr(ActiveWn,F.BufPtr^, F.BufSize-1);
+  F.BufEnd := Length(StrPas(F.BufPtr^))+1;
+  F.BufPtr^[F.BufEnd-1] := #10;
+  F.BufPos:=0;
+{  CrtWrite(F);}
   CrtRead:=0;
 End;
 
 Function CrtReturn(Var F:TextRec):Integer;
 Begin
+  F.BufEnd := 0;
+  F.BufPos:= 0;
   CrtReturn:=0;
 end;
 
@@ -755,7 +798,7 @@ End;
 function  Keypressed : boolean;
 var
    l : longint;
-   fd : fdSet;
+{   fd : fdSet;}
 Begin
    Keypressed := FALSE;
    nodelay(ActiveWn,bool(TRUE));
@@ -810,6 +853,40 @@ Begin
    ClrScr;
 End;
 
+{ Set the cursor visibility. Returns the previous value }
+{ or (-1) if value c is not supported by the terminal. }
+Function nCursor(c : integer) : integer;
+Begin
+   nCursor := curs_set(c);
+End;
+
+{ Set the <esc> key delay time in milliseconds. }
+{ Use d=(-1) to return current value without updating. }
+Function nEscDelay(d : longint) : longint;
+Begin
+   nEscDelay := ESCDELAY;
+   If d >= 0 Then ESCDELAY := d;
+End;
+
+{ unit initialization, following ncurses init }
+Procedure nInit;
+Begin
+   SubWn := nil;
+   TextMode(LastMode);
+
+   { Redirect the standard output }
+   assigncrt(Output);
+   Rewrite(Output);
+   TextRec(Output).Handle:=StdOutputHandle;
+   { Redirect the standard input }
+   assigncrt(Input);
+   Reset(Input);
+   TextRec(Input).Handle:=StdInputHandle;
+
+   nEscDelay(500); { default is 1000 (1 second) }
+   nCursor(cON);   { normal cursor }
+End;
+
 { exit procedure to ensure curses is closed up cleanly }
 Procedure nExit;
 Begin

+ 12 - 12
packages/ncurses/ncrt.pp

@@ -1,7 +1,7 @@
 Unit nCrt;
 {---------------------------------------------------------------------------
                                  CncWare
-                           (c) Copyright 1999
+                         (c) Copyright 1999-2000
                    Portions copyright the FreePascal Team
  ---------------------------------------------------------------------------
   Filename..: ncrt.pp
@@ -25,6 +25,15 @@ Unit nCrt;
   2.05 | 01/06/00 | kjw | See ncrt.inc, ocrt.pp
   2.06 | 01/11/00 | kjw | See ncrt.inc.
   2.07 | 01/31/00 | kjw | See ncrt.inc, ocrt.pp
+  2.08 | 06/09/00 | kjw | See ocrt.pp
+
+  2.08.01 | 06/11/00 | kjw | See ocrt.pp
+  2.09.00 | 06/16/00 | kjw | See ocrt.pp
+  2.10.00 | 06/23/00 | kjw | See ocrt.pp
+  2.11.00 | 06/27/00 | kjw | See ocrt.pp
+  2.12.00 | 06/29/00 | kjw | See ocrt.pp
+  2.13.00 | 06/30/00 | kjw | See ncrt.inc
+  2.14.00 | 07/05/00 | kjw | See ncrt.inc
 ------------------------------------------------------------------------------
 }
 Interface
@@ -40,17 +49,8 @@ Begin
    If Not StartCurses(ActiveWn) Then
       Halt;
 
-   SubWn := nil;
-   TextMode(LastMode);
-
-   { Redirect the standard output }
-   assigncrt(Output);
-   Rewrite(Output);
-   TextRec(Output).Handle:=StdOutputHandle;
-   { Redirect the standard input }
-   assigncrt(Input);
-   Reset(Input);
-   TextRec(Input).Handle:=StdInputHandle;
+   { crtassign }
+   nInit;
 
    { set the unit exit procedure }
    ExitSave := ExitProc;

+ 5 - 1
packages/ncurses/ncurses.pp

@@ -201,6 +201,7 @@ Var
        LINES   : longint;external name 'LINES';
        COLS    : longint;external name 'COLS';
        TABSIZE : longint;external name 'TABSIZE';
+       ESCDELAY: longint;external name 'ESCDELAY';
 
     Function define_key(_para1:pchar; _para2:longint):longint; cdecl;external;
     Function keyok(_para1:longint; _para2:bool):longint; cdecl;external;
@@ -1674,7 +1675,10 @@ end;
 end.
 {
   $Log$
-  Revision 1.7  2000-05-31 09:36:26  jonas
+  Revision 1.8  2000-07-08 18:06:36  peter
+    * updated to latest ncrt package from Ken
+
+  Revision 1.7  2000/05/31 09:36:26  jonas
     * restored (version included with ncrt 2.06 was outdated)
 
   Revision 1.5  2000/02/27 14:40:41  peter

+ 844 - 158
packages/ncurses/ocrt.pp

@@ -1,7 +1,7 @@
 Unit oCrt;
 {---------------------------------------------------------------------------
                                  CncWare
-                           (c) Copyright 1999
+                         (c) Copyright 1999-2000
  ---------------------------------------------------------------------------
   Filename..: ocrt.pp
   Programmer: Ken J. Wright, [email protected]
@@ -66,6 +66,62 @@ Unit oCrt;
   2.07 | 01/31/00 | kjw | 1) See ncrt.inc.
                         | 2) Added getcolor, getframecolor, getheadercolor
                         | methods to tnWindow.
+  2.08 | 06/09/00 | kjw | 1) Added Picture property to tEC object. This is
+                        | used for picture input masking in nSEdit.
+                        | 2) Added nCheckPxPicture() function.
+                        | 3) nSEdit() changed to use picture input masking.
+                        | See pxpic.txt for a description of the picture
+                        | string format.
+
+  2.08.01 | 06/11/2000 | kjw
+          | Fixed the spin cycle problem in nCheckPXPicture.
+  2.09.00 | 06/16/2000 | kjw
+          | 1) nSEdit renamed to nEdit. Now nSEdit just calls nEdit() for
+          | compatibility.
+          | 2) Added overloaded nEdit functions for Integer, LongInt, and
+          | Real types.
+          | 3) Changed nEdit() embedding of control characters to preface
+          | with a ^P. Also now uses a highlight attribute for the control
+          | characters.
+          | 4) Added control character cursor control to nEdit().
+          | 5) Added Esc/1..0 = F1..F10 to nEdit().
+          | 6) Added '@' to match set in pxpic.inc.
+          | 7) tnWindow.Align was not positioning properly. Off by one.
+          | 8) tnWindow.Init used wrong pointer for keypad and intrflush.
+          | 9) tnWindow.Edit was messing up ec.Special.
+  2.09.01 | 06/16/2000 | kjw
+          | 1) nStdScr (tnWindow) added and initialized at unit startup.
+          | nStdScr can be used for a default full screen window.
+          | 2) nEdit overloaded to work without a window pointer. It works
+          | with the currently active window.
+  2.10.00 | 06/23/2000 | kjw
+          | 1) Added character mapping to the tEC object. This includes the
+          | ChMap property and the AddChMap() and ClrChMap() methods.
+          | 2) Added AppendMode property to the tEC object. The character
+          | typed in nEdit() is always appended to the current string
+          | regardless of cursor position. Useful when ExitMode is true.
+          | 3) tnWindow.Done was not re-assigning an ActiveWn.
+          | 4) nEdit LeftArrow was allowing < x.
+          | 5) Added nEditNumber() function.
+          | 6) Added nEditDate() function.
+          | 7) I made a command decision and renamed the tEC.FirstTime
+          | property to tEC.ClearMode as it is more descriptive.
+  2.11.00 | 1) Cleaned up some loose ends with 2.10.
+          | 2) Some more overloading
+          | 3) Removed tnWindow.readln, write, and writeln methods.
+          | 4) See ncrt.inc.
+  2.12.00 | 1) Remove the "n" from the tnWindow.editxxx functions for
+          | consistancy. Procedurals are prefaced with an "n". Object methods
+          | are not.
+          | 2) Procedural FWrite renamed to nFWrite.
+          | 3) tEC object type renamed to tnEC.
+          | 4) Added nMakeWindow(), a one line procedural wrapper for
+          | tnWindow.Init and tnWindow.PutHeader.
+          | 5) Added GetX, GetY, IsFramed methods to tnWindow;
+          | 6) Fixed nFWrite for too long strings;
+          | 7) tnWindow.Align was wrong when justify was none.
+  2.13.00 | 06/30/00 | kjw | See ncrt.inc
+  2.14.00 | 07/05/00 | kjw | See ncrt.inc
 ------------------------------------------------------------------------------
 }
 Interface
@@ -74,21 +130,31 @@ Uses linux,ncurses,panel;
 
 Const
 
+   { decimal number format, us or european }
+   nUS = 0;
+   nEURO = 1;
+   nDecFmt : byte = nUS;
+
    { border styles for text boxes }
    btNone : integer = 0;
    btSingle : integer = 1;
    btDouble : integer = 2;
 
+   { ordinal key codes }
    nKeyEnter     = 13;      { Enter key }
    nKeyEsc       = 27;      { Home key }
    nKeyHome      = 71;      { Home key }
-   nKeyUp        = 72;      { Up Arrow }
-   nKeyPgUp      = 73;      { PgUp Key }
-   nKeyLeft      = 75;      { Left Arrow }
-   nKeyRight     = 77;      { Right Arrow }
-   nKeyEnd       = 79;      { End Key }
-   nKeyDown      = 80;      { Down Arrow }
-   nKeyPgDn      = 81;      { PgDn Key }
+   nKeyUp        = 72;      { Up arrow }
+   nKeyPgUp      = 73;      { PgUp key }
+   nKeyLeft      = 75;      { Left arrow }
+   nKeyRight     = 77;      { Right arrow }
+   nKeyEnd       = 79;      { End key }
+   nKeyDown      = 80;      { Down arrow }
+   nKeyPgDn      = 81;      { PgDn key }
+   nKeyIns       = 82;      { Insert key }
+   nKeyDel       = 83;      { Delete key }
+   nKeyCtrlLeft  = 115;     { Ctrl/left arrow }
+   nKeyCtrlRight = 116;     { Ctrl/right arrow }
    nKeyF1        = 59;      { f1 key }
    nKeyF2        = 60;      { f2 key }
    nKeyF3        = 61;      { f3 key }
@@ -110,31 +176,55 @@ Const
    nKeyF19       = 92;      { shift/f9 key }
    nKeyF20       = 93;      { shift/f10 key }
 
+   { character mapping }
+   nMaxChMaps    = 255;     { maximun index for character mapping }
+
+   { menus }
+   nMAXMENUITEMS = 23;
 
 Type
    { for scrolling a window }
    tnUpDown = (up,down);
    { for window & header positioning }
    tnJustify = (none,left,center,right,top,bottom);
+   { used for nEC character mapping }
+   nChMapStr = string[4];
+   nChMap = array [1..nMaxChMaps] of nChMapStr;
 
    { used for nSEdit }
-   {------------------------------------------------------------------
-     FirstTime = true : passed string is initialized to ''.
+   {------------------------------------------------------------------------
+     ClearMode = true : passed string is initialized to ''.
       IsHidden = true : causes a string of '*' to display in place of
                         the actual characters typed.
        InsMode        : toggle for insert/overwrite mode.
       ExitMode = true : sedit exits after every keystroke.
                = false: sedit only exits when #27,#13, or any extended
                         key *except* for Home,End,RArrow,LArrow.
-    ------------------------------------------------------------------}
-   tEC = Object
-      FirstTime,
+       Special        : If a pressed key is found in this string, then
+                        sedit exits without processing.
+       Picture        : An input mask string. See pxpic.txt for an
+                        explanation of picture strings.
+     CtrlColor        : The highlight color for embedded control characters.
+         ChMap        : An array of character triplets describing a character
+                        that is typed and what it should map to.
+    ------------------------------------------------------------------------}
+   tnEC = Object
+      ClearMode,
       IsHidden,
       InsMode,
-      ExitMode : boolean;
-      special : string;
-      Constructor Init(ft,ih,im,em : boolean; s : string);
+      ExitMode,
+      AppendMode : boolean;
+      Special : string;
+      Picture : string;
+      CtrlColor : integer;
+      ChMap : nChMap;
+      Constructor Init(ft,ih,im,em,ap : boolean;
+                                  s,p : string;
+                                   cc : integer;
+                                   mp : nChMap);
       Destructor Done;
+      Function AddChMap(mp : nChMapStr) : integer;
+      Procedure ClrChMap(idx : integer);
    End;
 
    pwin = ^Window;
@@ -154,11 +244,12 @@ Type
          hdrcolor : integer;  { header color }
          header : string[80]; { header string }
       Public
-         ec : tEC;            { edit control settings }
+         ec : tnEC;           { edit control settings }
          Constructor Init(x,y,x1,y1,wcolor : integer;
                                     border : boolean;
                                     fcolor : integer);
          Destructor Done;
+         Procedure Active;  { make this the current window }
          Procedure Show;    { display the window }
          Procedure Hide;    { hide the window }
          Procedure ClrScr;
@@ -170,9 +261,6 @@ Type
           Function WhereX : integer;
           Function WhereY : integer;
           Function ReadKey : char;
-          Function Readln : string;
-         Procedure Write(s : string);
-         Procedure Writeln(s : string);
          Procedure WriteAC(x,y,att,c : longint);
          Procedure FWrite(x,y,att,z : integer; s : string);
          Procedure DrawBox(LineStyle,x1,y1,x2,y2,att : Integer);
@@ -188,12 +276,21 @@ Type
          Procedure Align(hpos,vpos : tnJustify);
           Function Rows : integer;
           Function Cols : integer;
-          Function SEdit(x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
+          Function GetX : integer;
+          Function GetY : integer;
+          Function IsFramed : boolean;
+          Function Edit(x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
+          Function Edit(x,y,att,z,CursPos:Integer;es:LongInt;Var ch : Char) : LongInt;
+          Function Edit(x,y,att,z,CursPos:Integer;es:Real;Var ch : Char) : Real;
+          Function EditNumber(x,y,att,wid,decm : integer;bgd : string;initv,minv,maxv : real;var esc : boolean) : real;
+          Function EditNumber(x,y,att,wid,decm : integer;bgd : string;initv,minv,maxv : longint;var esc : boolean) : longint;
+          Function EditDate(x,y,att : integer;initv : string;var esc : boolean) : string;
    End;
 
 Var
-   nscreen : pwin;
-   nEC : tEC;
+   nStdScr : tnWindow; { default window created at unit initialization }
+   nscreen : pwin;     { pointer to ncurses stdscr }
+   nEC : tnEC;         { global edit control object }
 
 Procedure nSetActiveWin(win : pwindow);
 Procedure nDoNow(donow : boolean);
@@ -247,26 +344,29 @@ Procedure nVLine(win : pwindow; col,row,attr,y : integer);
 Procedure nWriteAC(win : pwindow; x,y : integer; att,acs_char : longint);
  Function IsBold(att : integer) : boolean;
  Function SetColorPair(att : integer) : integer;
-Procedure FWrite(col,row,attrib : integer; clear : integer; s : string);
+Procedure nFWrite(win : pwindow; col,row,attrib : integer; clear : integer; s : string);
+Procedure nFWrite(col,row,attrib : integer; clear : integer; s : string);
  Function nSEdit(win : pwindow; x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
+ Function nEdit(win : pwindow; x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
+ Function nEdit(win : pwindow; x,y,att,z,CursPos:Integer;es:LongInt;Var ch : Char) : LongInt;
+ Function nEdit(win : pwindow; x,y,att,z,CursPos:Integer;es:Real;Var ch : Char) : Real;
+ Function nEdit(x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
+ Function nEdit(x,y,att,z,CursPos:Integer;es:LongInt;Var ch : Char) : LongInt;
+ Function nEdit(x,y,att,z,CursPos:Integer;es:Real;Var ch : Char) : Real;
+ Function nEditNumber(win : pwindow; x,y,att,wid,decm : integer;bgd : string;initv,minv,maxv : real;var esc : boolean) : real;
+ Function nEditNumber(win : pwindow; x,y,att,wid,decm : integer;bgd : string;initv,minv,maxv : longint;var esc : boolean) : longint;
+ Function nEditNumber(x,y,att,wid,decm : integer;bgd : string;initv,minv,maxv : real;var esc : boolean) : real;
+ Function nEditNumber(x,y,att,wid,decm : integer;bgd : string;initv,minv,maxv : longint;var esc : boolean) : longint;
+ Function nEditDate(win : pwindow; x,y,att : integer;initv : string;var esc : boolean) : string;
+ Function nEditDate(x,y,att : integer;initv : string;var esc : boolean) : string;
+Procedure nMakeWindow(var win : tnWindow;x1,y1,x2,y2,ta,ba,ha : integer;hasframe : boolean;hdrpos : tnJustify;hdrtxt : string);
+ Function nCheckPxPicture(var s, Pic : string; var CPos : integer) : word;
 
 {$i ncrt.inc}
+{$i pxpic.inc}
 
-Const
-   internal_fwrite : Boolean = false;
-
-{ internal wrapper }
-Procedure intFWrite(win : pwindow; col,row,attrib,clear : integer; s : string);
 Var
-   tmp : pwindow;
-Begin
-   tmp := ActiveWn;
-   ActiveWn := win;
-   internal_fwrite := true;
-   FWrite(col,row,attrib,clear,s);
-   internal_fwrite := false;
-   ActiveWn := tmp;
-End;
+   _chmap : nChMap;
 
 {---------------------------------------------------------------------
   tnWindow.Init
@@ -283,6 +383,8 @@ End;
 Constructor tnWindow.Init(x,y,x1,y1,wcolor : integer;
                            border : boolean;
                            fcolor : integer);
+Var
+   mp : nChMap;
 Begin
    visible := false;
    hasframe := false;
@@ -305,10 +407,11 @@ Begin
       wbkgd(win,COLOR_PAIR(SetColorPair(wcolor)));
       If isbold(wcolor) then wattr_on(win,A_BOLD);
       scrollok(win,bool(true));
-      intrflush(stdscr,bool(false));
-      keypad(stdscr,bool(true));
+      intrflush(win,bool(false));
+      keypad(win,bool(true));
    End;
-   ec.Init(false,false,false,false,'');
+   FillChar(mp,SizeOf(mp),#0);
+   ec.Init(false,false,false,false,false,'','',15,mp);
    ActiveWn := wn;
 End;
 
@@ -318,8 +421,15 @@ Begin
    If subp <> nil Then del_panel(subp);
    If pan <> nil Then del_panel(pan);
    If sub <> nil Then delwin(sub);
-   If win <> nil Then delwin(win);
+   If (win <> nil) and (win <> stdscr) Then delwin(win);
    ec.Done;
+   ActiveWn := nscreen;
+End;
+
+{ make the window current for all normal crt requests }
+Procedure tnWindow.Active;
+Begin
+   ActiveWn := wn;
 End;
 
 { display the window and move to the top }
@@ -337,6 +447,7 @@ End;
 Procedure tnWindow.Hide;
 Begin
    ActiveWn := stdscr;
+{   ActiveWn := nStdScr.win;}
    visible := false;
    If subp <> nil Then hide_panel(subp);
    hide_panel(pan);
@@ -512,18 +623,18 @@ Begin
    getmaxyx(win,y,x);
    getbegyx(win,by,bx);
    Case hpos of
-      none   : x := bx+1;
+      none   : x := bx;
       left   : x := 1;
       right  : x := MaxCols - x;
       center : x := (MaxCols - x) div 2;
    End;
    Case vpos of
-      none   : y := by+1;
+      none   : y := by;
       top    : y := 1;
       bottom : y := MaxRows - y;
       center : y := (MaxRows - y) div 2;
    End;
-   move(x,y);
+   move(x+1,y+1);
 End;
 
 Procedure tnWindow.Scroll(ln : integer; dir : tnUpDown);
@@ -554,28 +665,6 @@ Begin
    ReadKey := nReadKey(wn);
 End;
 
-Function tnWindow.Readln : string;
-Begin
-   Readln := nReadln(wn);
-End;
-
-
-Procedure tnWindow.Write(s : string);
-Begin
-   tmp_b := dorefresh;
-   dorefresh := visible;
-   nWrite(wn,s);
-   dorefresh := tmp_b;
-End;
-
-Procedure tnWindow.Writeln(s : string);
-Begin
-   tmp_b := dorefresh;
-   dorefresh := visible;
-   nWriteln(wn,s);
-   dorefresh := tmp_b;
-End;
-
 Procedure tnWindow.WriteAC(x,y,att,c : longint);
 Begin
    tmp_b := dorefresh;
@@ -585,14 +674,10 @@ Begin
 End;
 
 Procedure tnWindow.FWrite(x,y,att,z : integer; s : string);
-Var tmp : pwindow;
 Begin
    tmp_b := dorefresh;
    dorefresh := visible;
-   tmp := ActiveWn;
-   ActiveWn := wn;
-   intFWrite(wn,x,y,att,z,s);
-   ActiveWn := tmp;
+   nFWrite(wn,x,y,att,z,s);
    dorefresh := tmp_b;
 End;
 
@@ -614,37 +699,151 @@ Begin
    Cols := nCols(wn);
 End;
 
-Function tnWindow.SEdit(x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
+Function tnWindow.GetX : integer;
+Var
+   x,y : longint;
+Begin
+   getbegyx(win,y,x);
+   GetX := x+1;
+End;
+
+Function tnWindow.GetY : integer;
+Var
+   x,y : longint;
+Begin
+   getbegyx(win,y,x);
+   GetY := y+1;
+End;
+
+Function tnWindow.IsFramed : boolean;
+Begin
+   IsFramed := hasframe;
+End;
+
+Function tnWindow.Edit(x,y,att,z,CursPos:Integer;es:String;Var ch : Char) : String;
+var
+   tmp_ec : tnec;
+Begin
+   { save global ec}
+   tmp_ec := nEC;
+   { init global ec to window ec }
+   nEC := ec;
+   Edit := nEdit(wn,x,y,att,z,CursPos,es,ch);
+   { re-init window ec to possible changed values }
+   ec.ClearMode := nEC.ClearMode;
+   ec.InsMode := nEC.InsMode;
+   { init global ec to saved }
+   nEC := tmp_ec;
+End;
+
+{ overload for longint }
+Function tnWindow.Edit(x,y,att,z,CursPos:Integer;es:LongInt;Var ch : Char) : LongInt;
+var
+   tmp_ec : tnec;
+Begin
+   tmp_ec := nEC;
+   nEC := ec;
+   Edit := nEdit(wn,x,y,att,z,CursPos,es,ch);
+   ec.ClearMode := nEC.ClearMode;
+   ec.InsMode := nEC.InsMode;
+   nEC := tmp_ec;
+End;
+
+{ overload for real }
+Function tnWindow.Edit(x,y,att,z,CursPos:Integer;es:Real;Var ch : Char) : Real;
+var
+   tmp_ec : tnec;
+Begin
+   tmp_ec := nEC;
+   nEC := ec;
+   Edit := nEdit(wn,x,y,att,z,CursPos,es,ch);
+   ec.ClearMode := nEC.ClearMode;
+   ec.InsMode := nEC.InsMode;
+   nEC := tmp_ec;
+End;
+
+Function tnWindow.EditNumber(x,y,att,wid,decm : integer;bgd : string;initv,minv,maxv : real;var esc : boolean) : real;
+var
+   tmp_ec : tnec;
+Begin
+   tmp_ec := nEC;
+   nEC := ec;
+   EditNumber := nEditNumber(wn,x,y,att,wid,decm,bgd,initv,minv,maxv,esc);
+   ec.ClearMode := nEC.ClearMode;
+   ec.InsMode := nEC.InsMode;
+   nEC := tmp_ec;
+End;
+
+Function tnWindow.EditNumber(x,y,att,wid,decm : integer;bgd : string;initv,minv,maxv : longint;var esc : boolean) : longint;
+var
+   tmp_ec : tnec;
+Begin
+   tmp_ec := nEC;
+   nEC := ec;
+   EditNumber := nEditNumber(wn,x,y,att,wid,decm,bgd,initv,minv,maxv,esc);
+   ec.ClearMode := nEC.ClearMode;
+   ec.InsMode := nEC.InsMode;
+   nEC := tmp_ec;
+End;
+
+Function tnWindow.EditDate(x,y,att : integer;initv : string;var esc : boolean) : string;
 var
-   tmp_ec : tec;
+   tmp_ec : tnec;
 Begin
-   tmp_ec.Init(nEC.FirstTime,nEC.IsHidden,nEC.InsMode,nEC.ExitMode,
-               nEC.Special);
-   nEC.Init(ec.FirstTime,ec.IsHidden,ec.InsMode,ec.ExitMode,
-            ec.Special);
-   SEdit := nSEdit(wn,x,y,att,z,CursPos,es,ch);
-   ec.Init(nEC.FirstTime,nEC.IsHidden,nEC.InsMode,ec.ExitMode,
-           ec.Special);
-   nEC.Init(tmp_ec.FirstTime,tmp_ec.IsHidden,tmp_ec.InsMode,tmp_ec.ExitMode,
-            tmp_ec.Special);
-   tmp_ec.Done;
+   tmp_ec := nEC;
+   nEC := ec;
+   EditDate := nEditDate(wn,x,y,att,initv,esc);
+   ec.ClearMode := nEC.ClearMode;
+   ec.InsMode := nEC.InsMode;
+   nEC := tmp_ec;
 End;
 
-{--------------------------- tEC -------------------------------}
+{--------------------------- tnEC -------------------------------}
 
-Constructor tEC.Init(ft,ih,im,em : boolean; s : string);
+Constructor tnEC.Init(ft,ih,im,em,ap : boolean;
+                                 s,p : string;
+                                  cc : integer;
+                                  mp : nChMap);
 Begin
-   FirstTime := ft;
+   ClearMode := ft;
    IsHidden := ih;
    InsMode := im;
    ExitMode := em;
+   AppendMode := ap;
    Special := s;
+   Picture := p;
+   CtrlColor := cc;
+   ChMap := mp;
 End;
 
-Destructor tEC.Done;
+Destructor tnEC.Done;
 Begin
 End;
 
+{ Add or replace a character map }
+Function tnEC.AddChMap(mp : nChMapStr) : integer;
+Var
+   i : integer;
+Begin
+   i := 0;
+   Repeat
+      inc(i);
+   Until (i > nMaxChMaps) or (Copy(ChMap[i],1,2) = Copy(mp,1,2)) or (ChMap[i] = '');
+   If i <= nMaxChMaps Then Begin
+      AddChMap := i;
+      ChMap[i] := mp;
+   End Else
+      AddChMap := 0;
+End;
+
+Procedure tnEC.ClrChMap(idx : integer);
+Begin
+   Case idx of
+      0 : FillChar(ChMap,SizeOf(ChMap),#0);
+      1..nMaxChMaps : ChMap[idx] := '';
+   End;
+End;
+
 {==========================================================================}
 
 { set the active window for write(ln), read(ln) }
@@ -748,7 +947,7 @@ Begin
    tmp_b := doRefresh;
    ActiveWn := win;
    doRefresh := false;
-   intFWrite(win,x,y,att,0,s);
+   nFWrite(win,x,y,att,0,s);
    ActiveWn := tmp;
    doRefresh := tmp_b;
 End;
@@ -1040,55 +1239,104 @@ End;
    Clear  = clear line up to x position
    s      = string to write
  -------------------------------------------------------------------}
-Procedure FWrite(col,row,attrib : integer; clear : integer; s : string);
-Const
-   ClearLine = { Following line is 80 Spaces }
-'                                                                                ';
-
-Var
+Procedure nFWrite(win : pwindow; col,row,attrib : integer; clear : integer; s : string);
+var
+   clr : array [0..255] of char;
    cs : string;
-   tmp,
    sub : pWindow;
    x,y,
+   mx,my,
    xx,yy : longint;
+   ctrl : boolean;
 Begin
    if Clear > 0 Then Begin
-      If Clear > 80 Then Clear := 80;
-      cs := Copy(ClearLine,1,(Clear-Col)-Length(s)+1);
+      FillChar(clr,SizeOf(clr),' ');
+      clr[SizeOf(clr)-1] := #0;
+      If Clear > MaxCols Then Clear := MaxCols;
+      cs := Copy(StrPas(clr),1,(Clear-Col)-Length(s)+1);
    End Else
       cs := '';
    s := s+cs;
    If s = '' Then Exit;
-   tmp := ActiveWn;
-   getyx(ActiveWn,yy,xx);
-   If Not internal_fwrite Then ActiveWn := stdscr;
-   getbegyx(ActiveWn,y,x);
-   sub := subwin(ActiveWn,1,Length(s),y+row-1,x+col-1);
-   ActiveWn := tmp;
+   getyx(win,yy,xx);
+   getbegyx(win,y,x);
+   getmaxyx(win,my,mx);
+   If Length(s) > mx Then s := Copy(s,1,mx);
+   sub := subwin(win,1,Length(s),y+row-1,x+col-1);
    If sub = nil Then Exit;
+   cs := s;
+   ctrl := false;
+   { look for embedded control characters }
+   For x := 1 to Length(s) Do Begin
+      If s[x] in [#0..#31] Then Begin
+         s[x] := ' ';
+         ctrl := true;
+      End;
+   End;
    wbkgd(sub,COLOR_PAIR(SetColorPair(Attrib)));
    If isbold(Attrib) then
       wattr_on(sub,A_BOLD);
    mvwaddstr(sub,0,0,StrPCopy(ps,s));
+   { highlight the embedded control characters substitutes }
+   If ctrl Then Begin
+      { nEC is always the current edit control object }
+      If Attrib <> nEC.CtrlColor Then
+         nWinColor(sub,nEC.CtrlColor)
+      Else Begin
+         { reverse the highlight color if same as current attribute }
+         bg := nEC.CtrlColor div 16;
+         fg := nEC.CtrlColor - (bg * 16);
+         While bg > 7 Do dec(bg,8);
+         While fg > 7 Do dec(fg,8);
+         nWinColor(sub,(fg*16)+bg);
+      End;
+      For x := 1 to Length(cs) Do Begin
+         If cs[x] in [#0..#31] Then
+            mvwaddch(sub,0,x-1,ord(cs[x])+64);
+      End;
+   End;
    If doRefresh Then wrefresh(sub);
    delwin(sub);
-   wmove(ActiveWn,yy,xx);
+   wmove(win,yy,xx);
 End;
 
-{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
-{                            String Editor                           }
+{ overload - no pointer }
+Procedure nFWrite(col,row,attrib : integer; clear : integer; s : string);
+Begin
+   nFWrite(ActiveWn,col,row,attrib,clear,s);
+End;
+
+{ compatibility for the old function name }
 Function nSEdit(win : pwindow; x,y,att,z,CursPos:integer;
                 es:string;var ch : char) : string;
+Var
+   s : string;
+Begin
+   s := nEdit(win,x,y,att,z,CursPos,es,ch);
+   nSEdit := s;
+End;
+
+{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
+{                            String Editor                           }
+Function nEdit(win : pwindow; x,y,att,z,CursPos:integer;
+               es:string;var ch : char) : string;
 Var
    ZMode,
+   AppendMode,
    SEditExit : boolean;
+   prvx,
+   prvy,
+   pidx,
+   pres,
    Index : integer;
+   ts,
    hes : string;
+   isextended : boolean;
 
 {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 Procedure NewString;
 BEGIN
-   nSEdit := es;
+   nEdit := es;
    hes := es;
    FillChar(hes[1],Length(hes),'*');
 END;
@@ -1100,9 +1348,9 @@ Begin
    xx := nWhereX(win);
    yy := nWhereY(win);
    If nEC.IsHidden Then
-      intFWrite(win,x,y,att,z,hes)
+      nFWrite(win,x,y,att,z,hes)
    Else
-      intFWrite(win,x,y,att,z,es);
+      nFWrite(win,x,y,att,z,es);
    nGotoXY(win,xx,yy);
 End;
 
@@ -1114,27 +1362,61 @@ End;
 
 {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 Procedure WriteChar;
+var s : string;
 Begin
-   If nWhereX(win) >= Length(es)+x Then Repeat
+   ts := es;
+   If AppendMode Then Begin
       es := es + ' ';
-   Until Length(es)+X-1 = nWhereX(win);
-   If Length(es)+X-1 = nWhereX(win) Then Index := Length(es);
+      Index := Length(es);
+   End Else Begin
+      If nWhereX(win) >= Length(es)+x Then Repeat
+         es := es + ' ';
+      Until Length(es)+x-1 = nWhereX(win);
+      If es = '' Then es := ' ';
+      If Length(es)+x-1 = nWhereX(win) Then Index := Length(es);
+   End;
    es[Index] := ch;
-   If nEC.IsHidden Then Ch := '*';
-   intFWrite(win,nWhereX(win),nWhereY(win),Att,0,Ch);
-   If (Index < Z-X+1) or not ZMode Then Begin
-      Index := Index+1;
-      nGotoXY(win,X+Index-1,Y);
+   s := Copy(es,1,Index);
+   If nCheckPxPicture(s,nEC.Picture,pidx) <> 0 Then Begin
+      { no error, picture satisfied }
+      If (Length(s) > Length(es)) or
+         ((Length(s) = Length(es)) and (s <> es)) Then Begin
+         { expanded/changed by picture }
+         es := s;
+      End;
+      If pidx > Index Then Begin
+         If pidx > Length(es) Then pidx := Length(es);
+         If pidx > Index Then Index := pidx;
+      End;
+   End Else Begin
+      { error, did not fit the picture }
+      Sound(1000);
+      Delay(50);
+      NoSound;
+      es := ts;
+      Dec(Index);
    End;
-   Ch := #255;{ Set Ch to No Execute Character }
    NewString;
+   WriteString;
+   If (Index < z-x+1) or not ZMode Then Begin
+      Index := Index+1;
+      nGotoXY(win,x+Index-1,y);
+   End;
 End;
 
 {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 Procedure EInsert;            { Insert      }
 Begin
    If Length(es) < Z-X+1 Then Begin
+      ts := es;
       Insert(' ',es,Index);
+      If nCheckPXPicture(es,nEC.Picture,pidx) = 0 Then Begin
+         Sound(1000);
+         Delay(50);
+         NoSound;
+         es := ts;
+         ch := #255;
+      End;
       NewString;
       WriteString;
    End;
@@ -1143,7 +1425,15 @@ End;
 {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 Procedure EDelete;            { Delete      }
 Begin
+   ts := es;
    Delete(es,Index,1);
+   If nCheckPXPicture(es,nEC.Picture,pidx) = 0 Then Begin
+      Sound(1000);
+      Delay(50);
+      NoSound;
+      es := ts;
+      ch := #255;
+   End;
    NewString;
    WriteString;
 End;
@@ -1166,11 +1456,10 @@ End;
 {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 Procedure ELeftArrow;         { Left Arrow  }
 Begin
-  Index := Index - 1;
-  If Index < 1 Then
-     Index := 1
-  Else
-     nGotoXY(win,nWhereX(win)-1,nWhereY(win));
+   If nWhereX(win) > x Then Begin
+      dec(Index);
+      nGotoXY(win,nWhereX(win)-1,nWhereY(win));
+   End;
 End;
 
 {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
@@ -1186,8 +1475,9 @@ End;
 Procedure EEnd;               { End         }
 Begin
    Index := Length(es)+1;
-   If Index >= z-x+1 Then Index := Length(es);
+   If Index > z-x+1 Then Index := Length(es);
    If Index < 1 Then Index := 1;
+   If Index > MaxCols Then Index := MaxCols;
    nGotoXY(win,x+(Index-1),y);
 End;
 
@@ -1262,18 +1552,18 @@ Begin
    nGotoXY(win,x+Index-1,y);
 End;
 
-{~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
-Procedure CheckForWriteChar;
+{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
+Procedure CheckForWriteChar(embed : boolean);
 Begin
-   If Not (Ch In [#8,#9,#27,#127,#255]) Then Begin
-      If (ch in [#10,#13]) {and not ControlKey} Then exit;
-      If nEC.FirstTime Then Begin
+   If embed or Not (Ch In [#27,#255]) Then Begin
+      If (ch in [#10,#13]) and (not embed) {and not ControlKey} Then exit;
+      If nEC.ClearMode Then Begin
          es := '';
          WriteString;
          nGotoXY(win,X,Y);
          Index := 1;
          WriteChar;
-         nEC.FirstTime := False;
+         nEC.ClearMode := False;
       End Else Begin
          If nEC.InsMode Then Begin
             EInsert;
@@ -1286,6 +1576,8 @@ End;
 {~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
 Procedure ProcessSpecialKey;
 begin
+   If ch = #129 Then ch := #68; { Linux, map Esc/0 to F10 }
+
    Case ch of
    #16..#25,
    #30..#38,
@@ -1316,6 +1608,7 @@ End;
 Procedure ProcessNormalKey;
 Var
    i : integer;
+   ctrl : boolean;
 begin
    For i := 1 to Length(nEC.Special) Do Begin
       If ch = nEC.Special[i] Then Begin
@@ -1323,17 +1616,122 @@ begin
          Exit;
       End;
    End;
+   ctrl := false;
    case ch of
-        #8 : Begin nEC.FirstTime := False;EBackSpace;End;
-        #9 : ECtrlRightArrow;
-      #127 : Begin nEC.FirstTime := False;ETurboBackSpace;End;
+      #0..#15,
+      #17..#31 : Begin
+         nEC.ClearMode := False;
+         Case ch of
+            #1 : EHome;
+            #5 : EEnd;
+            #2 : ELeftArrow;
+            #6 : ERightArrow;
+           #19 : ECtrlLeftArrow;
+            #4 : ECtrlRightArrow;
+            #7 : EDelete;
+            #9 : EInsMode;
+            #8 : EBackSpace;
+           #10 : ch := #13;
+           #13 : Begin
+                    pres := nCheckPxPicture(es,nEC.Picture,pidx);
+                    If pres <> 2 Then Begin
+                       Sound(1000);
+                       Delay(50);
+                       NoSound;
+                       ch := #255;
+                    End;
+                 End;
+           #27 : If KeyPressed Then Begin
+                    { covers up a Linux peculiarity where the next }
+                    { character typed bleeds through with esc/1..9 }
+                    nGotoXY(win,prvx,prvy);
+                    WriteString;
+                    ch := ReadKey;
+                    { make it a function key }
+                    If ch in ['1'..'9'] Then
+                       ch := Char(Ord(ch)+10)
+                    Else ch := #27;
+                    SEditExit := true;
+                 End;
+         End;
+         Exit;
+      End;
+      #16 : Begin
+               { embed control characters in the string }
+               ch := UpCase(ReadKey);
+               If ch in ['@','2','A'..'Z'] Then Begin
+                  ctrl := true;
+                  If ch = '2' Then ch := '@';
+                  ch := Char(Ord(ch)-64);
+               End;
+            End;
+     #127 : Begin nEC.ClearMode := False;ETurboBackSpace;Exit;End;
    end;
-   CheckForWriteChar;
+   CheckForWriteChar(ctrl);
+   ch := #0;
 end;
 
+{-----------------------------------------------------------------------
+  Map a keystroke to another character, normal or extended.
+
+  The maps are 4 character strings interpreted as 2 sets of character
+  pairs that represent the following:
+
+  1st char - If it is #0 then it is an extended char. Use the 2nd
+             character to identify.
+  2nd char - Only used if 1st char is #0.
+
+  The first pair of the string is the actual key pressed.
+  The second pair is what that key should be become.
+
+  #0#59 = F1, extended key
+  #59#0 = ; , normal key
+
+  So a map of #0#59#59#0 maps the F1 key to the ; key,
+          and #0#59#0#60 maps the F1 key to the F2 key,
+          and #0#59#0#0 maps the F1 key to a null.
+
+   Examples:
+     #0#59#0#60 = map F1 to F2
+     #1#0#0#59  = map ^A to F1
+     #0#59#1#0  = map F1 to ^A
+     #0#59#0#0  = map F1 to ^@ (null)
+     #0#0#0#59  = map ^@ to F1
+     #97#0#65#0 = map a to A
+}
+Procedure MapKey(var ch : char;var eflag : boolean);
+Var
+   i : integer;
+   s2 : string[2];
+   s4 : string[4];
+Begin
+   { look for a character map assignment }
+   i := 0;
+   s4 := #0#0#0#0;
+   Case eflag of
+      true  : s2 := #0+ch;
+      false : s2 := ch+#0;
+   End;
+   Repeat
+      inc(i);
+   Until (i > nMaxChMaps) or (pos(s2,nEC.ChMap[i]) = 1);
+   { if found, then re-assign ch to the mapped key }
+   If i <= nMaxChMaps Then Begin
+      system.Move(nEC.ChMap[i,1],s4[1],Length(nEC.ChMap[i]));
+      s2 := Copy(s4,3,2);
+      eflag := (s2[1] = #0);
+      Case eflag of
+         true  : ch := s2[2];
+         false : ch := s2[1];
+      End;
+      If ch = #0 Then eflag := false;
+   End;
+End;
+
 {============================================================================}
 Begin
    SEditExit := nEC.ExitMode;
+   AppendMode := nEC.AppendMode;
    ZMode := z <> 0;
    If CursPos > Length(es)+x Then
       Index := Length(es)+1                { End Of String    }
@@ -1343,44 +1741,332 @@ Begin
    WriteString;
    nGotoXY(win,CursPos,y);
    Repeat
+      prvx := nWhereX(win); { save for ProcessNormalKey }
+      prvy := nWhereY(win);
       If Not ZMode then z := x+length(es);
       ch := ReadKey;
-      If ch = #0 Then Begin
+      isextended := (ch = #0);
+      If isextended Then
          ch := ReadKey;
-         ProcessSpecialKey;
-      End Else
+      MapKey(ch,isextended);
+      If isextended Then
+         ProcessSpecialKey
+      Else
          ProcessNormalKey;
-   Until (ch In [#10,#13,#27]) or SEditExit;
-   If ch = #10 Then ch := #13;
-   nEC.FirstTime := False;
+   Until (ch In [#13,#27]) or SEditExit;
+   nEC.ClearMode := False;
    NewString;
-End;{ of nSEdit }
+End;{ of nEdit }
 
+{ nEdit using currently active window }
+Function nEdit(x,y,att,z,CursPos:integer;
+               es:string;var ch : char) : string;
+Begin
+   nEdit := nEdit(ActiveWn,x,y,att,z,CursPos,es,ch);
+End;
+
+{ overload for longint type }
+Function nEdit(x,y,att,z,CursPos:integer;
+               es:longint;var ch : char) : longint;
+Begin
+   nEdit := nEdit(ActiveWn,x,y,att,z,CursPos,es,ch);
+End;
+
+{ with pointer }
+Function nEdit(win : pwindow; x,y,att,z,CursPos:integer;
+                es:LongInt;var ch : char) : LongInt;
+Var
+   savpic,
+   ess : string;
+   esv,
+   err : longint;
 Begin
-   nEC.Init(false,false,false,false,'');
+   Str(es:0,ess);
+   savpic := nEC.Picture;
+   If savpic = '' Then nEC.Picture := '[-]#*#';
+   ess := nEdit(win,x,y,att,z,CursPos,ess,ch);
+   nEC.Picture := savpic;
+   val(ess,esv,err);
+   nEdit := esv;
+End;
+
+{ overload for real type }
+Function nEdit(x,y,att,z,CursPos:integer;
+               es:real;var ch : char) : real;
+Begin
+   nEdit := nEdit(ActiveWn,x,y,att,z,CursPos,es,ch);
+End;
+
+{ with pointer }
+Function nEdit(win : pwindow; x,y,att,z,CursPos:integer;
+                es:Real;var ch : char) : Real;
+Var
+   savpic,
+   ess : string;
+   esv : real;
+   i,
+   err : Integer;
+Begin
+   Str(es:0:12,ess);
+   While ess[Length(ess)] = '0' Do Delete(ess,Length(ess),1);
+   savpic := nEC.Picture;
+   If savpic = '' Then Begin
+      Case nDecFmt of
+         nUS   : nEC.Picture := '[+,-]#*#[[.*#][{E,e}[+,-]#[#][#][#]]]';
+         nEURO : Begin
+                    nEC.Picture := '[+,-]#*#[[;,*#][{E,e}[+,-]#[#][#][#]]]';
+                    For i := 1 to Length(ess) Do
+                       If ess[i] = '.' Then ess[i] := ',';
+                 End;
+      End;
+   End;
+   ess := nEdit(win,x,y,att,z,CursPos,ess,ch);
+   nEC.Picture := savpic;
+   For i := 1 to Length(ess) Do If ess[i] = ',' Then ess[i] := '.';
+   val(ess,esv,err);
+   nEdit := esv;
+End;
+
+{ And now some sugar for Rainer Hantsch! }
+{------------------------------------------------------------------------
+  This is a right justified number editor. As a digit is typed, the
+  existing number string gets pushed left and the new digit is appended.
+  If decimal columns are specified, then pressing <space> will enter the
+  decimal character (. or ,). A background string can be specified that
+  fills the empty spaces.
+ ------------------------------------------------------------------------}
+Function nEditNumber(
+       win : pwindow;
+         x,              { edit field start column }
+         y,              { edit field start row }
+       att,              { edit field color attribute }
+       wid,              { edit field width }
+      decm : integer;    { number of decimal columns }
+       bgd : string;     { background string -
+                           if bgd = '', then no background
+                           if bgd = a single character, then is used as the
+                           background fill character.
+                           if bgd length is longer than wid, then the entire
+                           bgd string is used as the background.}
+     initv,              { initial value }
+      minv,              { range minimum value }
+      maxv  : real;      { range maximum value }
+   var esc : boolean     { if Esc key pressed = true, else = false }
+) : real;
+
+Const
+   { up to 12 decimal places }
+   decs : string = '[#][#][#][#][#][#][#][#][#][#][#][#]';
+Var
+   r : real;
+   s,s1,s2 : string;
+   i,
+   e,
+   bc,
+   bx : integer;
+   ch : char;
+   fill : array [0..255] of char;
+   tmp_ec : tnEC;
+Begin
+   tmp_ec := nEC;
+   nEC.ExitMode := true;
+   nEC.AppendMode := true;
+   nEC.ClrChMap(0);
+   nEC.AddChMap(#7#0#0+Char(nKeyDel));
+   nEC.AddChMap(#8#0#0+Char(nKeyDel));
+   If decm > (Length(decs) div 3) Then
+      decm := (Length(decs) div 3);
+   If decm >= wid Then decm := (wid - 1);
+   If decm > 0 Then Begin
+      nEC.Picture := '[-]*#[{.}'+Copy(decs,1,(decm*3))+']';
+      If nDecFmt = nEURO Then Begin
+         nEC.Picture[8] := ',';
+         Insert(';',nEC.Picture,8);
+         nEC.AddChMap('.'+#0+','+#0);
+      End;
+   End Else
+      nEC.Picture := '[-]*#';
+   If bgd = '' Then Begin
+      bgd := ' ';
+      bc := att;
+   End Else
+      bc := nEC.CtrlColor;
+   If Length(bgd) < wid Then Begin
+      FillChar(fill,wid,bgd[1]);
+      fill[wid] := #0;
+      bgd := StrPas(fill);
+   End;
+   bx := x;
+   If Length(bgd) > wid Then inc(x);
+   str(initv:wid:decm,s);
+   While s[1] = ' ' Do Delete(s,1,1);
+   If Pos('.',s) <> 0 Then
+      While s[Length(s)] = '0' Do Delete(s,Length(s),1);
+   If decm = 0 Then Delete(s,Pos('.',s),1);
+   If nDecFmt = nEURO Then For i := 1 to Length(s) Do
+      If s[i] = '.' Then s[i] := ',';
+   Repeat
+      nFWrite(win,bx,y,bc,bx+Length(bgd)-(x-bx),copy(bgd,1,wid-length(s)+(x-bx)));
+      If x > bx Then
+         nFWrite(win,x+wid,y,bc,0,copy(bgd,wid+2,length(bgd)));
+      s1 := nEdit(win,x+wid-Length(s),y,att,x+wid-1,x+wid-1,s,ch);
+      s2 := s1;
+      If nDecFmt = nEURO Then For i := 1 to Length(s2) Do
+         If s2[i] = ',' Then s2[i] := '.';
+      val(s2,r,e);
+      If (s1 = '') or ((e = 0) and (r >= minv) and (r <= maxv)) Then
+         s := s1
+      Else
+         If ch <> #27 then Begin
+            ch := #0;
+            Sound(1000);
+            Delay(50);
+            NoSound;
+         End;
+      nEC.AppendMode := Length(s) < wid;
+   Until ch in [#13,#27];
+   esc := (ch = #27);
+   nEditNumber := r;
+   nEC := tmp_ec;
+End;
+
+{ overload - real, no pointer }
+Function nEditNumber(
+   x,y,att,wid,decm : integer;
+                bgd : string;
+              initv,
+               minv,
+               maxv : real;
+            var esc : boolean) : real;
+Begin
+   nEditNumber := nEditNumber(ActiveWn,x,y,att,wid,decm,bgd,initv,minv,maxv,esc);
+End;
+
+{ overload for longint }
+Function nEditNumber(
+                win : pwindow;
+   x,y,att,wid,decm : integer;
+                bgd : string;
+              initv,
+               minv,
+               maxv : longint;
+            var esc : boolean) : longint;
+Var
+   r : real;
+Begin
+   r := nEditNumber(win,x,y,att,wid,0,bgd,Real(initv),Real(minv),Real(maxv),esc);
+   nEditNumber := Trunc(r);
+End;
+
+{ overload - longint, no pointer }
+Function nEditNumber(
+   x,y,att,wid,decm : integer;
+                bgd : string;
+              initv,
+               minv,
+               maxv : longint;
+            var esc : boolean) : longint;
+Var
+   r : real;
+Begin
+   r := nEditNumber(ActiveWn,x,y,att,wid,0,bgd,Real(initv),Real(minv),Real(maxv),esc);
+   nEditNumber := Trunc(r);
+End;
+
+{ More sugar for Rainer }
+{------------------------------------------------------------------------
+  A date string editor.
+ ------------------------------------------------------------------------}
+Function nEditDate(
+       win : pwindow;
+         x,           { edit field start column }
+         y,           { edit field start row }
+       att : integer; { edit field color attribute }
+      init : string;     { initial value }
+   var esc : boolean     { if Esc key pressed = true, else = false }
+) : string;
+
+Const
+   wid = 10;
+Var
+   s : string;
+   i : integer;
+   ch : char;
+   tmp_ec : tnEC;
+
+Begin
+   tmp_ec := nEC;
+   nEC.InsMode := false;
+   nEC.ClearMode := false;
+   nEC.ExitMode := false;
+   nEC.AppendMode := false;
+   Case nDecFmt of
+      nUS :  Begin
+         nEC.Picture := '{#,m,M}{#,m,M}/{#,d,D}{#,d,D}/{#,y,Y}{#,y,Y}{#,y,Y}{#,y,Y}';
+         s := 'mm/dd/yyyy';
+      End;
+      nEURO : Begin
+         nEC.Picture := '{#,d,D}{#,d,D}/{#,m,M}{#,m,M}/{#,y,Y}{#,y,Y}{#,y,Y}{#,y,Y}';
+         s := 'dd/mm/yyyy';
+      End;
+   End;
+   If nCheckPxPicture(init,nEC.Picture,i) <> 0 Then
+      system.move(init[1],s[1],Length(init));
+   nEC.AddChMap(#7#0#0+Char(nKeyLeft));
+   nEC.AddChMap(#8#0#0+Char(nKeyLeft));
+   nEC.AddChMap(#0+Char(nKeyDel)+#0+Char(nKeyLeft));
+   Repeat
+      s := nEdit(x,y,att,x+9,x,s,ch);
+      If ch = #13 Then Begin
+         For i := 1 to Length(s) Do
+            If s[i] in ['m','d','y'] Then ch := #0;
+      End;
+   Until ch in [#13,#27];
+   esc := (ch = #27);
+   nEditDate := s;
+   nEC := tmp_ec;
+End;
+
+{ overload - no pointer }
+Function nEditDate(x,y,att : integer;initv : string;var esc : boolean) : string;
+Begin
+   nEditDate := nEditDate(ActiveWn,x,y,att,initv,esc);
+End;
+
+{ A one-line procedural wrapper }
+Procedure nMakeWindow(
+    var win : tnWindow;
+    x1,y1,
+    x2,y2,
+    ta,ba,ha : integer;
+    hasframe : boolean;
+    hdrpos : tnJustify;
+    hdrtxt : string);
+Begin
+   win.init(x1,y1,x2,y2,ta,hasframe,ba);
+   If hdrtxt <> '' Then win.PutHeader(hdrtxt,ha,hdrpos);
+End;
+
+{----------------------- initialize the unit!------------------------- }
+Begin
+   FillChar(_chmap,SizeOf(_chmap),#0);
+   nEC.Init(false,false,false,false,false,'','',15,_chmap);
    { load the color pairs array with color pair indices (0..63) }
    For bg := 0 to 7 Do For fg := 0 to 7 do cp[bg,fg] := (bg*8)+fg;
    { initialize ncurses }
-   If StartCurses(ActiveWn) Then
-      nscreen := ActiveWn
-   Else
+   If StartCurses(ActiveWn) Then Begin
+      { save pointer to ncurses stdscr }
+      nscreen := ActiveWn;
+      { create the default full screen window object }
+      nStdScr.Init(1,1,MaxCols,MaxRows,7,false,0);
+   End Else
       Halt;
 
-   SubWn := nil;
-   TextMode(LastMode);
-
-   { Redirect the standard output }
-   assigncrt(Output);
-   Rewrite(Output);
-   TextRec(Output).Handle:=StdOutputHandle;
-   { Redirect the standard input }
-   assigncrt(Input);
-   Reset(Input);
-   TextRec(Input).Handle:=StdInputHandle;
+   { crtassign }
+   nInit;
 
    { set the unit exit procedure }
    ExitSave := ExitProc;
    ExitProc := @nExit;
 
 End. { of Unit nCrt }
- 

+ 35 - 29
packages/ncurses/ocrt_demo.pp

@@ -1,7 +1,7 @@
 Program ocrt_demo;
 {---------------------------------------------------------------------------
                                  CncWare
-                           (c) Copyright 1999
+                         (c) Copyright 1999-2000
  ---------------------------------------------------------------------------
   Filename..: ocrt_demo.pp
   Programmer: Ken J. Wright
@@ -18,6 +18,7 @@ Program ocrt_demo;
                         | 2) Renamed from ncrt_demo to ocrt_demo.
                         | 3) Added some standard crt code at beginning.
   1.03 | 01/06/00 | kjw | Some minor changes for ncrt mods.
+  1.04 | 06/27/00 | kjw | Changes for ncrt mods.
 ------------------------------------------------------------------------------
 }
 uses oCrt;
@@ -39,14 +40,14 @@ Begin
    TextAttr := TextAttr + blink;
    ClrScr;
    GotoXY(2,35);
-   Writeln(1.0:0:4,' This is a test!');
+   Writeln(1.0:0:4,' This should be blinking text');
    Window(10,10,70,15);
    TextAttr := TextAttr - blink;
    TextBackground(2);
    ClrScr;
    s := ' : ';
    for i := 1 to 6 do
-   writeln(i:0,s,'this is a test');
+   writeln(i:0,s,'No blinking here');
    writeln('Press Enter');
    readln(s);
    TextBackground(3);
@@ -72,21 +73,21 @@ Begin
    stdscr := nscreen;
    nClrScr(stdscr,7);
    nDrawBox(stdscr,btSingle,1,1,80,3,31);
-   FWrite(27,2,30,0,'nCrt Demonstration Program');
+   nFWrite(27,2,30,0,'nCrt Demonstration Program');
    nNewWindow(win1,9,9,71,16);
    nClrScr(win1,95);
    nWriteScr(win1,3,2,95,'This is a background window.');
    nWriteScr(win1,10,3,95,'It was built first, then displayed later.');
-   FWrite(1,24,15,80,'Enter some text, press [Enter]');
+   nFWrite(stdscr,1,24,15,80,'Enter some text, press [Enter]');
    nWindow(win,10,10,70,15);
    nClrScr(win,31);
    nGotoXY(win,1,1);
    s := nReadln(win);
    If s <> 'oop' Then Begin { skip right to OOP section? }
-      FWrite(1,24,15,80,'Enter some more text, press [Enter]');
+      nFWrite(stdscr,1,24,15,80,'Enter some more text, press [Enter]');
       nGotoXY(win,nWhereX(win),nWhereY(win));
       s := nReadln(win);
-      FWrite(1,24,79,80,'Please wait...');
+      nFWrite(stdscr,1,24,79,80,'Please wait...');
       nGotoXY(win,1,1);
       Delay(500);
       nDelLine(win);
@@ -101,10 +102,10 @@ Begin
       { force nCrt to use full screen }
       nSetActiveWin(stdscr);
       ClrScr;
-      FWrite(1,24,14,80,'Enter even more text, press [Enter]');
+      nFWrite(1,24,14,80,'Enter even more text, press [Enter]');
       s := nReadln(stdscr);
       nClrScr(win,47);
-      FWrite(1,24,11,80,'Press some keys, followed by [Esc]');
+      nFWrite(1,24,11,80,'Press some keys, followed by [Esc]');
       nGotoXY(win,5,1);
       x := nWhereX(win);
       y := nWhereY(win);
@@ -120,6 +121,8 @@ Begin
          InsLine;
          dec(i);
       End;
+      { turn on oCrt keyboard echo }
+      nEcho(true);
       str(x:0,s);
       nWrite(win,'x = '+s+', ');
       str(y:0,s);
@@ -127,7 +130,7 @@ Begin
       nWriteln(stdscr,'press a key...');
       readkey;
       nDrawBox(stdscr,btSingle,11,11,69,14,63);
-      FWrite(30,11,79,49,' nCrt Demo Program');
+      nFWrite(30,11,79,49,' nCrt Demo Program');
       nDelWindow(win);
       nDelWindow(win1);
       nWindow(win,2,2,79,24);
@@ -137,45 +140,47 @@ Begin
    End;
    { and now for some object oCrt }
    win := nscreen;
-   New(win11,Init(1,1,80,25,31,true,30));
+   New(win11,Init(1,1,nStdScr.Cols,nStdScr.Rows,31,true,30));
    win11^.PutHeader(' Now for some OOP with nCrt! ',79,center);
    win11^.DrawBox(1,1,1,78,3,62);
    New(win22,Init(20,7,60,17,47,false,0));
    win33.Init(30,15,50,20,79,true,78);
    win33.PutHeader(' Little Window ',15,right);
-   win33.Writeln('And here is window #3');
+   Writeln('And here is window #3');
    win11^.Show;
-   win11^.GotoXY(2,2);
-   win11^.Write('Please press a key...');
-   win11^.ReadKey;
+   GotoXY(2,2);
+   Write('Please press a key...');
+   ReadKey;
    msgbox.init(25,11,55,13,47,true,47);
    s := 'Please enter a string';
    msgbox.FWrite((msgbox.cols-length(s)) div 2,1,46,0,s);
    msgbox.Show;
-   win11^.GotoXY(1,10);
+   win11^.Active;
+   GotoXY(1,10);
    msgbox.Show;
-   { turn on oCrt keyboard echo }
-   nEcho(true);
-   s := win11^.Readln;
+   win11^.Active;
+   Readln(s);
    msgbox.Hide;
    win22^.Show;
-   win22^.Writeln(s);
+   Writeln(s);
    Delay(2000);
    win11^.Hide;
-   win22^.Writeln('Hiding window 1...');
+   win22^.Active;
+   Writeln('Hiding window 1...');
    Delay(2000);
    win33.Show;
    Delay(2000);
    win11^.Show;
-   win11^.Writeln('Showing window 1');
+   Writeln('Showing window 1');
    win22^.Show;
-   win22^.Writeln('Showing window 2');
+   Writeln('Showing window 2');
    win33.Show;
-   win33.Write('Showing window 3');
+   Write('Showing window 3');
    nKeypressed(2000);
    While Keypressed Do Readkey;
    win11^.Hide;
-   win33.Write('Hiding window 1');
+   win33.Active;
+   Write('Hiding window 1');
    win22^.PutFrame(62);
    win22^.PutHeader(' New frame color ',63,center);
    win22^.Show;
@@ -183,7 +188,8 @@ Begin
    nKeypressed(3000);
    While Keypressed Do Readkey;
    win22^.Hide;
-   win33.Write('Hiding window 2');
+   win33.Active;
+   Write('Hiding window 2');
    nKeypressed(2000);
    While Keypressed Do Readkey;
    win33.SetColor(47);
@@ -197,8 +203,8 @@ Begin
       dec(y);
       str(i:0,s);
       win33.Move(x,y);
-      win33.Writeln('Moved by '+s);
-      FWrite(1,25,63,80,'Moved by '+s);
+      Writeln('Moved by '+s);
+      nFWrite(stdscr,1,nStdScr.Rows,63,80,'Moved by '+s);
       Delay(250);
    End;
    win33.Align(center,none);
@@ -215,5 +221,5 @@ Begin
    Dispose(win22,Done);
    win33.Done;
    msgbox.Done;
-
+   ClrScr;
 End.