home *** CD-ROM | disk | FTP | other *** search
- { ********** Window Management Services ********** }
- { ********** Version 1.0 8/06/84 ********** }
-
- { (c) Copyright 1984 Timothy E. Ide All commercial rights reserved }
-
- { ********** constant and variable declarations ********** }
-
- const
- _wxa = 1; {min col}
- _wya = 1; {min row}
- _wxz = 80; {max col}
- _wyz = 23; {max row}
- _wlz = 1840; {max length}
- _wxv : set of byte = [_wxa.._wxz];
- _wyv : set of byte = [_wya.._wyz];
- _wzr : integer = 0;
-
- type
- _wbs = string[4]; {border character string}
- _wpt = ^_wcb;
- _wcb = record {window control block}
- _wno, {window number}
- _wx, {window col}
- _wy, {window row}
- _ww, {window width}
- _wh : byte; {window height}
- _wxo, {window origin col}
- _wyo, {window origin row}
- _wl : integer; {window length}
- _wb : boolean; {window border flag}
- _wbc : array [1..4] of char; {window border char}
- _wc, {window cols}
- _wr : byte; {window rows}
- _wcv : set of _wxa.._wxz; {available width}
- _wrv : set of _wya.._wyz; {available height}
- _wrp : array [_wya.._wyz] of integer; {window row positions}
- _wnx : _wpt; {next pointer}
- _wch : array [1.._wlz] of char; {window contents}
- end;
- _wst = string[_wxz];
-
- var
- { global variables available to user }
- wi_status : boolean; { true = success, false = failure }
- wi_eow, wi_eoln : boolean;
-
- { for use by window management services }
- _whd, _wp0, _wp1 : _wpt;
-
-
-
- { ********** internal function and procedure declarations ********** }
-
- function _wi_find ( no : integer ) : boolean; forward;
- procedure _wi_stb ( var c; l : integer; var st : _wst); forward;
- procedure _wi_bord1 ( var b : _wbs ); forward;
- procedure _wi_bord2; forward;
- procedure _wi_out ( var no : integer;
- var st : _wst; out : boolean ); forward;
- procedure _wi_outln ( var no : integer;
- var st : _wst; out : boolean ); forward;
- procedure _wi_getst ( l, x, y : integer; var s : _wst ); forward;
- procedure _wi_inp ( var no, l : integer;
- var st : _wst; inp : boolean ); forward;
- procedure _wi_inpln ( var no, l : integer;
- var st : _wst; inp : boolean ); forward;
- procedure _wi_sher ( var no : integer; show : boolean ); forward;
-
-
-
- { ********** Window Management Services ********** }
-
- { ********* wi_delln ********** }
- { delete line from window }
-
- procedure wi_delln ( no, y : integer );
- var
- i : integer;
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- if not (y in _wrv) then
- wi_status := false
- else begin
- for i := y to pred(_wr) do
- move(_wch[(succ(_wrp[succ(i)]))],_wch[(succ(_wrp[i]))],_wc);
- fillchar(_wch[(succ(_wrp[_wr]))],_wc,' ');
- _wx := 1;
- _wy := y;
- wi_status := true;
- end;
- end;
- end;
- end; {wi_delln}
-
-
- { ********** wi_insln ********** }
- { insert line into window }
-
- procedure wi_insln ( no, y : integer );
- var
- i : integer;
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- if not (y in _wrv) then begin
- if (y < 1) then
- wi_status := false
- else begin
- wi_delln(no,1);
- _wy := _wr;
- end
- end
- else begin
- for i := _wr downto y do
- move(_wch[(succ(_wrp[pred(i)]))],_wch[(succ(_wrp[i]))],_wc);
- fillchar(_wch[(succ(_wrp[y]))],_wc,' ');
- _wy := y;
- _wx := 1;
- wi_status := true;
- end;
- end;
- end;
- end; {wi_insln}
-
-
- { ********** wi_clreol ********** }
- { clear from current window position to end of line }
-
- procedure wi_clreol ( no : integer );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- if (_wy in _wrv) and (_wx in _wcv) then begin
- fillchar(_wch[(_wrp[_wy]+_wx)],(succ(_wc-_wx)),' ');
- wi_status := true;
- end;
- end;
- end;
- end; {wi_clreol}
-
-
- { ********** wi_clear ********* }
- { blank window contents }
-
- procedure wi_clear ( no : integer );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- fillchar(_wch[1],_wl,' ');
- _wx := 1;
- _wy := 1;
- _wi_bord2;
- end;
- wi_status := true;
- end;
- end; {wi_clear}
-
-
- { ********* wi_home ********** }
- { set window position to beginning of first line }
-
- procedure wi_home ( no : integer );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- _wx := 1;
- _wy := 1;
- end;
- wi_status := true;
- end;
- end; {wi_clear}
-
-
- { ********* wi_border ********** }
- { set/reset window border characters }
-
- { overlay }
- procedure wi_border ( no : integer; b : _wbs );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- if (_wb) then begin
- _wi_bord1(b);
- _wi_bord2;
- wi_status := true;
- end;
- end;
- end;
- end; {wi_border}
-
-
- { ********* wi_open ********** }
- { open window - allocate dynamic memory for window control block }
-
- { overlay }
- procedure wi_open ( no, x, y, w ,h : integer; b : _wbs );
- var
- i, l : integer;
- begin
- wi_status := false;
- if (w in _wxv) and (h in _wyv)
- and not (_wi_find(no)) then begin
- l := w * h;
- getmem (_wp1, ((sizeof(_wcb)-_wlz)+l));
- with _wp1^ do begin
- _wno := no;
- _wx := 1;
- _wy := 1;
- _wxo := x;
- _wyo := y;
- _ww := w;
- _wh := h;
- _wl := l;
- if (length(b) > 0) then begin
- _wb := true;
- _wc := _ww-2;
- _wr := _wh-2;
- _wcv := [1.._wc];
- _wrv := [1.._wr];
- _wi_bord1(b);
- for i := _wya to _wyz do
- _wrp[i] := (succ(i*_ww));
- end
- else begin
- _wb := false;
- _wc := _ww;
- _wr := _wh;
- _wcv := [_wxa.._ww];
- _wrv := [_wya.._wh];
- for i := _wya to _wyz do
- _wrp[i] := (pred(i)*_wc);
- end;
- _wnx := _whd;
- _whd := _wp1;
- end;
- wi_clear(no);
- end;
- end; {wi_open}
-
-
- { ********** wi_close ********** }
- { close window - release dynamic memory }
-
- { overlay }
- procedure wi_close ( no : integer );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- if _wp1 = _whd then
- _whd := _wp1^._wnx
- else begin
- _wp0^._wnx := _wp1^._wnx
- end;
- with _wp1^ do
- freemem(_wp1,((sizeof(_wcb)-_wlz)+_wl));
- _wp1 := nil;
- wi_status := true;
- end;
- end; {wi_close}
-
-
- { ********** wi_getpos ********** }
- { get window position }
-
- { overlay }
- procedure wi_getpos ( no : integer; var x, y : integer );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- x := _wx;
- y := _wy;
- end;
- wi_status := true;
- end;
- end; {wi_getpos}
-
-
- { ********* wi_getorg ********** }
- { get window screen origin }
-
- { overlay }
- procedure wi_getorg ( no : integer; var x, y : integer );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- x := _wxo;
- y := _wyo;
- end;
- end;
- end; {wi_getorg}
-
-
- { ********** wi_setpos ********** }
- { set window position }
-
- procedure wi_setpos ( no, x, y : integer );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- if (x in _wcv) and (y in _wrv) then begin
- _wx := x;
- _wy := y;
- wi_status := true;
- end
- else
- wi_status := false;
- end;
- end;
- end; {wi_setpos}
-
-
- { ********** wi_setorg ********** }
- { set window screen origin }
-
- procedure wi_setorg ( no, x, y : integer );
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- _wxo := x;
- _wyo := y;
- end;
- wi_status := true;
- end;
- end; {wi_setorg}
-
-
- { ********** wi_put ********* }
- { store string in window }
-
- procedure wi_put ( no : integer; st : _wst );
- begin
- _wi_out(no,st,false);
- end; {wi_put}
-
-
- { ********* wi_putln ********* }
- { store string in window }
-
- procedure wi_putln ( no : integer ; st : _wst );
- begin
- _wi_outln(no,st,false);
- end; {wi_putln}
-
-
- { ********* wi_get ********* }
- { retrieve string from window }
-
- procedure wi_get ( no, l : integer; var st : _wst );
- begin
- _wi_inp(no,l,st,false);
- end; {wi_get}
-
-
- { ********* wi_getln ********* }
- { retrieve string from window }
-
- procedure wi_getln ( no, l : integer; var st : _wst );
- begin
- _wi_inpln(no,l,st,false)
- end; {wi_getln}
-
-
- { ********* wi_write ********* }
- { write string to screen thru window }
-
- procedure wi_write ( no : integer; st : _wst );
- begin
- _wi_out(no,st,true);
- end; {wi_write}
-
-
- { ********* wi_writeln ********** }
- { write string to screen thru window }
-
- procedure wi_writeln ( no : integer; st : _wst );
- begin
- _wi_outln(no,st,true);
- end; {wi_writeln}
-
-
- { ********* wi_read ********* }
- { read string from keyboard thru window }
-
- procedure wi_read ( no : integer; l : integer; var st : _wst );
- begin
- _wi_inp(no,l,st,true);
- end; {wi_read}
-
-
- { ********** wi_readln ********** }
- { read string from keyboard thru window }
-
- procedure wi_readln ( no : integer; l : integer; var st : _wst );
- begin
- _wi_inpln(no,l,st,true);
- end; {wi_readln}
-
-
- { ********** wi_show ********* }
- { display window to screen }
-
- procedure wi_show ( no : integer );
- begin
- _wi_sher(no,true);
- end; {wi_show}
-
-
- { ********* wi_erase ********** }
- { blank window region on screen }
-
- procedure wi_erase ( no : integer );
- begin
- _wi_sher(no,false);
- end; {wi_erase}
-
-
-
- { ********** internal functions and procedures ********** }
-
- { ********** _wi_find ********** }
- { locate window record in defined window list }
-
- function _wi_find { no : integer ) : boolean};
- const
- first : boolean = true;
- var
- fnd : boolean;
- begin
- _wi_find := false;
- if first then begin
- first := false;
- _whd := nil;
- _wp0 := nil;
- _wp1 := nil;
- end;
- if (_wp1 <> nil) and (_wp1^._wno = no) then
- _wi_find := true
- else begin
- _wp1 := _whd;
- fnd := false;
- while ((_wp1 <> nil) and (not fnd)) do begin
- with _wp1^ do begin
- if _wno = no then begin
- _wi_find := true;
- fnd := true;
- end
- else begin
- _wp0 := _wp1;
- _wp1 := _wnx;
- end;
- end;
- end;
- end;
- end; {_wi_find}
-
-
- { ********** _wi_stb ********* }
- { build string }
-
- procedure _wi_stb { var c; l : integer; var st : _wst};
- var
- a : byte absolute c;
- begin
- move(a,st[1],l);
- move(l,st[0],1);
- end; {_wi_stb}
-
-
- { ********** _wi_bord1 ********** }
- { store window border string }
-
- procedure _wi_bord1 { var b: _wbs };
- var
- i : integer;
- begin
- with _wp1^ do begin
- for i := 1 to 4 do begin
- if (length(b) >= i) then
- _wbc[i] := b[i]
- else
- _wbc[i] := chr(0);
- end;
- if (_wbc[2] = chr(0)) then
- _wbc[2] := _wbc[1];
- if (_wbc[3] = chr(0)) then
- _wbc[3] := _wbc[1];
- if (_wbc[4] = chr(0)) then
- _wbc[4] := _wbc[2];
- end;
- end; {wi_bord1}
-
-
- { ********** _wi_bord2 ********* }
- { insert border into window }
-
- procedure _wi_bord2;
- var
- i : integer;
- begin
- with _wp1^ do begin
- if (_wb) then begin
- for i := 1 to _wh do begin
- _wch[(succ(pred(i)*_ww))] := _wbc[1];
- _wch[((pred(i)*_ww)+_ww)] := _wbc[3];
- end;
- for i := 1 to _ww do begin
- _wch[i] := _wbc[2];
- _wch[(_wl-_ww+i)] := _wbc[4];
- end;
- end;
- end;
- end; {_wi_bord2}
-
-
- { ********** _wi_out ********** }
- { store string to window at current window position }
- { optionally, write string to screen at current screen position }
-
- procedure _wi_out { var no : integer; var st : _wst; out : boolean};
- var
- i, x, y : integer;
- begin
- wi_status := false;
- wi_eoln := false;
- wi_eow := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- if (_wy > _wr) then begin
- wi_insln(no,_wy);
- if (out) then
- wi_show(no);
- end;
- i := 1;
- while (i <= length(st)) and (_wx <= _wc) do begin
- _wch[(_wrp[_wy]+_wx)] := st[i];
- if (out) then begin
- x := _wxo+_wx;
- y := _wyo+_wy;
- if (not _wb) then begin
- x := pred(x);
- y := pred(y);
- end;
- if ((x in _wxv) and (y in _wyv)) then begin
- gotoxy(x,y);
- write(st[i]);
- end;
- end;
- _wx := succ(_wx);
- i := succ(i);
- end;
- if (_wx > _wc) then begin
- _wx := 1;
- _wy := succ(_wy);
- wi_eoln := true;
- if (_wy > _wr) then
- wi_eow := true;
- end;
- wi_status := true;
- end;
- end;
- end; {_wi_out}
-
-
- { ********* _wi_outln ********** }
- { store string to window at current window position }
- { optionally, write string to screen at current screen position }
-
- procedure _wi_outln { var no : integer; var st : _wst; out : boolean};
- begin
- _wi_out(no,st,out);
- if (wi_status) then begin
- with _wp1^ do begin
- if (_wx > 1) then begin
- fillchar(_wch[(_wrp[_wy]+_wx)],(succ(_wc-_wx)),' ');
- if (out) then begin
- if (pred(_wxo+_wx) in _wxv)
- and (pred(_wyo+_wy) in _wyv) then begin
- wi_clreol(no);
- end;
- end;
- _wx := 1;
- _wy := succ(_wy);
- wi_eoln := true;
- if (_wy > _wr) then
- wi_eow := true;
- end;
- end;
- end;
- end; {_wi_outln}
-
-
- { ********** _wi_getst ********** }
- { get character string from terminal }
-
- procedure _wi_getst { var l, x, y : integer; var s : _wst };
- const
- bel = ^G;
- bs = 08;
- cr = 13;
- del = 127;
- var
- c : char;
- bgn : integer;
- eos : boolean;
- begin
- s := '';
- eos := false;
- bgn := x;
- repeat
- gotoxy(x,y);
- read(kbd,c);
- case ord(c) of
- del,bs : if (x > bgn) then begin
- x := pred(x);
- gotoxy(x,y);
- write(' ');
- delete(s,length(s),1);
- end
- else
- write(bel);
- $20..$7E : if (length(s) >= l) then
- write(bel)
- else begin
- s := s+c;
- gotoxy(x,y);
- write(c);
- x := succ(x);
- end;
- cr : eos := true;
- else write(bel);
- end;
- until eos;
- end; { _wi_getst }
-
-
- { ********** _wi_inp ********* }
- { retrieve string from window or from keyboard }
-
- procedure _wi_inp { var no, l : integer;
- var st : _wst; inp : boolean};
- var
- i, j, x, y : integer;
- s : _wst;
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- st := '';
- wi_eoln := false;
- wi_eow := false;
- if (_wy <= _wr) then begin
- i := 1;
- if (inp) then begin
- s := '';
- x := pred(_wxo+_wx);
- y := pred(_wyo+_wy);
- if (_wb) then begin
- x := succ(x);
- y := succ(y);
- end;
- if (_wxo in _wxv)
- and (pred(_wxo+_ww) in _wxv)
- and (_wyo in _wyv)
- and (pred(_wyo+_wh) in _wyv) then begin
- wi_status := true;
- j := succ(_wc-_wx);
- if (l > j) then
- _wi_getst(j,x,y,s)
- else
- _wi_getst(l,x,y,s);
- end
- else begin
- write(chr(7));
- wi_status := false;
- end;
- if (length(s) < l) then begin
- l := length(s);
- if (l = 0) then
- _wx := succ(_wx);
- end;
- end;
- while (not wi_eoln) and (i <= l) do begin
- with _wp1^ do begin
- if (_wy <= _wr) then begin
- j := (_wrp[_wy]+_wx);
- if (inp) then
- _wch[j] := s[i];
- st := st+_wch[j];
- i := succ(i);
- _wx := succ(_wx);
- if (_wx > _wc) then begin
- _wy := succ(_wy);
- _wx := 1;
- wi_eoln := true;
- if (_wy > _wc) then
- wi_eow := true;
- end;
- end
- else begin
- wi_eow := true;
- wi_eoln := true;
- end;
- end;
- wi_status := true;
- end;
- end
- else
- wi_status := false;
- end;
- end;
- end; {_wi_inp}
-
-
- { ********* _wi_inpln ********* }
- { retrieve string from window or from keyboard }
-
- procedure _wi_inpln { var no, l : integer;
- var st : _wst; inp : boolean};
- begin
- _wi_inp(no,l,st,inp);
- {gotoxy(1,23);}
- {clreol;}
- {write('stat=',wi_status,' eoln=',wi_eoln,' eow=',wi_eow);}
- if (wi_status) then begin
- if (not wi_eow) then begin
- with _wp1^ do begin
- if (_wy <= _wr) and (_wx > 1) then begin
- _wx := 1;
- _wy := succ(_wy);
- wi_eoln := true;
- if (_wy > _wr) then
- wi_eow := true;
- end;
- end;
- end;
- end;
- end; {_wi_inpln}
-
-
- { ********** _wi_sher ********* }
- { show/erase window from screen }
-
- procedure _wi_sher { var no : integer; show : boolean };
- var
- i, j, k, x, y : integer;
- st : _wst;
- begin
- wi_status := false;
- if (_wi_find(no)) then begin
- with _wp1^ do begin
- j := pred(_wxo+_ww);
- if (j <= _wxz) then
- j := _ww
- else
- j := _ww-(j-_wxz);
- if (_wxo >= 1) then begin
- k := 1;
- x := _wxo;
- end
- else begin
- j := pred(_wxo+_ww);
- k := succ(_ww-j);
- x := 1;
- end;
- if (j > 0) then begin
- if (not show) then begin
- fillchar(st[1],j,' ');
- move(j,st[0],1);
- end;
- for i := 1 to _wh do begin
- y := pred(_wyo+i);
- if (x in _wxv) and (y in _wyv) then begin
- if (show) then begin
- _wi_stb(_wch[((pred(i)*_ww)+k)],j,st);
- end;
- gotoxy(x,y);
- write(st);
- end;
- end;
- end;
- end;
- wi_status := true;
- end;
- end; {_wi_sher}
-
- { ********** End of Window Management Services ********* }